Обнаружение отмены пользователем SKReceiptRefreshRequest для входа в систему

Когда нам нужно обновить квитанцию ​​iOS7, подходящий способ сделать это - использовать SKReceiptRefreshRequest. Появится диалоговое окно Apple, в котором пользователь может войти в систему, используя свой идентификатор Apple. Это также позволяет им Отменить. Как мы можем определить, нажимает ли пользователь Отмена? (Конечно, в iOS6 это можно сделать с помощью ловите событие отмены для [[SKPaymentQueue defaultQueue] restoreCompletedTransactions ]).

Объект SKReceiptRefreshRequest имеет делегат с двумя способами:

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

В моем коде вызывается метод делегирования requestDidFinish, если пользователь делает или не отменяет.

Причиной для меня является то, что я хочу отменить процесс восстановления, если пользователь нажимает Отмена. Если после запроса обновления просто не было получения, это может быть относительно легко. Однако иногда к приложению SKReceiptRefreshRequest присутствует квитанция (с некоторыми покупками), и она остается в приложении, если пользователь отменяет вход из диалогового окна входа.

У меня есть две идеи, как это сделать:

1) Удалите квитанцию ​​из пакета до запроса обновления. Очевидная проблема заключается в том, что приложение не может удалить файлы из пакета (например, см. Удалить файл из комплекта после установки). Я пытался. Нет.

2) Проверьте байты квитанции перед запросом на обновление и после; если они отличаются, то это должно указывать на то, что пользователь не нажал "Отмена" . Если они не отличаются друг от друга, я не уверен, что указывает, что они нажали Cancel. Если квитанция содержит покупки, я думаю, что байты будут отличаться, потому что обновленная квитанция должна иметь другой идентификатор транзакции (но те же "оригинальные" идентификаторы транзакции). Если квитанция не содержит покупок, я не уверен в этом.

Обновление, 11/9/15; Я только заметил, что ответ делегата на пользователя, нажав "Отмена" , по-видимому, изменился. Теперь вызывается didFailWithError. Однако проблема обнаружения аннулирования пользователя остается. Как мы можем отличить пользователя от нажатия "Отмена" и подлинной ошибки? Я тестировал iOS8.4 и iOS9.2 (бета). Я теперь сообщил об этом недостатке различимости в качестве ошибки для Apple (ошибка # 23476210).

Обновление, 11/10/15; Эта проблема не появляется в iOS 9.0.2! Я просто попробовал это сейчас со всеми тремя системами с одним и тем же бинарником приложения в том же приблизительном интервале времени (в течение 20 минут для всех трех систем): (A) iOS9.2 (13C5050d): Проблема возникает (вызывается didFailWithError и не может различать реальную ошибку и пользователь, нажимающий отменить), (B) iOS9.0.2, проблема не возникает (вызывается requestDidFinish) и (C) iOS8.4.1, проблема возникает. Со всеми тремя версиями системы это работает на реальном оборудовании, а не на симуляторе.

Ответ 1

iOS 9.2.1, Xcode 7.2.1, ARC включен

Я понимаю, что вы спросили об этом 2 года назад, но недавно я столкнулся с этой проблемой и нашел решение, и хотел поделиться этим, чтобы другие могли сэкономить некоторое время.

1) Вы можете выбрать, чтобы сохранить квитанцию ​​в брелок и получить доступ к ее копии, это позволяет вам удалить ее или обновить по своему усмотрению.

2) Да, вы можете определенно проверить, изменилось ли это, я думаю, что самый простой способ сделать это:

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

Мое предложение выглядит следующим образом:

Ключ должен ожидать error от метода:

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

который вызывается, когда отключение пользователя отменяется после входа в журнал входа в iTunes Store. Есть много обычаев, вы могли бы выполнить запрос обновления, поэтому результаты могут отличаться, но вот другая ошибка, которую вы получите для моего запроса:

Если нет подключения к iTunes:

Ошибка домена = SSErrorDomain Code = 110 "Не удается подключиться к iTunes Store" UserInfo = {NSLocalizedDescription = Не удается подключиться к iTunes Store, NSUnderlyingError = 0x13c76d680 {Ошибка домена = NSURLErrorDomain Код = -1009 "Не удается подключиться к iTunes Store" UserInfo = {NSLocalizedDescription = Не удается подключиться к iTunes Store, NSErrorFailingURLStringKey =

{идентификаторы продуктов и соответствующие URI здесь}

_kCFStreamErrorCodeKey = 8, _kCFStreamErrorDomainKey = 12, NSLocalizedDescription = Подключение к Интернету отключено.}}}

Когда пользователь отменяет отмену:

Ошибка домена = SSErrorDomain Code = 16 "Не удается подключиться к iTunes Store" UserInfo = {NSLocalizedDescription = Не удается подключиться к iTunes Store, NSUnderlyingError = 0x13c6ac7b0 { Домен ошибки = AKAuthenticationError Код = -7003 "(null)" }}

Самый легкий, по-моему, проверить error.code, если вы хотите усложнить ситуацию, вы можете выбрать синтаксический анализ полной строки ошибки, чтобы получить более подробную информацию об ошибке.

В моем случае код ошибки <110 > отсутствует, и когда пользователь отменяет запись в код ошибки 16. Обработать ошибку.