Swift 如何在Xcode 9中实现PKPaymentAuthorizationViewControllerDelegate以实现iOS 8向后兼容性?
我正在尝试构建一个在Xcode 9上使用Apple Pay的应用程序。部署目标是iOS 8 直到Xcode 8.3.3(以及iOS 10 SDK)之前,这一切都运行得非常好: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
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上需要支持的方法声明中提供的类型),我认为这是错误的。