2013-11-21 6 views
12

Wenn wir einen iOS7-Beleg aktualisieren müssen, verwenden Sie SKReceiptRefreshRequest. Dadurch wird ein Apple-Dialogfeld geöffnet, in dem sich der Benutzer mit seiner Apple ID anmelden kann. Außerdem können sie abbrechen. Wie können wir feststellen, ob der Benutzer auf Abbrechen drückt? (Natürlich kann dies in iOS6 mit catching the cancel event for [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] erfolgen).Ermitteln, ob Benutzer SKReceiptRefreshRequest abgebrochen hat, um sich anzumelden

Das SKReceiptRefreshRequest Objekt hat einen Delegierten mit zwei Methoden: Wenn der Benutzer

- (void)requestDidFinish:(SKRequest *)request; 
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error; 

In meinem Code der requestDidFinish Delegat-Methode aufgerufen wird tut oder nicht drücken nicht abbrechen.

Der Grund, warum dies für mich wichtig ist, ist, dass ich den Wiederherstellungsvorgang abbrechen möchte, wenn der Benutzer Abbrechen drückt. Wenn nach der Aktualisierungsanforderung einfach kein Beleg vorhanden war, könnte dies relativ einfach sein. Manchmal ist jedoch in der App vor dem SKReceiptRefreshRequest eine Quittung (mit einigen Käufen) vorhanden, die in der App verbleibt, wenn der Benutzer den Anmeldevorgang abbricht.

Ich habe zwei Ideen, wie dies zu tun:

1) Löschen Sie den Eingang aus dem Bündel vor der Auffrischanforderung. Das offensichtliche Problem dabei ist, dass die App Dateien nicht aus dem Bundle entfernen kann (siehe z. B. Delete file from bundle after install). Ich habe es versucht. Nee.

2) Überprüfen Sie die Bytes der Quittung vor der Aktualisierungsanforderung und danach; Wenn sie sich unterscheiden, sollte dies anzeigen, dass der Benutzer nicht auf Abbrechen geklickt hat. Wenn sie sich nicht unterscheiden, bin ich mir nicht sicher, ob anzeigt, dass sie Abbrechen gedrückt haben. Wenn die Quittung Käufe enthält, denke ich, dass sich die Bytes unterscheiden, da ein aufgefrischter Beleg unterschiedliche Transaktions-IDs haben sollte (aber die gleiche "ursprüngliche" Transaktions-ID). Wenn die Quittung keine Einkäufe enthält, bin ich mir nicht sicher.

Aktualisierung, 11/9/15; Ich habe gerade bemerkt, dass die Delegiertenantwort auf den Benutzer, der Abbrechen drückt, sich geändert zu haben scheint. Jetzt wird didFailWithError aufgerufen. Das Problem des Erkennens einer Benutzerlöschung bleibt jedoch bestehen. Wie können wir unterscheiden, ob der Benutzer Abbrechen und einen echten Fehler drückt? Ich habe auf iOS8.4 und iOS9.2 (Beta) getestet. Ich habe diesen Mangel an Unterscheidbarkeit jetzt als einen Fehler an Apple gemeldet (Bug # 23476210).

Aktualisierung, 11/10/15; Dieses Problem wird nicht erscheinen mit iOS 9.0.2! Ich habe das jetzt mit allen drei Systemen mit der gleichen App-Binärdatei im gleichen ungefähren Zeitintervall versucht (innerhalb von 20 Minuten für alle drei Systeme): (A) iOS9.2 (13C5050d): Problem tritt auf (didFailWithError wird aufgerufen) (B) iOS9.0.2, Problem tritt nicht auf (requestDidFinish wird aufgerufen) und (C) iOS8.4.1, Problem tritt auf. Bei allen drei Systemversionen läuft dies auf echter Hardware, nicht auf dem Simulator.

+0

Ich habe gerade Nummer 2) oben getestet. Und wenn vor der Aktualisierung ein nicht leerer Beleg vorhanden ist, der keine Einkäufe enthält, wird nach der Aktualisierung ein ** anderer ** nicht leerer Beleg angezeigt. Oder zumindest in den zwei Versuchen, die ich gemacht habe, war das der Fall. Eine direktere Lösung wäre natürlich gut. Z. B. eine Löschmethode, die aufgerufen wurde, um anzuzeigen, dass der Benutzer Cancel gedrückt hat. Byteweise unterschieden sich 5515 Bytes und 5522 Bytes zwischen den Quittungen in den Tests, die ich gemacht habe. –

Antwort

1

iOS 9.2.1, Xcode 7.2.1 aktiviert ARC

Ich verstehe Sie diese vor 2 Jahren gefragt, aber ich hatte vor kurzem mit diesem Thema mein zulaufen und eine Lösung gefunden und wollte teilen Hier können andere etwas Zeit sparen.

1) Sie können den Beleg in einen Schlüsselbund speichern und auf eine Kopie davon zugreifen. Dadurch können Sie ihn löschen oder nach Belieben aktualisieren.

2) Ja, Sie können auf jeden Fall überprüfen, ob es änderte ich glaube, der einfachste Weg, dies zu tun zu verwenden ist:

[receipt isEqualToData:(NSData *)(copyReceiptObject)] 

Mein Vorschlag lautet wie folgt:

Der Schlüssel ist die error Sie aus dem Verfahren erhalten zu erwarten:

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error;

wird aufgerufen, wenn der Benutzer auf Abbrechen klickt, nachdem der Anmeldedialog im iTunes Store angezeigt wird. Es gibt viele individuelle waren Sie die Auffrischanforderung tun könntest, so dass die Ergebnisse können variieren, aber hier sind die unterschiedlichen Fehler, den Sie für meine Anfrage bekommen:

Wenn es keine Verbindung zu iTunes ist:

Fehler Domain = SSErrorDomain-Code = 110 "Kann keine Verbindung zum iTunes Store" Userinfo = {NSLocalizedDescription = Kann nicht zum iTunes Store verbinden, NSUnderlyingError = 0x13c76d680 {Fehler Domain = NSURLErrorDomain -Code = -1009 „Kann keine Verbindung zum iTunes Store " Userinfo = {NSLocalizedDescription = Kann keine Verbindung zum iTunes Store, NSErrorFailingURLStringKey =

{Ihr Produkt-IDs und entsprechenden URIs hier}

, _kCFStreamErrorCodeKey = 8, _kCFStreamErrorDomainKey = 12, NSLocalizedDescription = Die Internet-Verbindung wird angezeigt . offline sein}}}

Wenn die Benutzer Hähne abbrechen:

Fehler Domain = SSErrorDomain-Code = 16 "Kann nicht an iTunes Store verbinden" Userinfo = {NSLocalizedDescription = Kann nicht zum iTunes Store verbinden, NSUnderlyingError = 0x13c6ac7b0 {Fehler Domain = AKAuthenticationError -Code = -7003 „(null) "}}

die einfachste ich denke, ist die error.code zu überprüfen, wenn Sie kompliziertere Sie den vollständigen Fehler Zeichenfolge analysieren können wählen, um weitere Informationen zu erhalten, um den Fehler erhalten möchten.

In meinem Fall keine Verbindung Fehlercode 110 und wenn der Benutzer das Protokoll im Code Fehler abgebrochen ist 16. Behandeln Sie den Fehler.

+0

Ich möchte mehr über diese Fehler wissen und fragte eine Follow-up-Frage hier http://StackOverflow.com/q/35851069/4018041 über SSErrorDomain. –

+0

Ich habe keine Ahnung, wie zuverlässig es ist, solche Fehlercodes zu verwenden, aber ab Januar 2017 wird der Fehlercode 16 immer noch zurückgegeben, wenn die Abbruch-Taste gedrückt wird. – Richard

+0

Nicht zuverlässig, aber ich kenne keine andere Möglichkeit, dies zu erkennen, und dies ist eine wünschenswerte Bedingung, um die Benutzererfahrung zu verbessern. Vielen Dank für die Bestätigung, dass es immer noch funktioniert. –