Adding and removing a transaction queue observer is the right way?

Regarding In App Purchase ... I refer to this Technical Note: https://developer.apple.com/library/ios/technotes/tn2387/_index.html

It states that we must add a transaction observer to didFinishLaunchingWithOptions in the AppDelegate file. And that we must remove the transaction observer in applicationWillTerminate AppDelegate .

This does not correspond to many textbooks that I read (fairly current), and also does not agree with many topics on this issue (also recently).

I am embarrassed. Apple is obviously the "king of the heap." So I have to take the direction of the technical note and add the transaction queue observer to didFinishLaunchingWithOptions and delete it in applicationWillTerminate ?

Can someone clarify this a bit more? Thanks in advance.

+5
source share
2 answers

You are asking:

It says that we must add a transaction observer to didFinishLaunchingWithOptions in the AppDelegate file. And that we must remove the transaction observer in applicationWillTerminate AppDelegate .

This is not consistent with many tutorials I read ...

No, there is nothing wrong with adding it this way. As noted in the technical note: "Adding an observer to the application at startup ensures that it will be preserved during all launches of your application, which will allow your application to receive all notifications about the payment queue."

If there is any link that you have that advises against this practice, edit your question and share a specific link with us, and we can comment on this link.

In a comment, you later asked:

Do I also need to include all relevant delegate methods in AppDelegate ?

There are several options. For example, you can create an instance of a selected object for this. In Swift 3:

 let paymentTransactionObserver = PaymentTransactionObserver() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { SKPaymentQueue.default().add(paymentTransactionObserver) return true } func applicationWillTerminate(_ application: UIApplication) { SKPaymentQueue.default().remove(paymentTransactionObserver) } 

Or in Swift 2:

 let paymentTransactionObserver = PaymentTransactionObserver() func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { SKPaymentQueue.defaultQueue().addTransactionObserver(paymentTransactionObserver) return true } func applicationWillTerminate(application: UIApplication) { SKPaymentQueue.defaultQueue().removeTransactionObserver(paymentTransactionObserver) } 

C, in Swift 3:

 class PaymentTransactionObserver: NSObject, SKPaymentTransactionObserver { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { ... } func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { ... } func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { ... } func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { ... } func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) { ... } } 

Or in Swift 2:

 class PaymentTransactionObserver: NSObject, SKPaymentTransactionObserver { func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { ... } func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { ... } func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { ... } func paymentQueue(queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: NSError) { ... } func paymentQueue(queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) { ... } } 

Or, conversely, you can add it directly to your AppDelegate , but if you do, you might want to add a protocol match with the extension so that these respective methods are carefully grouped, for example in Swift 3:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { SKPaymentQueue.default().addTransactionObserver(self) return true } func applicationWillTerminate(_ application: UIApplication) { SKPaymentQueue.default().remove(self) } 

Or in Swift 2:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { SKPaymentQueue.defaultQueue().addTransactionObserver(self) return true } func applicationWillTerminate(application: UIApplication) { SKPaymentQueue.defaultQueue().removeTransactionObserver(self) } 

and

 extension AppDelegate: SKPaymentTransactionObserver { // the `SKPaymentTransactionObserver` methods here } 
+11
source

It is useful to add observers when starting the application, because sometimes it happens when the application closes during the flow of purchases or, perhaps, the Internet goes down (such cases are not taken into account in textbooks, since they are more specific for explaining the textbook)

If the transaction is aborted, it will not be completed until the next transaction begins, when you register the observer. To avoid this, you attach it to the launch of the application, and the OS will be updated with the last transaction pending at startup, and this will give a better stream of users.

+5
source

Source: https://habr.com/ru/post/1247636/


All Articles