我有一个使用本地通知并支持iOS 10的应用程序。我正在尝试添加iOS 9支持,这需要我使用旧的位置通知API。我试图在我的iOS 10代码上使用@available和#available,我无法弄清楚如何将我的中心变量仅用于运行iOS 10的设备。
当我将目标从iOS 10设置为9时,我收到此变量的错误消息:“UNUserNotificationCenter仅适用于iOS 10.0或更高版本。”它建议我将“@available(iOS 10.0,*)”添加到我的整个班级,我不想这样做,因为这个类中的代码将用于iOS 9.我很欣赏有关如何限制我的任何建议中心属性到iOS 10。
class ViewController: UIViewController, UITextFieldDelegate {
let center = UNUserNotificationCenter.current()
...
@available
可用于整个类或一个或多个函数,但不适用于属性。
关于你的UNUserNotificationCenter用法,current
返回一个永不改变的单例,那么为什么不删除center
常量,只使用UNUserNotificationCenter.current()
使用center
?
以下是一个潜在的解决方案(感谢blog post)。
我们的想法是使用类型为Any
的存储属性,然后创建一个计算属性,该属性将转换存储的属性(并在必要时实例化它)。
private var _selectionFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
fileprivate var selectionFeedbackGenerator: UISelectionFeedbackGenerator {
if _selectionFeedbackGenerator == nil {
_selectionFeedbackGenerator = UISelectionFeedbackGenerator()
}
return _selectionFeedbackGenerator as! UISelectionFeedbackGenerator
}
我知道这是一个较老的问题,但我想为那些通过Google来到这里的人添加答案。
正如kgaidis和Cœur所提到的,你可以在计算属性上使用@available
。但是,lazy
变量被认为是计算属性,所以你也可以在它们上使用@available
。这有一个很好的好处,即删除额外存储属性和强制转换的样板 - 事实上,它没有在iOS 10之前的代码中留下属性的证据。
您可以简单地声明它:
@available(iOS 10.0, *)
lazy private(set) var center = UNUserNotificationCenter.current()
不幸的是,没有办法让它完全只读,但private(set)
至少使它在课堂外只读。
与kgaidis类似的想法,通过使用任何版本中接受的类型的单独存储属性。但Any
可能过于通用,因为它不能被声明为weak
,所以你可能想在某些情况下用一致的协议替换它:
private weak var _notificationCenterDelegate: NSObjectProtocol?
@available(iOS 10.0, *)
var notificationCenterDelegate: UNUserNotificationCenterDelegate? {
return _notificationCenterDelegate as? UNUserNotificationCenterDelegate
}
我在我的应用程序中用于支持iOS 9的反馈生成器的代码。正如您所看到的,它很简单,并且没有强制转换。主要思想是在Any?
属性中存储值并通过计算值使用它。
private var storedFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
private var feedbackGenerator: UISelectionFeedbackGenerator {
if let generator = storedFeedbackGenerator as? UISelectionFeedbackGenerator {
return generator
}
let generator = UISelectionFeedbackGenerator()
generator.prepare()
storedFeedbackGenerator = generator
return generator
}
let validClass = NSClassFromString("UNUserNotificationCenter") != nil
使用validClass
来决定iOS 10的特定代码,如:
if validClass
// iOS 10 code
else
// Earlier than iOS 10 code