swift - 如何在 Xcode 9 中实现 PKPaymentAuthorizationViewControllerDelegate 以实现 iOS 8 向后兼容?

标签 swift xcode xcode9 applepay passkit

我正在尝试构建一个在 Xcode 9 上使用 Apple Pay 的应用程序。部署目标是 iOS 8。

在 Xcode 8.3.3(和 iOS 10 SDK)之前,它工作得很好:

extension MyViewController: PKPaymentAuthorizationViewControllerDelegate {

func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingAddress address: ABRecord, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Void) {
    // handle the ABRecord for iOS 8
}

@available(iOS 9.0, *)
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingContact contact: PKContact, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Void) {
    // handle the PKContact on iOS 9 and later
}

现在,使用 Xcode 9 我得到以下构建错误:

Protocol 'PKPaymentAuthorizationViewControllerDelegate' requires 'paymentAuthorizationViewController(_:didSelectShippingContact:completion:)' to be available on iOS 8.0 and newer

这意味着,我应该将 @available(iOS 9, *) 更改为 @available(iOS 8, *)

查看 PKPaymentAuthorizationViewControllerDelegate 的定义,我看到以下内容:

@available(iOS, introduced: 8.0, deprecated: 11.0, message: "Use paymentAuthorizationViewController:didSelectShippingContact:handler: instead to provide more granular errors")
optional public func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingContact contact: PKContact, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Swift.Void)

因此该方法被定义为从 iOS 8 开始可用。

问题来了:查看 PKContact 的定义(它是上述方法的方法签名的一部分),您可以看到以下内容:

@available(iOS 9.0, *)
open class PKContact : NSObject {
    ...
}

因此,根据目前的SDK,该方法在iOS 8上可用(导致构建错误),但其参数类型之一仅在iOS 9上可用。这似乎是互斥的。

我知道我尝试实现的方法已被弃用,但替代方法仅在 iOS 11 上可用,所以现在看来​​我无论如何都需要实现已弃用的方法(或者我在这里弄错了吗?)。

有人遇到同样的问题吗?对此有什么想法吗?我感谢每一个想法:)

谢谢!

最佳答案

Protocol 'PKPaymentAuthorizationViewControllerDelegate' requires 'paymentAuthorizationViewController(_:didSelectShippingContact:completion:)' to be available on iOS 8.0 and newer

并不意味着该方法需要 iOS 8.0 及更新版本。这意味着该方法在类中发布的内容应支持 iOS 8.0。您可以通过在类声明之前放置 @available(iOS 9.0, *) 来轻松检查它

@available(iOS 9.0, *)
class MyViewController: UIViewController, PKPaymentAuthorizationViewControllerDelegate {
    //...
}

错误会消失

但是如何处理你的问题。创建两个将发布 PKPaymentAuthorizationViewControllerDelegate 协议(protocol)的类。其中一个应该发布 iOS 8 支持,另一个应该发布 iOS 9 和新版本。

class DeprecatedPayment: NSObject, PKPaymentAuthorizationViewControllerDelegate {
    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {

    }
    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingAddress address: AddressBook.ABRecord, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Swift.Void) {
    }
}

@available(iOS 9.0, *)
class Payment: NSObject, PKPaymentAuthorizationViewControllerDelegate {
    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
    }
    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingContact contact: PKContact, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Void) {
        // handle the PKContact on iOS 9 and later
    }
}

现在你可以根据安装的iOS使用相应的类了

if #available(iOS 9.0, *) {
    //use Payment
} else {
    //use DeprecatedPayment
}

此外,当时机成熟时,也很容易放弃对已弃用的 iOS 的支持。

关于swift - 如何在 Xcode 9 中实现 PKPaymentAuthorizationViewControllerDelegate 以实现 iOS 8 向后兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46421576/

相关文章:

ios - 数组枚举期间核心数据获取实体

ios - UICollectionView 找不到成员

ios - Xcode 9 构建项目但无法启动模拟器

ios - Swift - UIViewControllerAnimatedTransitioning 未按预期使用 Swift4 进行转换

iphone - Tableview推送到不同的 View

ios - 为什么我的动画不流畅?

ios - Swift:ViewDidLoad 在接受通知权限请求后不会继续

swift - Alamofire 非阻塞连接

ios - 启动时未加载同步 Realm

swift - 如何更新可观察对象中数组的元素