Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift Xcode 12和OSLog(os.log):包装OSLogMessage会导致编译错误:参数必须是字符串插值_Swift_String_Xcode_String Interpolation_Oslog - Fatal编程技术网

Swift Xcode 12和OSLog(os.log):包装OSLogMessage会导致编译错误:参数必须是字符串插值

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"

在Xcode 12/IOS14中,OSLog获得了对字符串插值的支持(耶!)。但是仍然不可能附加钩子来轻松地登录到其他通道,例如Crashlytics

所以我想我只需要做一个简单的包装器并传递参数。然而,关于字符串插值似乎有一些神奇的事情发生

提供了新的记录器类,它采用
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_日志中的字符串插值。