はじめに
iOS15からStoreKitが大きくアップデートされ、StoreKit2として新しくなりました。
今回はStoreKit2を使用した購入処理を紹介したいと思います。
StoreKit2になって主に変更された箇所
StoreKit2の主な変更点は以下の二つだと思います。
- async/awaitの追加によりDelegateなど使用せずに簡単かつ、短く記述できる。
- SKProduct,SKPayment,SKPaymentQueue,SKPaymentTransaction,SKProductsRequestなど登場人物が多く複雑だったのが、主にProduct,Transactionだけになった。
これにより、コードが見やすく、簡単に実装できるようになったと思います。
実装
Product(課金アイテム)の取得方法
課金アイテムの取得方法は以下のように記述します。
結果は、Productの配列として、取得できます。
1 | let storeProducts = try await Product.products(for: ["nonconsumable.item1", "nonconsumable.item2"]) |
ちなみに今までのStoreKitだとこのように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 | func getProduct() { let request = SKProductsRequest(productIdentifiers: ["nonconsumable.item1", "nonconsumable.item2"]) request.delegate = self request.start() } extension IAPTest: SKProductsRequestDelegate { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { if !response.products.isEmpty { // ここで購入アイテムの確認 } } } |
このようにStoreKitではSKProductRequestを使って、delegateの処理を書いていたところ、StoreKit2では取得自体は、課金アイテムのIDを渡すだけで、1行で取得することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | for product in storeProducts { switch product.type { case .consumable: case .nonConsumable: case .autoRenewable: default: //Ignore this product. print("Unknown product") } } |
また、取得したProductのtypeを確認することで、消耗型、非消耗型、サブスクリプションなどを確認することができます。
Product(課金アイテム)の購入方法
課金アイテムの購入方法は以下のように記述します。
上記で取得したProductにpurchase処理を呼び出すだけでOKです。
1 | let result = try await product.purchase() |
結果は、PurchaseResultというenumが取得できます。このようにして購入のチェックを行います。
1 2 3 4 5 6 7 8 | switch result { case .success(let verification): // 購入成功処理 case .userCancelled, .pending: return nil default: return nil } |
Product(課金アイテム)の購入状況を確認する
購入状況を確認するにはTransaction.latestを使用し、課金アイテムの最新のTransactionを取得します。nilにならない場合はすでに購入済みということになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | func isPurchased(_ productIdentifier: String) async throws -> Bool { //Get the most recent transaction receipt for this `productIdentifier`. guard let result = await Transaction.latest(for: productIdentifier) else { //If there is no latest transaction, the product has not been purchased. return false } let transaction = try checkVerified(result) //Ignore revoked transactions, they're no longer purchased. //For subscriptions, a user can upgrade in the middle of their subscription period. The lower service //tier will then have the `isUpgraded` flag set and there will be a new transaction for the higher service //tier. Ignore the lower service tier transactions which have been upgraded. return transaction.revocationDate == nil && !transaction.isUpgraded } |
さいごに
iOS15からしか使用できないのは注意が必要ですが、以前と比べてかなり課金処理が簡単に行えるようになったので、これから課金処理を実装する人は是非使って見てください。