如何将@available用于已重命名的方法?

时间:2017-11-02 02:54:15

标签: ios swift

PushKit在iOS 11中有一种新方法,旨在取代iOS 10中的方法。

在使用iOS 11作为基本SDK(我目前正在使用Xcode 9.2B)构建时,无法使用iOS 10方法,因为编译器错误表明该方法已重命名。 但它也无法使用iOS 11方法,然后在iOS 10设备上运行应用程序,因为会出现无法识别的选择器异常。

我不能使用#available {} else {}作为整个方法。

所以我做了这个

@available(iOS, introduced: 8.0, deprecated: 11.0)
public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType)
{
 ...   
}
@available(iOS 11.0, *)
public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Swift.Void)
{
    ...
}

OR:

@available(iOS 11, *)
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void)
{
...

@available(iOS 10, *)
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType)
{
...

但是这两个都导致第二个声明的编译错误,说它已被重命名。

如何使用iOS 11或iOS 10版本?

(该应用不支持版本< 10)

1 个答案:

答案 0 :(得分:0)

这里的部分问题是Swift 3和Swift 4之间的区别,以及iOS 11中一个委托方法的附加参数。

以下代码使用iOS 10的部署目标和iOS 11.1的基本SDK编译Swift 3.2:

import UIKit
import PushKit

class ViewController: UIViewController, PKPushRegistryDelegate {
    func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, forType type: PKPushType) {

    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
        pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) {
            // no-op
        }
    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        // Do what is needed

        completion()
    }
}

以下用Swift 4编译清理:

import UIKit
import PushKit

class ViewController: UIViewController, PKPushRegistryDelegate {
    func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {

    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
        pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) {
            // no-op
        }
    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        // Do what is needed

        completion()
    }
}

两组代码之间的唯一区别是,在Swift 3下,前两个方法有一个名为forType的参数,而在Swift4下,它被命名为for

新的iOS 11 API使用for作为该参数,无论Swift版本如何。

现在剩下的问题是你真的需要提供前两个委托方法的两个副本,一个集合for,一个集合forType,以确保实际调用所有委托方法在所有iOS版本下,无论您使用哪种Swift版本?