web-dev-qa-db-ja.com

iOSアプリのレシートの更新:ユーザーがアプリストアにサインインする必要があるかどうかを判断する方法は?

私はiOS 7にAppleの「グランドユニファイドレシート」を実装しています。これにより、アプリは検証と検証のためにAppleのサーバーに連絡する必要なく、アプリの購入レシートをローカルで確認できます。これは、ユーザーがアプリにレシートを保存している場合に最適です。アプリにレシートがない場合のベストプラクティスは、次のようにアプリにレシートの更新を要求することです。

    SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
    [request setDelegate:self];
    [request start];

問題は、このコードを呼び出すと、ユーザーにApple IDでログインするように求められます。これが常に発生するのか、またはユーザーのアプリがストアのログインがタイムアウトしました。本当に必要な場合を除いて、Apple IDログイン画面をユーザーに表示したくないのですが、間違って請求されることを人々に心配したくありません。 。Apple IDパスワードを要求される理由をユーザーに知らせる画面を表示したいのですが、実際にパスワードを入力する必要がある場合に限られます。パスワードを入力するには、シームレスで非表示のプロセスにしたいのですが、続行するための最善の方法は何ですか?ユーザーがアプリストアにサインインする必要があるかどうかを確認するのが最善の方法だと思いますが、よくわかりませんそれが可能な場合。

24
Jason

これに対処するのは非常に複雑なので、この答えは完全に満足のいくものではない可能性があります(そして、私は遅れています-私はそれを知っています)。

私もこれを正しく行っていない可能性がありますが、これまでのところすべてが機能し、理にかなっていますが、ここで「話すBS」であれば、遠慮なく修正してください。

しかし、とにかく、実際に認証アラートが表示されるのを防ぐことはできませんが、表示される回数を最小限に抑える方法はいくつかあります。

存在しないことがわかっている領収書を再ダウンロードする必要はありません。ユーザーが領収書を購入していないか、復元していない場合は、領収書を再ダウンロードすることを避け、アラートビューを完全に回避できます。これは私がやったことです:

if([[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]] != YES)
{
    SKReceiptRefreshRequest *refresh = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
    [refresh start];
}

私のアプリにはIAPでロック解除される多くの「プロ」機能があるので、メインアプリケーションループの前にmain.mファイルにこれを配置しますが、実際にこれを適切な場所に配置できます。

主な考え方は、レシートはアプリのディレクトリに保存された実際のファイルであるということです。したがって、ここで行うすべてのことは、レシートが実際に存在するかどうかを確認することです。そうでない場合は、更新する手間が省け、ユーザーに認証画面を表示する手間が省けます。

必要に応じて、ユーザーがアプリの「プロ」機能を使用できる場所にこのコードを配置できます。 SKReceiptRefreshRequestSKRequestを継承しているため、SKRequestDelegateメソッドを呼び出します。したがって、ユーザーがプロ機能のある画面に移動した瞬間に、レシートを更新し、デリゲートメソッドが呼び出されたときに(レシートの内容を確認する追加の作業を行った後で)この機能を有効にすることができます。

このアプローチの大きな欠点は、インターネット接続が必要なことです。アプリがオフラインで動作する場合、ユーザーはすべてのIAPもオフラインで動作することを期待するため、特定のシナリオではレシートの再ダウンロードが問題になります。

16
Andy Ibanez

App Storeアプリでは通常、領収書が存在します。アプリと一緒にApp Storeからダウンロードされます。ユーザーがiTunesを使用して(つまり、バックアップから)デバイスにアプリをロードした場合、領収書はありません。

Xcodeでデバッグしていて、レシートをダウンロードさせるための操作を何も行っていない場合(レシートの更新や何かの購入など)は、レシートが存在しない主な使用例です。

本番環境では、ユーザーが何らかのアクションを実行した後にのみ、新しい(新しい)レシートを取得できます(何かを購入し、レシートを更新してサインインし、購入を復元してサインインします)。サイレントにレシートを更新する方法はありません。

ユーザーの操作なしで新しいレシートを取得したい場合は、サーバールートに移動する必要があります。サーバーを介して古いレシートをiTunesに送信し、最新のレシートを受け取ります。

7
nevan king

私の経験を共有したいと思います。サンドボックスで作業していて、アプリを削除した後にアプリの領収書が表示されません。 (そして、re-Command-R-ing)これが本番環境で発生するかどうかはわかりませんが、発生しているように聞こえます。アプリの初回起動時に更新を要求し、ユーザーにパスワードを要求するのは驚くべきことです。もちろん、これは問題です。

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]もアプリのレシートをサイレントに更新するようですなしダイアログボックスをポップします。つまり、トランザクションが復元された後、appReceiptURL + Dataを要求すると、nil以外の値が返されます。これは、私の短いテストの結果です。自分でテストしてください。

5
No Name