将@available与存储的属性一起使用

时间:2017-01-27 23:35:07

标签: ios swift uilocalnotification

我有一个使用本地通知并支持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()
  ...

7 个答案:

答案 0 :(得分:20)

以下是一个潜在的解决方案(感谢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
}

答案 1 :(得分:4)

我知道这是一个比较老的问题,但是我想为像我一样通过Google来到这里的人们添加一个答案。

正如kgaidis和Cœur所述,您可以在计算属性上使用@available。但是,lazy变量被视为计算属性,因此您也可以在它们上使用@available。这样做有一个很好的好处,那就是删除多余的存储属性和强制转换的样板-实际上,在iOS 10之前的代码中没有留下该属性的证据。

您可以像这样简单地声明它:

@available(iOS 10.0, *)
lazy private(set) var center = UNUserNotificationCenter.current()

不幸的是,没有办法使它完全是只读的,但是private(set)至少使其在类之外是只读的。

答案 2 :(得分:1)

@available可以在整个类或一个或多个函数周围使用,但不能用于属性。

关于您的UNUserNotificationCenter使用情况,current会返回一个永不改变的单例,那么为什么不删除center常量,只使用UNUserNotificationCenter.current()使用center

答案 3 :(得分:1)

与kgaidis类似的想法,通过使用任何版本中接受的类型的单独存储属性。但是Any可能过于通用,因为它不能被声明为weak,因此您可能希望在某些情况下将其替换为符合协议:

private weak var _notificationCenterDelegate: NSObjectProtocol?
@available(iOS 10.0, *)
var notificationCenterDelegate: UNUserNotificationCenterDelegate? {
    return _notificationCenterDelegate as? UNUserNotificationCenterDelegate
}

答案 4 :(得分:0)

我在支持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
}

答案 5 :(得分:0)

对于物镜-c

@property (nonatomic, strong) CustomClass *object API_AVAILABLE(ios(10.0));

答案 6 :(得分:-3)

let validClass = NSClassFromString("UNUserNotificationCenter") != nil

使用validClass来确定特定于iOS 10的代码,如:

if validClass
   // iOS 10 code
else
   // Earlier than iOS 10 code