Adding & Removing Transaction Queue Observer - The Correct Way?
You ask:
It states that we should add the transaction observer in
didFinishLaunchingWithOptions
in the AppDelegate file. And that we should remove the transaction observer in theapplicationWillTerminate
of theAppDelegate
.This is not in keeping with many tutorials that I have read ...
No, there's nothing wrong with adding it this way. As the technical note says, "Adding your app's observer at launch ensures that it will persist during all launches of your app, thus allowing your app to receive all the payment queue notifications."
If there's some reference that you have that advises against that practice, please edit your question and share the specific reference with us and we can comment specifically on that link.
In a comment, you later asked:
I will have to include all the relevant delegate methods in the
AppDelegate
also?
There are a few options. For example, you could instantiate a dedicated object for this. Thus:
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)
}
Where:
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, alternatively, you could add it directly to your AppDelegate
, too, (as outlined in Setting Up the Transaction Observer for the Payment Queue). but if you do so, you might want add protocol conformance with an extension, to keep those relevant methods cleanly grouped together, e.g.:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SKPaymentQueue.default().addTransactionObserver(self)
return true
}
func applicationWillTerminate(_ application: UIApplication) {
SKPaymentQueue.default().remove(self)
}
And
extension AppDelegate: SKPaymentTransactionObserver {
// the `SKPaymentTransactionObserver` methods here
}
See previous revision of this answer for Swift 2 rendition.
Its useful to add the observers on app launch since there are sometimes when the app quits during a purchase flow or maybe the internet goes down ( such cases are not taken in account by tutorials since they are more specific on explaining the tutorial)
If a transaction is interrupted, it wont be completed until the next transaction starts where you register observer. To avoid this, you attach it on app launch and the OS will update with the last pending transaction on launch and that will give better user flow.