以前の AppCoins SDK バージョンからの更新
このガイドでは、以前のバージョンの AppCoins iOS SDK から現行バージョンへ更新する方法を説明します。新バージョンは StoreKit 2 の公開インターフェースに合わせて設計されており、そのためにいくつかのプロパティ名の変更、Purchase 型から Transaction への置き換え、および PurchaseIntent / Purchase.updates フローの完全な削除が必要となりました。
概要
現行 SDK バージョンにおける主な変更点は次のとおりです。
PurchaseからTransactionへの名称変更 —Purchase.all、Purchase.unfinished、Purchase.latestは、それぞれTransaction.all、Transaction.unfinished、Transaction.latest(for:)になりました。PurchaseIntentとPurchase.updatesの削除 — 旧来のPurchase.updatesは、明示的な確認を必要とするPurchaseIntentオブジェクトを発行していました。購入結果はproduct.purchase()からVerificationResult<Transaction>として直接返されるようになりました。Productのプロパティ名の変更 —sku→id、title→displayName、priceLabel→displayPrice。Product.products(domain:for:)の簡素化 —domainパラメータが削除されました。SDK がバンドル識別子を自動的に読み取ります。- 購入エラーが throw されるように変更 —
.failed(let error)の結果ケースを、product.purchase()を囲むdo/catchに置き換えてください。 transaction.finish()が throw しなくなった —tryキーワードを削除してください。
互換性のない変更の一覧
| 旧 API | 新 API |
|---|---|
product.sku | product.id |
product.title | product.displayName |
product.priceLabel | product.displayPrice |
product.priceValue | product.displayPrice(整形済み)または product.price(Decimal) |
Product.products(domain:for:) | Product.products(for:) — domain は削除 |
PurchaseResult.failed(let error) | throws AppCoinsSDKError — do/catch を使用 |
try await purchase.finish() | await transaction.finish() — throw しなくなりました |
Purchase.unfinished()(async、throws) | Transaction.unfinished — AsyncStream、throw なし |
Purchase.all()(async、throws) | Transaction.all — AsyncStream |
Purchase.latest(sku:) | Transaction.latest(for: productID:) |
Purchase.updates(PurchaseIntent のストリーム) | 削除 — product.purchase() の戻り値を使用 |
PurchaseIntent.confirm() | 削除 |
PurchaseIntent.reject() | 削除 |
Xcode の設定
Xcode のターゲットで次の設定が行われていることを確認してください。これらは SDK の動作に必須です。
-
Keychain Sharing
- Project Navigator(左サイドバー)でプロジェクトを選択します。
- TARGETS でターゲットを選択します。
- Signing & Capabilities タブを開きます。
- + ボタンをクリックして新しい機能を追加します。
- Keychain Sharing を検索して選択します。
- Keychain Groups フィールドで、既定値を
com.aptoide.appcoins-walletに正確に置き換えます。
-
URL スキーム
- TARGETS でターゲットを選択します。
- Info タブに移動します。
- URL Types セクションを展開し、+ をクリックします。
- URL Schemes を
$(PRODUCT_BUNDLE_IDENTIFIER).iap、Role を Editor に設定します。
-
MKSellsDigitalGoods
- Info タブで Custom iOS Target Properties セクションまでスクロールし、+ をクリックします。
- キー
MKSellsDigitalGoodsを追加し、値をYES(Boolean)に設定します。
1. 購入フローの更新
変更前:
let result = await product.purchase()
switch result {
case .success(let verificationResult):
switch verificationResult {
case .verified(let purchase):
try await purchase.finish()
case .unverified(let purchase, let error):
print("Unverified: \(error)")
}
case .pending:
break
case .userCancelled:
break
case .failed(let error):
print("Purchase failed: \(error)")
}
変更後:
do {
let result = try await product.purchase()
switch result {
case .success(let verificationResult):
switch verificationResult {
case .verified(let transaction):
await transaction.finish()
case .unverified(let transaction, let error):
print("Unverified: \(error)")
}
case .pending:
break
case .userCancelled:
break
}
} catch let error as AppCoinsSDKError {
print("Purchase failed: \(error)")
}
相違点は次の 2 点です。
product.purchase()がtry await product.purchase()になりました。この呼び出しは throw する可能性があります。try await purchase.finish()がawait transaction.finish()になりました。この呼び出しは throw しなくなりました。
2. 未完了トランザクションの更新
変更前:
func processUnfinished() async {
do {
let purchases = try await Purchase.unfinished()
for purchase in purchases {
giveItem(for: purchase.sku)
try await purchase.finish()
}
} catch {
print("Error loading unfinished: \(error)")
}
}
変更後:
func processUnfinished() async {
if await AppcSDK.isAvailable() {
for await verificationResult in Transaction.unfinished {
if case .verified(let transaction) = verificationResult {
giveItem(for: transaction.productID)
await transaction.finish()
}
}
}
}
Transaction.unfinished は AsyncStream です。for await で反復処理してください。try は不要で、別途ループするためのラッパー配列もありません。
3. Transaction.all と Transaction.latest の更新
変更前:
let purchases = try await Purchase.all()
let latest = try await Purchase.latest(sku: "gas")
変更後:
// Iterate all transactions
for await verificationResult in Transaction.all {
if case .verified(let transaction) = verificationResult {
// handle transaction
}
}
// Get the latest transaction for a product
if let verificationResult = await Transaction.latest(for: "gas") {
if case .verified(let transaction) = verificationResult {
// handle transaction
}
}
4. PurchaseIntent の処理を削除する
旧 SDK では、Purchase.updates が、明示的な確認または拒否を必要とする PurchaseIntent オブジェクトのストリームとして公開されていました。Purchase.updates を監視するコードはすべて削除してください。代替となるストリームはありません。購入結果は product.purchase() から直接返されます。
変更前:
for await intent in Purchase.updates {
if User.isSignedIn {
let result = await intent.confirm()
// handle result
}
}
変更後: この監視処理を完全に削除します。product.purchase() を呼び出す箇所で結果を処理してください。
let result = try await product.purchase()
switch result {
case .success(let verificationResult):
if case .verified(let transaction) = verificationResult {
giveItem(for: transaction.productID)
await transaction.finish()
}
case .pending, .userCancelled:
break
}
ユーザーが認証されるまで確認を遅らせる実装にしていた場合は、保留中の商品を保存しておき、ユーザーのログイン後に product.purchase() を呼び出してください。
5. エラー処理の変更
変更前:
switch result {
case .failed(let error):
switch error {
case .networkError:
showNetworkAlert()
case .purchaseNotAllowed:
showNotAllowedAlert()
default:
showGenericAlert()
}
// ...
}
変更後:
do {
let result = try await product.purchase()
// handle result
} catch let error as AppCoinsSDKError {
switch error {
case .networkError:
showNetworkAlert()
case .purchaseNotAllowed:
showNotAllowedAlert()
case .productUnavailable:
showUnavailableAlert()
case .notEntitled:
showEntitlementAlert()
case .systemError:
showSystemErrorAlert()
case .unknown:
showGenericAlert()
}
}
AppCoinsSDKError のケースはすべて変更ありません。変わったのは、結果のケースとして受け取るか、スローされたエラーとして受け取るかという受け取り方だけです。