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

问题描述 投票:11回答:6

我有一个使用本地通知并支持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()
  ...
ios swift uilocalnotification
6个回答
1
投票

@available可用于整个类或一个或多个函数,但不适用于属性。

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


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
}

6
投票

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

正如kgaidis和Cœur所提到的,你可以在计算属性上使用@available。但是,lazy变量被认为是计算属性,所以你也可以在它们上使用@available。这有一个很好的好处,即删除额外存储属性和强制转换的样板 - 事实上,它没有在iOS 10之前的代码中留下属性的证据。

您可以简单地声明它:

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

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


1
投票

与kgaidis类似的想法,通过使用任何版本中接受的类型的单独存储属性。但Any可能过于通用,因为它不能被声明为weak,所以你可能想在某些情况下用一致的协议替换它:

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

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
}

-3
投票
let validClass = NSClassFromString("UNUserNotificationCenter") != nil

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

if validClass
   // iOS 10 code
else
   // Earlier than iOS 10 code
© www.soinside.com 2019 - 2024. All rights reserved.