Swift 和 NS_EXTENSION_UNAVAILABLE
根据 App Extension Programming Guide,有些 API 在 App Extension 中是不允许调用的,其中最典型的一个就是 UIApplication.shared
。这些方法和属性都由 NS_EXTENSION_UNAVAILABLE
这个宏作为标记,在 App Extension 中使用的话 Swift 代码直接无法通过编译(因为程序会直接崩溃),但是因为 Swift 不支持宏定义,所以无法用 #if
来判断是否允许调用。
那么用 Swift 的我们应该怎么做呢?
1 | @available(iOSApplicationExtension, unavailable, message: "This method is NS_EXTENSION_UNAVAILABLE.") |
好了,散伙。
[SR-1266] 修复之前
其实我是因为 AcknowList 需要兼容 App Extension 才了解到,感谢 这个 PR,我们不用再曲线救国了。不过当时因为 @available
只是运行时判断,所以并不能解决无法编译的问题。无奈的我想到了这些(很可能不兼容 Objective-C)的方法:
- 最简单的是把需要用到这些 API 的代码作为
extension
放在另一个文件中,只在非扩展的 target 中包含。 - 或者是修改工程文件,把
NS_EXTENSION_UNAVAILABLE
加到扩展 target 的 Build Settings 里的 Swift Compiler - Custom Flags 里。这样就能用#if
判断了。 - 最后这个方法是在 WWDC17 去 Messages Extension 的 lab 时候想到的,问了下苹果工程师,大概没问题。自己把函数或变量修饰为
@available(...OSAplicationExtension, unavailable)
,然后内部通过 Key Path 实现。其它NS_EXTENSION_UNAVAILABLE
适用的地方尝试调用会因为@available
无法通过编译,所以只要自己控制好不要在实现的时候乱用就行。完整的例子如下:
1 | @available(iOSApplicationExtension, unavailable, message: "This is unavailable: Use view controller based solutions where appropriate instead.") |