
StoreKitを使ってアプリ内課金(In-App Purchase)を実装するうえで中心的な存在となるのが Product 構造体です。
この記事では、SwiftにおけるStoreKit 2の Product 構造体について、その基本的な役割や使い方、主要プロパティやメソッドをわかりやすく解説します。
Product構造体とは?
Product はStoreKit 2で導入された構造体で、App Storeに登録した課金アイテム(消耗型、非消耗型、サブスクリプションなど)をアプリ側で扱うためのデータモデルです。
ユーザーに表示する商品名や価格、説明といった情報がこの Product に含まれています。
StoreKit 1では SKProduct クラスを使っていましたが、SwiftUIや非同期処理に最適化されたStoreKit 2では Product 構造体に置き換えられました。
StoreKit 2では、非同期で商品情報を取得し、Swiftらしい書き方で課金処理を行うことができるようになっています。
基本的な使い方
まずはStoreKit 2を使って Product を取得するシンプルなコード例を見てみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import StoreKit @MainActor class StoreManager: ObservableObject { @Published var products: [Product] = [] func fetchProducts() async { do { let storeProducts = try await Product.products(for: [ "com.example.app.coin100", "com.example.app.premium" ]) products = storeProducts } catch { print("商品の取得に失敗しました: \(error)") } } } |
このコードでは、Product.products(for:) メソッドを使って、指定したProduct IDの課金商品情報を取得しています。
取得結果は [Product] 型として返ってきます。
この Product 1つ1つが、App Storeに登録した課金アイテムに対応しています。
主要なプロパティ
StoreKitの Product には多くのプロパティが用意されていますが、よく使うものをピックアップして紹介します。
| プロパティ名 | 型 | 説明 |
|---|---|---|
id |
String |
Product ID(例: com.example.app.coin100) |
displayName |
String |
商品名(例: 100コイン) |
description |
String |
商品の説明文 |
price |
Decimal |
商品の価格(税抜) |
displayPrice |
String |
ユーザーに表示する形式の価格(例: ¥120) |
subscription |
Product.SubscriptionInfo? |
サブスクリプション情報(定期購入のみ) |
type |
Product.ProductType |
商品タイプ(消耗型、非消耗型、サブスクリプションなど) |
これらのプロパティを使うことで、ユーザーに商品を表示する画面を簡単に作れます。
主要なメソッド
Product 構造体は、課金アイテムの情報を保持するだけでなく、実際にアプリ内課金を行うためのメソッドも提供しています。
特に .products(for:) と .purchase() は、StoreKit 2 を使った課金処理の中心となります。
代表的なメソッド一覧
| メソッド名 | 戻り値 | 説明 |
|---|---|---|
Product.products(for ids: [String]) |
[Product] |
指定したProduct IDに対応する商品一覧を非同期で取得する |
Product.purchase(options:) |
PurchaseResult |
購入処理を開始し、結果(成功・キャンセル・保留など)を返す |
ポイント
.products(for:)は 複数のIDを一度に渡せる.purchase()は 購入の開始から検証まで非同期で完結- 返ってくる結果は必ず
.verifiedをチェックする必要がある
具体例:ユーザーに購入させる処理
取得した Product に対して .purchase() メソッドを呼び出すことで、実際の課金処理を開始できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
func purchase(_ product: Product) async { do { let result = try await product.purchase() switch result { case .success(let verification): if case .verified(_) = verification { print("購入成功!") // 機能のアンロックなど } else { print("購入検証失敗") } case .userCancelled: print("ユーザーがキャンセルしました") case .pending: print("保留中の購入があります") default: break } } catch { print("購入処理中にエラーが発生しました: \(error)") } } |
この .purchase() メソッドは非同期で、ユーザーに購入ダイアログを表示し、購入完了後の検証まで含めて処理してくれます。
検証結果が .verified のときだけ、実際に購入が完了しているとみなして、機能をアンロックするのがポイントです。
Productの活用シーン
Product 構造体は以下のような場面で活用されます。
- アプリ内で購入できるアイテムやプランを一覧表示する
- ユーザーに価格を表示して購入してもらう
- サブスクリプションのプラン比較UIを表示する
- 課金によるロック解除やプレミアム機能を実装する
- 価格のローカライズ対応(
displayPriceが自動で通貨を考慮)
特に displayPrice を使えば、各国の通貨に合わせた表示が自動で行われるため、価格の国際対応も非常に簡単に行えます。
注意点と事前準備
Product を使うには以下のような前提条件があります。
- App Store Connectに商品IDを登録しておく必要がある
- 実機でのテストが基本(シミュレータでは課金動作はできない)
Product.products(for:)で取得するIDが正しく設定されていることpurchase()後の検証処理をしっかり行うこと(.verifiedかどうかのチェック)
また、StoreKit 2の機能を利用するには iOS 15 以降 が必要です。
まとめ
今回はStoreKit 2における Product 構造体について全体像を解説しました。
ProductはApp Storeの商品情報を扱うためのデータ構造Product.products(for:)で商品一覧を取得displayNameやdisplayPriceを使ってUIに商品を表示.purchase()メソッドで購入処理を非同期に実行- サブスクリプションにも対応しており、価格のローカライズも簡単
これらの機能を使いこなせば、SwiftUIベースのアプリでもスムーズに課金機能を導入できます。
ぜひStoreKit 2と Product を活用して、課金対応アプリを作ってみてくださいね!
