Checking for protocol availability in Swift

2019-06-02 23:55发布

I am adopting WatchConnectivity, but I am still supporting iOS7 and iOS 8 for which this library is not available. Moreover I am adopting protocol WCSessionDelegate also not supported but this older systems. In ObjectiveC I would have used preprocessing directives to shield this declaration and the protocol adoption from versions not supporting them. How do I handle that in Swift so that the app does not crash on older systems?

3条回答
小情绪 Triste *
2楼-- · 2019-06-03 00:41

In Swift 2 you can now use Availability Checking to shield features from older system versions where they are not available.

You can use the availability check in a if, guard, while statement if you want to shield only part of a method, or you can shield whole functions, extensions or even classes.

Here's an example on how to shield WCSession and WCSessionDelegate from versions lower than 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
    }
}
查看更多
神经病院院长
3楼-- · 2019-06-03 00:43

I thank @joern for the suggestion of adopting the protocol in a delegate which I here summarize:

@available(iOS 9, *)
extension inArrivoHDAppDelegate: WCSessionDelegate {}
查看更多
闹够了就滚
4楼-- · 2019-06-03 00:44

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")
    }
}
查看更多
登录 后发表回答