20

この質問や他の場所で説明されているように、Apple は現在、ユーザーがアプリ内購入の完了したトランザクションを復元する手段を含めることをアプリに要求しています。

私はこれに賛成です。私のアプリの最初のバージョンは、どういうわけかそれなしで審査を通過しました (私はその時点でこの規則を認識していなかったか、および/またはまだ施行されていませんでした)、しかしその後、ユーザーから多くの電子メールを受け取るようになりました不足しているコンテンツについて質問します (データ ストレージ ガイドラインもありますが、重いダウンロード可能なコンテンツはバックアップされません)。

では、UI のどこかに「復元」ボタンを含めて、タップすると次の呼び出しが行われるとします。

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

ここまでは順調ですね。ユーザーは AppleID やパスワードを求められ、復元プロセスが開始されます。

私が抱えている問題は次のとおりです。復元するトランザクションがない場合、AppleID プロンプトの後、基本的にアプリで何も起こらず、ユーザーを混乱させたり、アプリが応答しなくなったり壊れたりする可能性があります。

「すべての購入は最新です」などのアラート ビューを表示できるようにしたいと考えています。

このケースを検出するために、Transaction Observer コードでできることはありますか?

UXの観点から、それが悪いデザインだと思う人はいますか?

4

4 に答える 4

11

これは、最新の SDK / xCode 8.0、Swift 3 ではまだ問題です。購入を行っていないユーザーが「復元」を試みた場合は、次の方法を使用します。

SKPaymentQueue.default().restoreCompletedTransactions()

購入/復元を処理する通常のデリゲート メソッドをトリガーしません。

paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {...}

興味深いことに、おそらくエラーをキャッチするはずのメソッドも呼び出されません。

func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error){...}

代わりに、復元が正常に機能したかのように、オプションのメソッドがトリガーされます。

func paymentQueueRestoreCompletedTransactionsFinished()

これにより、アプリがハングしているように見えたり、何もしていないように見えることがあります。

他の回答で説明したように、これの原因は SKPaymentQueue にトランザクションが含まれていないことです。

Swift では、この問題は次の方法で解決できます。

//Optional Method.
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue)
{

    let transactionCount = queue.transactions.count

    if transactionCount == 0
    {
        print("No previous transactions found")

        //You can add some method to update your UI, indicating this is the problem e.g. use notification centre:
        NotificationCenter.default.post(name: "restoreFailedNoPrevIAP", object: nil)

    }

}

重要なのは、ユーザーが以前に購入したことがある場合、トランザクション キューは空にならないため、updateTransaction デリゲート メソッドが呼び出され、復元要求が正常に処理されることです。

于 2016-09-26T13:29:39.183 に答える
10

次のデリゲート関数を実装することもできます。

-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error

その後、復元プロセスがいつ終了したか、または失敗したかがわかります。paymentQueueRestoreCompletedTransactionsFinished で queue.transactions.count の使用法を混ぜて、トランザクションが復元されたかどうかを確認できます。

で SKPaymentTransactionStateRestored を処理することを忘れないでください

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

SKPaymentTransactionStatePurchased トランザクションで行ったのと同じ方法で、復元されたトランザクションを処理することもできます。

于 2012-08-10T21:35:42.317 に答える
9

購入を復元するための適切な/最適な文言に興味がありました。

[error localizedDescription]insideを使用するだけで、十分な「不明なエラー」アラートが表示され-(void)paymentQueue:restoreCompletedTransactionsFailedWithError:ました。(todo: フィルレーダー)

そこで、Apple のやり方を調べてみました。現時点で消費不可のアプリ内購入が可能な Apple の唯一のアプリは GarageBand (2014 年 12 月) です。

「購入を復元する」、「以前の購入を復元する」などの代わりに、"Already Purchased?".

購入画面1

しかし、これは私がより興味を持っている画面です "Already Purchased?"。復元するものが何もないときにを押した結果です。

購入画面2

"There are no items available to restore at this time."革新的ではありませんが、「未知のエラー」を打ち負かします

では、見てみましょう-(void)paymentQueue:restoreCompletedTransactionsFailedWithError:

iOS :

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
    if ([error.domain isEqual:SKErrorDomain] && error.code == SKErrorPaymentCancelled)
    {
        return;
    }

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"There are no items available to restore at this time.", @"")
                                                    message:nil
                                                   delegate:nil
                                          cancelButtonTitle:NSLocalizedString(@"OK", @"")
                                          otherButtonTitles:nil];
    [alert show];
}

OS X :

私は、OS X で同じテキストだけに満足していません。

私にとっての 1 つのオプションは、ユーザーに購入する必要があることを"To use it, you need to buy “%@”.".

私が思いついた別のオプションは、そこにブラウザを表示させることです購入履歴。で直接リンクできることがわかりましたitms://phobos.apple.com/purchaseHistory。正直なところ、iTunes Store での購入履歴はくだらないものです。

しかし、何かを買い戻させようとしないということは、人々に再保険をかけるのに役立つかもしれません。顧客は非消耗品と消耗品の違いを知らない、または区別できないと常に想定してください。また、非消耗品に対して 2 回請求できないことも知りません。

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
    {
    if ([error.domain isEqual:SKErrorDomain] && error.code == SKErrorPaymentCancelled)
    {
        return;
    }

    NSAlert *alert = nil;
    alert = [NSAlert alertWithMessageText:NSLocalizedString(@"There are no items available to restore at this time.", @"")
                            defaultButton:NSLocalizedString(@"OK", @"")
                          alternateButton:NSLocalizedString(@"Purchase History", @"")
                              otherButton:nil
                informativeTextWithFormat:@"You can see your purchase history in the iTunes Store."];
    NSModalResponse returnCode = [alert runModal];
    if (returnCode == NSAlertAlternateReturn)
    {
        NSURL *purchaseHistory = [NSURL URLWithString:@"itms://phobos.apple.com/purchaseHistory"];
        [[NSWorkspace sharedWorkspace] openURL:purchaseHistory];
    }
}

OS X での例

OS X での例

テストに関する注意事項 (OS X、itunesconnect サンドボックス ユーザー):

ユーザーがキャンセルをクリックすると:

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
Error Domain=SKErrorDomain Code=2 "The payment was canceled by the user" UserInfo=0x600000470a40 {NSLocalizedDescription=The payment was canceled by the user}

復元するものがない場合:

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
Error Domain=SKErrorDomain Code=0 "Unknown Error." UserInfo=0x60800007fb80 {NSLocalizedDescription=Unknown Error.}
于 2014-12-05T23:25:02.683 に答える
0

現在作業中のアプリで同じ問題に遭遇しました。私の回避策は、X 秒のタイマーを使用することです。「購入の復元」ボタンをタップすると開始し、復元されたトランザクション イベントが発生すると再開します。X 秒のマークに達すると、「購入が復元されました」というポップアップが表示されます。したがって、トランザクションがない場合は、X 秒待つだけで済みます。それが役立つことを願っています。

于 2012-07-26T07:40:52.283 に答える