I am trying to wrap os_log for logging in my iOS app like so:
import Foundation
import OSLog
enum LogCategory: String, CaseIterable {
case viewCycle
case tracking
case api
}
struct Log {
private static let logs = {
return LogCategory.allCases
.reduce(into: [LogCategory: OSLog]()) { dict, category in
dict[category] = OSLog(subsystem: Bundle.main.bundleIdentifier ?? "BIMB", category: category.rawValue)
}
}()
static func debug(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .debug, args)
}
static func info(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .info, args)
}
static func notice(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .default, args)
}
static func warning(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .default, args)
}
static func error(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .error, args)
}
static func critical(category: LogCategory, message: StaticString, _ args: CVarArg...) {
logImpl(category: category, message: message, type: .fault, args)
}
private static func logImpl(category: LogCategory, message: StaticString, type: OSLogType, _ args: CVarArg...) {
guard let log = logs[category] else {
return
}
os_log(message, log: log, type: type, args)
}
}
The problem is if I did this:
Log.debug(category: .tracking,
message: "Device ID: %s.",
UIDevice.current.identifierForVendor?.uuidString ?? "unknown")
it always crashed with this error:
2023-12-13 12:33:35.173798+0700 bimb-authenticate-ios[62740:928633]
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Swift.__SwiftDeferredNSArray
UTF8String]: unrecognized selector sent to instance 0x600000dcbbc0'
But if I just do it with os_log like this:
os_log("Device ID: %s.",
log: OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "tracking"),
type: .debug,
UIDevice.current.identifierForVendor?.uuidString ?? "unknown")
it worked fine. Also if I changed %@ in my wrapper instead, it didn't crash, but the idfv is shown inside a pair of brackets like this:
Device ID: (
"C0F906C8-CD73-44F6-86A1-A587248680D3"
).`
But with os_log it is shown normally like this: Device ID: C0F906C8-CD73-44F6-86A1-A587248680D3.
Can you tell me what's wrong here? And how do I fix this?
Thanks.
NOTE: This is using os_log since the minimum version is iOS 11. I don't know why people advising me with using Logger instead.