在 Swift 中检查协议可用性

Checking for protocol availability in Swift

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

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

You can use the is and as operators described in Type Casting to check for protocol conformance, and to cast to a specific protocol. Checking for and casting to a protocol follows exactly the same syntax as checking for and casting to a type:

The is operator returns true if an instance conforms to a protocol and returns false if it does not.

The as? version of the downcast operator returns an optional value of the protocol’s type, and this value is nil if the instance does not conform to that protocol.

The as! version of the downcast operator forces the downcast to the protocol type and triggers a runtime error if the downcast does not succeed.

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

在 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
    }
}

感谢@joern 提出的在委托中采用该协议的建议,我在此总结如下:

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