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

Swift 如何在Xcode 9中实现PKPaymentAuthorizationViewControllerDelegate以实现iOS 8向后兼容性?,swift,xcode,xcode9,applepay,passkit,Swift,Xcode,Xcode9,Applepay,Passkit,我正在尝试构建一个在Xcode 9上使用Apple Pay的应用程序。部署目标是iOS 8 直到Xcode 8.3.3(以及iOS 10 SDK)之前,这一切都运行得非常好: extension MyViewController: PKPaymentAuthorizationViewControllerDelegate { func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewContro

我正在尝试构建一个在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,我得到以下生成错误:

协议“PKPaymentAuthorizationViewControllerDelegate”要求“paymentAuthorizationViewController(\uux0:didSelectShippingContact:completion:)”在iOS 8.0及更高版本上可用

这意味着,我应该将
@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)
@available(iOS 9.0, *)
open class PKContact : NSObject {
    ...
}
因此,该方法被定义为在iOS 8上可用

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

@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)
@available(iOS 9.0, *)
open class PKContact : NSObject {
    ...
}
因此,根据当前的SDK,该方法在iOS 8上可用(这会导致生成错误),但它的一个参数类型仅在iOS 9上可用。这似乎是相互排斥的

我知道我试图实现的方法已经被弃用了,但是替换方法只在iOS 11上可用,所以现在看来我需要实现弃用的方法(或者我在这里搞错了?)

有人有同样的问题吗?有什么想法吗?我感激你的每一个想法:)

谢谢大家!

协议“PKPaymentAuthorizationViewControllerDelegate”需要 'paymentAuthorizationViewController(\u:didSelectShippingContact:completion:)' 在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的支持。

感谢您为提供解决方案所做的努力。然而问题仍然存在,你在答案开头的陈述和我的陈述一样有效。编译问题当然可以通过将整个实现类限制为iOS 9来解决,但这不是我的问题。我也很感谢您的解决方案。我最初担心苹果对协议方法的注释不正确(包括一种仅在iOS 9和iOS 8上需要支持的方法声明中提供的类型),我认为这是错误的。