2017-09-26 79 views
5

我试图构建在Xcode的9部署目标采用了苹果的付费应用程序是iOS的8如何在Xcode 9中实现PKPaymentAuthorizationViewControllerDelegate for 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,所以目前看来我需要实施弃用的方法(或者我误解了吗?)。

有没有人有同样的问题?对此有何想法?我很欣赏每一个想法:)

谢谢!

回答

0

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协议。其中一个应该释放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的支持,当时间来到将能够使用专用类。

+0

感谢您提供解决方案。然而,问题依然存在,您在答复开始时的陈述与我的陈述一样有效。编译问题当然可以通过将整个实现类限制到iOS 9来解决,但那不是我的问题。 – floriankrueger

+0

我也很感谢你的解决方案。我最初关心的协议方法被Apple错误地注释了(包括仅在iOS 9上可用的类型,以及在iOS 8上需要支持的方法声明中,这在我看来是错误的)。 – floriankrueger