如何在Xcode 9中实现PKPaymentAuthorizationViewControllerDelegate for iOS 8向后兼容性?

时间:2017-09-26 08:37:33

标签: swift xcode xcode9 applepay passkit

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

直到Xcode 8.3.3(以及iOS 10 SDK)才能完美运行:

public partial class MessageLabel : UILabel
    {
        public MessageLabel(IntPtr handle) : base(handle)
        {
        }

        public override void DrawText(CoreGraphics.CGRect rect)
        {
            UIEdgeInsets insets = new UIEdgeInsets() { Bottom = 5, Top = 5, Left = 5, Right = 5 };
            base.DrawText(insets.InsetRect(rect));
        }
    }

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

  

协议'PKPaymentAuthorizationViewControllerDelegate'要求'paymentAuthorizationViewController(_:didSelectShippingContact:completion :)'在iOS 8.0及更高版本上可用

这意味着,我应该将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 } 更改为@available(iOS 9, *)

查看@available(iOS 8, *)的定义,我看到以下内容:

PKPaymentAuthorizationViewControllerDelegate

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

接下来是:查看@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) 的定义(这是上述方法的方法签名的一部分),您可以看到以下内容:

PKContact

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

我知道我试图实现的方法已被弃用,但替代版仅在iOS 11上可用,所以现在似乎我需要实现已弃用的方法(或者我在这里错了?)。

有人有同样的问题吗?有什么想法吗?我很欣赏每一个想法:)

谢谢!

1 个答案:

答案 0 :(得分:0)

  

协议' PKPaymentAuthorizationViewControllerDelegate'要求   ' paymentAuthorizationViewController(_:didSelectShippingContact:完成:)'   可在iOS 8.0及更高版本上使用

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

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

错误将消失

但是如何处理你的问题。创建两个将发布PKPaymentAuthorizationViewControllerDelegate协议的类。其中一个应该发布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的支持。