カテゴリー: iOS

[iOS15]StoreKit2で課金処理をより簡単に

はじめに

iOS15からStoreKitが大きくアップデートされ、StoreKit2として新しくなりました。
今回はStoreKit2を使用した購入処理を紹介したいと思います。

StoreKit2になって主に変更された箇所

StoreKit2の主な変更点は以下の二つだと思います。

  • async/awaitの追加によりDelegateなど使用せずに簡単かつ、短く記述できる。
  • SKProduct,SKPayment,SKPaymentQueue,SKPaymentTransaction,SKProductsRequestなど登場人物が多く複雑だったのが、主にProduct,Transactionだけになった。

これにより、コードが見やすく、簡単に実装できるようになったと思います。

実装

Product(課金アイテム)の取得方法

課金アイテムの取得方法は以下のように記述します。
結果は、Productの配列として、取得できます。

let storeProducts = try await Product.products(for: ["nonconsumable.item1", "nonconsumable.item2"])

ちなみに今までのStoreKitだとこのように記述します。

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行で取得することができます。

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です。

let result = try await product.purchase()

結果は、PurchaseResultというenumが取得できます。このようにして購入のチェックを行います。

switch result {
case .success(let verification):
    // 購入成功処理
case .userCancelled, .pending:
    return nil
default:
    return nil
}

Product(課金アイテム)の購入状況を確認する

購入状況を確認するにはTransaction.latestを使用し、課金アイテムの最新のTransactionを取得します。nilにならない場合はすでに購入済みということになります。

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からしか使用できないのは注意が必要ですが、以前と比べてかなり課金処理が簡単に行えるようになったので、これから課金処理を実装する人は是非使って見てください。

参考

https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api

おすすめ書籍

nukky

シェア
執筆者:
nukky
タグ: SwiftiOS

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前