トラブルシューティング
このページでは、AppCoins iOS SDK を Swift および Unity で連携する際に開発者が遭遇しやすい問題と、その解決方法を説明します。各項目は、症状、原因、対処方法という同じ構成になっています。
isAvailable() が常に false を返す
症状: 実機であっても、AppcSDK.isAvailable()(Swift)または AppCoinsIAP.ConfigureStoreAsync の Automatic モードの判定(Unity)で AppCoins 課金が有効になりません。
原因:
- テスト環境が設定されておらず、アプリが代替マーケットプレイス経由で配信されたものと認識されていない。
- デバイスの iOS が 17.4 より前のバージョンである。
- アプリが Apple App Store または TestFlight からインストールされている。
インストール元の一覧と利用可否への影響については、実行時判定の仕組み を参照してください。
対処方法:
- Xcode でターゲットの Build Settings を開き、Marketplaces を検索します。Deployment で値を
com.aptoide.ios.storeに設定します。 - スキームで Run → Options を開き、Distribution のドロップダウンから
com.aptoide.ios.storeを選択します。 - iOS 17.4 以降が動作する実機で実行します。
あるいは、再ビルドせずに実行時に AppCoins モードを強制することもできます。デバイスで Safari を開き、次の URL にアクセスしてください。
{bundle_id}.iap://wallet.appcoins.io/default/mode?value=appcoins
{bundle_id} はアプリケーションのバンドル識別子に置き換えてください。Apple 課金へのフォールバックをテストするには value=apple を、通常の判定に戻すには value=automatic を使用します。なお、不正利用を防ぐため、Apple App Store からインストールされたビルドではモードの上書きは無効です。
購入時に notEntitled エラーが発生する
症状: product.purchase()(Swift)または controller.InitiatePurchase(Unity)を呼び出すと、決済シートが表示されずに即座に AppCoinsSDKError.notEntitled がスローされる、または返されます。
原因:
- Keychain Sharing 機能がターゲットに追加されていない。
- キーチェーングループが誤った値に設定されている(Xcode がチーム識別子やバンドル識別子を自動入力する場合があります)。
対処方法:
- Xcode でターゲットを選択し、Signing & Capabilities タブを開きます。
- + をクリックして Keychain Sharing 機能を追加します。
- Keychain Groups の一覧で既存のエントリをすべて削除し、
com.aptoide.appcoins-walletと正確に入力します。 - クリーンしてから再ビルドします。
com.aptoide.appcoins-wallet である必要があります。それ以外の値を設定すると、実行時に notEntitled が発生します。商品の配列が空になる/productUnavailable エラーが発生する
症状: Product.products(for:)(Swift)が空の配列を返す、または GetProducts(Unity)が OnProductsFetchFailed を発火します。あるいは product.purchase() が productUnavailable をスローします。
原因:
- アプリが Aptoide Connect でまだ提出・承認されていない。
- コード内の SKU 識別子が、Aptoide Connect で定義されたものと完全には一致していない(識別子は大文字と小文字を区別します)。
対処方法:
- Aptoide Connect を開き、アプリのリスティングが存在し、承認済みであることを確認します。
- アプリのリスティングで Products に移動し、各 SKU 識別子が
Product.products(for:)(Swift)または Unity のProductCatalogに渡している値と 1 文字単位で一致していることを確認します。 - 商品を照会できるようになるのは、審査に通過した後のみです。
決済のリダイレクトが完了しない(購入が停止したままになる)
症状: ユーザーが決済方法へリダイレクトされるものの、アプリが購入結果を一切受け取らず、購入が保留のままになります。
原因(Swift):
- URL コンテキストのハンドラーで
AppcSDK.handle(redirectURL:)が呼び出されていない。 - Info → URL Types に、ロール Editor の URL スキーム
$(PRODUCT_BUNDLE_IDENTIFIER).iapが存在しない。
対処方法:
- Xcode でターゲットの Info タブを開きます。URL Types に次のエントリがあることを確認してください。
- URL Schemes:
$(PRODUCT_BUNDLE_IDENTIFIER).iap - Role:
Editor
- URL Schemes:
SceneDelegate.swiftで、scene(_:openURLContexts:)がAppcSDK.handle(redirectURL:)を呼び出していることを確認します。なお、AppcSDK.initialize()は URL ハンドラー内ではなく、アプリ起動時のwillConnectToで呼び出す必要があります。
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if AppcSDK.handle(redirectURL: URLContexts.first?.url) { return }
// your existing URL handling
}
Unity の場合、ポストビルドスクリプトが URL スキームを自動的に追加します。それでも購入が停止したままになる場合は、Unity から Xcode プロジェクトを再ビルドし、Xcode ターゲットの Info タブに URL Type が表示されていることを確認してください。
アプリのクラッシュや再起動の後にユーザーの購入が反映されない
症状: ユーザーは支払いを完了したものの、購入フローの途中でアプリがクラッシュまたは強制終了されたためにアイテムを受け取れず、再起動後もアイテムが付与されていません。
原因: 起動時に Transaction.unfinished(Swift)を反復処理していない、または FetchPurchases(Unity)を呼び出していないため、支払い済みかつ未消費のトランザクションが復元されていません。
対処方法(Swift):
isAvailable() チェックの後、アプリの初期化シーケンスに未完了トランザクションの処理を追加します。
func processUnfinishedTransactions() async {
guard await AppcSDK.isAvailable() else { return }
for await verificationResult in Transaction.unfinished {
switch verificationResult {
case .verified(let transaction):
giveItemToUser(productID: transaction.productID)
await transaction.finish()
case .unverified(_, let error):
print("Unverified unfinished transaction: \(error.description)")
}
}
}
対処方法(Unity):
Connect() の前に ProcessPendingOrdersOnPurchasesFetched(true) を設定し、その後で FetchPurchases() を呼び出します。未完了の購入は、新規購入と同じ OnPurchasePending ハンドラーを通じて再度届きます。
async void Start()
{
await AppCoinsIAP.ConfigureStoreAsync(AppCoinsStoreMode.Automatic);
controller = UnityIAPServices.StoreController();
controller.OnPurchasePending += OnPurchasePending;
// Must be set before Connect so FetchPurchases results come through OnPurchasePending
controller.ProcessPendingOrdersOnPurchasesFetched(true);
await controller.Connect();
controller.FetchPurchases(); // recovers unfinished transactions
}
transaction.id の型の不一致(Swift)
症状: transaction.id を比較または保存する際にコンパイルエラーや予期しない動作が発生し、StoreKit で動作していたコードが AppCoins SDK ではコンパイルできない、または誤った結果になります。
原因: StoreKit の Transaction.id は UInt64 ですが、AppCoins SDK の Transaction.id は String です。StoreKit の連携からコピーしたコードは動作しません。
対処方法:
すべての比較および保存処理で transaction.id を String として扱うよう更新してください。
// Wrong (StoreKit pattern)
let id: UInt64 = transaction.id
// Correct (AppCoins SDK)
let id: String = transaction.id
同一のコードベースで StoreKit と AppCoins の課金を併用している場合は、必要に応じて StoreKit のトランザクション ID を変換してください。
let appCoinsCompatibleID = String(storeKitTransaction.id)
Unity: Connect の前に ConfigureStoreAsync を await していない
症状: Unity IAP は接続されるものの、誤った課金プロバイダーが使用される、または OnProductsFetched が発火しません。本来有効になるはずのデバイスでも AppCoins 課金が有効になりません。
原因: ConfigureStoreAsync の完了前に controller.Connect() が呼び出されました。Unity IAP の初期化時点で、AppCoins のストアプロバイダーがまだ登録されていません。
対処方法:
Connect を呼び出す前に、必ず ConfigureStoreAsync を await してください。
async void Start()
{
var selectedStore = await AppCoinsIAP.ConfigureStoreAsync(AppCoinsStoreMode.Automatic);
Debug.Log("Selected store: " + selectedStore);
await controller.Connect();
}
ConfigureStoreAsync は Connect を呼び出す前に await する必要があります。await しない場合、AppCoins ストアの登録が間に合わず、Unity IAP が Apple にフォールバックするか、エラーを出さずに失敗する可能性があります。Unity: デバイスで AppCoins が有効にならない(Automatic モード)
症状: iOS 17.4 以降の実機で Automatic モードを使用しているにもかかわらず、AppCoinsIAP.SelectedStore が常に "AppleAppStore" になります。
原因: テスト環境が未設定です。Swift で isAvailable() が false を返す場合と同じ根本原因です。
対処方法:
Xcode とスキームに同じ設定を適用してください。
- Build Settings で Marketplaces を
com.aptoide.ios.storeに設定します。 - スキームの Run → Options → Distribution で
com.aptoide.ios.storeを選択します。
または、デバイスの Safari から次のディープリンクを開いて AppCoins モードを強制します。
{bundle_id}.iap://wallet.appcoins.io/default/mode?value=appcoins