【问题标题】:Checking for protocol availability in Swift在 Swift 中检查协议的可用性
【发布时间】:2015-10-24 19:14:02
【问题描述】:

我正在采用 WatchConnectivity,但我仍然支持该库不可用的 iOS7 和 iOS 8。此外,我采用的协议 WCSessionDelegate 也不支持,但这个旧系统。 在 ObjectiveC 中,我会使用预处理指令来屏蔽此声明和协议采用,使其免受不支持它们的版本的影响。如何在 Swift 中处理该问题,以使应用程序不会在旧系统上崩溃?

【问题讨论】:

    标签: ios swift preprocessor protocols watchconnectivity


    【解决方案1】:

    感谢@joern 提出的在代表中采用该协议的建议,我在此总结一下:

    @available(iOS 9, *)
    extension inArrivoHDAppDelegate: WCSessionDelegate {}
    

    【讨论】:

      【解决方案2】:

      https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID283

      您可以使用类型转换中描述的isas 运算符来检查 用于协议一致性,并强制转换为特定协议。检查 for 和强制转换为协议的语法与 检查并转换为类型:

      如果实例符合协议,is 运算符返回 true,否则返回 false。

      向下转换运算符的as? 版本 返回协议类型的可选值,该值是 如果实例不符合该协议,则为 nil。

      as! 版本 downcast 运算符的强制向下转换到协议类型和 如果向下转换不成功,则触发运行时错误。

      for object in objects {
          if let objectWithArea = object as? HasArea {
              print("Area is \(objectWithArea.area)")
          } else {
              print("Something that doesn't have an area")
          }
      }
      

      【讨论】:

      • 当然,但这可能只是在运行时使用。包含和协议的一致性只能在编译时被屏蔽,当然 'is' 和 'as' 不可用,也没有任何检查版本的常用工具。
      • 您正在使用最新的 iOS SDK 构建代码,因此您的应用程序知道界面。但是检查是在运行时执行的。或者你认为如果 Objective-C Xcode 为每个 iOS SDK 编译代码?它甚至不发货!
      • 恐怕我听不懂你的意思。
      【解决方案3】:

      在 Swift 2 中,您现在可以使用可用性检查来屏蔽不可用的旧系统版本的功能。

      如果您只想屏蔽方法的一部分,或者您可以屏蔽整个函数、扩展甚至类,则可以在 ifguardwhile 语句中使用可用性检查。

      下面是一个如何屏蔽WCSessionWCSessionDelegate免受低于iOS9版本的示例:

      class ViewController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              if #available(iOS 9, *) {
                  if WCSession.isSupported() {
                      let session = WCSession.defaultSession()
                      session.delegate = self
                      session.activateSession()
                  }
              }
          }
      }
      
      @available(iOS 9, *)
      extension ViewController: WCSessionDelegate {
          func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
              // do stuff
          }
      }
      

      【讨论】:

      • 当然,我也这样做了,但问题再次出现在包含指令和协议采用中,其中 #available 标记可能无法使用。当然,我不确定这在 iOS 7 中是否会成为问题,因为我不再有 iOS 7 设备可用于测试。
      • 您能否在您的问题中添加包含指令和协议采用的代码示例?我不太清楚你的意思
      • 在我的回答中,我通过使用扩展来屏蔽旧系统版本的协议采用。
      • 什么意思,你是在扩展中模拟 WatchConnectivity 吗?
      • 不,我只是确保需要 iOS9 (WatchConnectivity) 的代码对旧系统隐藏,以便应用程序不会崩溃。这就是为什么我将协议采用转移到能够使用可用性 API 的扩展。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2014-11-09
      • 2021-10-13
      • 1970-01-01
      • 2019-12-31
      • 1970-01-01
      相关资源
      最近更新 更多