I'd like to give control to the app developer that uses my library to select which level of logs they'd like to see from my lib (e.g. do they want to see all debug messages or just errors).
I know there are filtering controls that Xcode gives us, but I'm wondering if there is a way to pull this off with code. Ideally the user callsite would look like MyLib(logLevel: .info).
And then I would pass that info level somehow to OSLog. Today, I create my logger like this:
let myLogger = Logger(
subsystem: Bundle.main.bundleIdentifier ?? "UnknownApp",
category: "MyLibrary"
)
As far as I can tell, there is nothing I can then pass to my myLogger instance to configure the threshold level. I'm imagining an interface like:
myLogger.logLevel(.warning)
// Later...
myLogger.debug("You won't see this")
myLogger.error("But you will see this")
Does OSLog and friends give us any ability to do this out of the box, or are we building little wrappers around OSLog to accomplish this?
Thank you,
Lou
Post
Replies
Boosts
Views
Activity
Hi all,
I am adding the following StoreKit 2 code to my app, and I don't see anything in Apple's documentation that explains the unverified case. When is that case exercised? Is it when someone has tampered with the app receipt? Or is it for more mundane things like poor network connectivity?
// Apple's docstring on `shared` states:
// If your app fails to get an AppTransaction by accessing the shared property, see refresh().
// Source: https://developer.apple.com/documentation/storekit/apptransaction/shared
var appTransaction: VerificationResult<AppTransaction>?
do {
appTransaction = try await AppTransaction.shared
} catch {
appTransaction = try? await AppTransaction.refresh()
}
guard let appTransaction = appTransaction else {
AppLogger.error("Couldn't get the app store transaction")
return false
}
switch appTransaction {
case .unverified(appTransaction, verificationError):
// For what reasons should I expect this branch to be entered in production?
return await inspectAppTransaction(appTransaction, verifiedByApple: false)
case .verified(let appTransaction):
return await inspectAppTransaction(appTransaction, verifiedByApple: true)
}
Thank you,
Lou
Hi all,
The use of setVoiceProcessingEnabled increases the channel count of my microphone audio from 1 to 5. This has downstream effects, because when I use AVAudioConverter to convert between PCM buffer types the output buffer contains only silence.
Here is a reproduction showing the channel growth from 1 to 5:
let avAudioEngine: AVAudioEngine = AVAudioEngine()
let inputNode = avAudioEngine.inputNode
print(inputNode.inputFormat(forBus: 0))
// Prints <AVAudioFormat 0x600002f7ada0: 1 ch, 48000 Hz, Float32>
do {
try inputNode.setVoiceProcessingEnabled(true)
} catch {
print("Could not enable voice processing \(error)")
return
}
print(inputNode.inputFormat(forBus: 0))
// Prints <AVAudioFormat 0x600002f7b020: 5 ch, 44100 Hz, Float32, deinterleaved>
If it helps, the reason I'm using setVoiceProcessingEnabled because I don't want the mic to pick up output from the speakers. Per wwdc
When enabled, extra signal processing is applied on the incoming audio, and any audio that is coming from the device is taken
Here is my conversion logic from the input PCM format (which in the case above is 5ch, 44.1kHZ, Float 32, deinterleaved) to the target format PCM16 with a single channel:
let outputFormat = AVAudioFormat(
commonFormat: .pcmFormatInt16,
sampleRate: inputPCMFormat.sampleRate,
channels: 1,
interleaved: false
)
guard let converter = AVAudioConverter(
from: inputPCMFormat,
to: outputFormat) else {
fatalError("Demonstration")
}
let newLength = AVAudioFrameCount(outputFormat.sampleRate * 2.0) guard let outputBuffer = AVAudioPCMBuffer(
pcmFormat: outputFormat,
frameCapacity: newLength) else {
fatalError("Demonstration")
}
outputBuffer.frameLength = newLength
try! converter.convert(to: outputBuffer, from: inputBuffer)
// Use the PCM16 outputBuffer
The outputBuffer contains only silence. But if I comment out inputNode.setVoiceProcessingEnabled(true) in the first snippet, the outputBuffer then plays exactly how I would expect it to.
So I have two questions:
Why does setVoiceProcessingEnabled increase the channel count to 5?
How should I convert the resulting format to a single channel PCM16 format?
Thank you,
Lou
Hi,
I run a service that protects API calls from Apple ecosystem apps with several layers of security, one of them being DeviceCheck's server-to-server functionality. All requests arrive with a DeviceCheck token that I send to Apple to validate.
Essentially I'm using the functionality listed here:
The server-to-server APIs also let you verify that the token you receive comes from your app on an Apple device.
https://developer.apple.com/documentation/devicecheck
However, occasionally I see huge bursts of traffic that contain valid DeviceCheck tokens from a scripter. I want to understand how they are generating them. It seems like they have identified a way to forge tokens.
Here are traffic patterns for my site. The scale of the y-axis is somewhat arbitrary due to how I'm sampling the requests, but you get the gist. You can see the dark green bars at the bottom are general traffic, and the light green is what we rejected (we have other layers besides DeviceCheck that reject traffic). Interestingly, though, all those light green requests contained valid device check tokens!
I have thousands of the tokens stored in a file for analysis.
Are there known ways that Apple knows of tokens being forged? I wanted to open a TSI for this but the flow requires an Xcode project, and there is no Xcode project to demonstrate this issue. I would really like to get in contact with someone from Apple that either works on DeviceCheck or supports it.
Hundreds of apps in the store depend on my service, and DeviceCheck forms a layer of security that I want to rely on. Obviously we can't solely rely on it, and we don't, but it does form an important layer of our defense. So I ask:
If you know of a way to forge tokens, please comment and I'll shoot you a DM
If you work at Apple and know who I can talk to, please help me work through the process to get in touch with them.
Thanks,
Lou