Swift Xcode 12和OSLog(os.log):包装OSLogMessage会导致编译错误:参数必须是字符串插值
在Xcode 12/IOS14中,OSLog获得了对字符串插值的支持(耶!)。但是仍然不可能附加钩子来轻松地登录到其他通道,例如Crashlytics 所以我想我只需要做一个简单的包装器并传递参数。然而,关于字符串插值似乎有一些神奇的事情发生 提供了新的记录器类,它采用Swift Xcode 12和OSLog(os.log):包装OSLogMessage会导致编译错误:参数必须是字符串插值,swift,string,xcode,string-interpolation,oslog,Swift,String,Xcode,String Interpolation,Oslog,在Xcode 12/IOS14中,OSLog获得了对字符串插值的支持(耶!)。但是仍然不可能附加钩子来轻松地登录到其他通道,例如Crashlytics 所以我想我只需要做一个简单的包装器并传递参数。然而,关于字符串插值似乎有一些神奇的事情发生 提供了新的记录器类,它采用OSLogMessage作为参数,可按如下方式使用: let someVar = "some var" let logger = Logger(subsystem: "com.my.app"
OSLogMessage
作为参数,可按如下方式使用:
let someVar = "some var"
let logger = Logger(subsystem: "com.my.app", category: "UI")
logger.error("some message")
logger.error("some message with default var: \(someVar)")
logger.error("some message with private var: \(someVar, privacy: .private)")
logger.error("some message with private var: \(someVar, privacy: .private(mask: .hash))")
logger.error("some message with public var: \(someVar, privacy: .public)")
包装新的记录器结构 让我们把它包装在一个结构中:
struct MyLogger {
let logger = Logger(subsystem: "com.my.app", category: "UI")
func error(_ message: OSLogMessage) {
logger.error(message)
}
}
相同的签名,但不幸的是,编译器不允许:
ERROR: Argument must be a string interpolation
此外,尝试调用my struct还会导致一个奇怪的编译器错误:
let logger = MyLogger()
let value = "value"
logger.error("Some log message \(value, privacy: .public)")
收益率:
String interpolation cannot be used in this context; if you are calling an os_log function, try a different overload
直接调用os\u log(u:OSLogMessage)
而不是新的结构会得到相同的结果
有办法解决这个问题吗?我遗漏了什么吗?日志API使用特殊的编译器功能在编译时评估隐私级别。正如诊断所说,您必须使用静态(即编译时已知的)方法或“OSLogPrivacy”属性;它不能是在运行时计算的变量。这意味着,如果不使用编译器内部特性,就无法为这些API创建自己的包装器
您无法包装记录器调用。参数必须是字符串文字,而不是传递的值。@matt谢谢,你能告诉我为什么不能传递字符串文字吗?对我来说,似乎有点不清楚me函数似乎将定义的类型作为参数,但不是真的?还有,有没有其他方法可以解决这个问题?一旦你把它传下去,它就不再是文字了!“传递”和“文字”是对立的,统一日志上的文档没有“限制”。他们太残忍了!嗯,我不应该夸大;他们比以前好多了我的建议是从2016年IIRC开始,多年来只看WWDC的视频。苹果一直警告不要过早地使用
os\u log
。关键是,直到运行时,在我们离开应用程序进程并进入logging land之后,插值才被计算。这样一来,昂贵的插值被推迟,应用程序本身也不会变慢。新的记录器通过要求一个文本来实现这一点。这里令人恼火的部分是,如果我们想要注入#文件和#行,它将被完全阻止。因此,如果我们想在日志中记录文件/行/函数名,那么os_日志就没有用处。苹果可能会强制执行,但他们也让他们的记录器对大多数开发者来说基本上毫无用处。我们甚至不必从写文件的能力开始。我想我们会看到主要的OSS记录器重新实现苹果添加到os_日志中的字符串插值。