2013-11-21 18 views
12

Khi chúng tôi cần làm mới biên nhận iOS7, cách thích hợp để làm điều đó là sử dụng SKReceiptRefreshRequest. Thao tác này sẽ trả về hộp thoại Apple để người dùng đăng nhập bằng Apple ID của họ. Nó cũng cho phép họ Hủy. Làm cách nào chúng tôi có thể phát hiện xem người dùng có nhấn Hủy không? (Tất nhiên, trong iOS6, điều này có thể được thực hiện bằng cách sử dụng catching the cancel event for [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]).Phát hiện người dùng hủy SKReceiptRefreshRequest để đăng nhập

Đối tượng SKReceiptRefreshRequest có một đại biểu với hai phương pháp:

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

Trong mã của tôi requestDidFinish phương pháp đại biểu được gọi là nếu người dùng không hoặc không nhấn hủy.

Lý do quan trọng đối với tôi là tôi muốn hủy quá trình khôi phục nếu người dùng nhấn Hủy. Nếu chỉ đơn giản là không có hóa đơn sau khi yêu cầu làm mới, điều này có thể tương đối dễ dàng. Tuy nhiên, đôi khi có một biên nhận (với một số giao dịch mua) có trong ứng dụng trước SKReceiptRefreshRequest và do đó nó vẫn nằm trong ứng dụng nếu người dùng hủy khỏi hộp thoại đăng nhập.

Tôi có hai ý tưởng về cách thực hiện việc này:

1) Xóa biên lai khỏi gói trước yêu cầu làm mới. Vấn đề rõ ràng với điều này là ứng dụng không thể xóa tệp khỏi gói (ví dụ: xem Delete file from bundle after install). Tôi đã thử. Không.

2) Kiểm tra byte của biên nhận trước yêu cầu làm mới và sau đó; nếu chúng khác nhau, thì điều này sẽ cho biết người dùng không nhấn Hủy. Nếu chúng không khác nhau, tôi không chắc chắn rằng cho biết chúng đã nhấn Hủy. Nếu biên nhận chứa các giao dịch mua, tôi nghĩ rằng các byte sẽ khác nhau bởi vì biên lai được làm mới phải có các id giao dịch khác nhau (nhưng cùng một id giao dịch "gốc"). Nếu biên nhận không có giao dịch mua, tôi không chắc chắn về điều đó.

Cập nhật, 11/9/15; Tôi vừa nhận thấy rằng phản hồi của đại biểu cho người dùng nhấn Cancel dường như đã thay đổi. Bây giờ, didFailWithError được gọi. Tuy nhiên, vấn đề phát hiện hủy người dùng vẫn còn. Làm thế nào chúng ta có thể phân biệt giữa người dùng nhấn Cancel và một lỗi chính hãng? Tôi đã thử nghiệm trên iOS8.4 và iOS9.2 (beta). Bây giờ tôi đã báo cáo sự thiếu phân biệt này là một lỗi đối với Apple (bug # 23476210).

Cập nhật, 11/10/15; Vấn đề này không không xuất hiện với iOS 9.0.2! Tôi đã thử điều này ngay bây giờ với cả ba hệ thống, với cùng một ứng dụng nhị phân, trong cùng khoảng thời gian (trong vòng 20 phút cho cả ba hệ thống): (A) iOS9.2 (13C5050d): Sự cố xảy ra (didFailWithError được gọi là và không thể phân biệt giữa một lỗi thực sự và người dùng nhấn hủy), (B) iOS9.0.2, sự cố không xảy ra (requestDidFinish được gọi) và (C) iOS8.4.1, sự cố không xảy ra. Với tất cả ba phiên bản hệ thống, điều này đang chạy trên phần cứng thực, không phải là trình mô phỏng.

+0

Tôi vừa thử nghiệm số 2) ở trên. Và nếu có biên lai không trống trước khi làm mới, không có giao dịch mua, nó sẽ là một biên nhận không có ** khác ** sau khi làm mới. Hoặc ít nhất là trong hai lần tôi làm như vậy. Tất nhiên, một giải pháp trực tiếp hơn cho điều này sẽ là tốt. Ví dụ: phương pháp xóa được gọi để cho biết người dùng đã nhấn Hủy. Bytewise, 5515 byte và 5522 byte khác nhau giữa các biên nhận trong các bài kiểm tra tôi đã thực hiện. –

Trả lời

1

iOS 9.2.1, Xcode 7.2.1, ARC kích hoạt

Tôi hiểu bạn hỏi này 2 năm trước, nhưng tôi gần đây đã chạy của tôi với vấn đề này và tìm ra giải pháp, và muốn chia sẻ ở đây để những người khác có thể tiết kiệm thời gian.

1) Bạn có thể chọn lưu trữ biên nhận thành chuỗi và truy cập bản sao của nó, điều này cho phép bạn xóa hoặc làm mới nó khi bạn thấy phù hợp.

2) Yeah bạn chắc chắn có thể kiểm tra xem nó đã thay đổi, tôi nghĩ rằng cách đơn giản nhất để làm điều đó là sử dụng:

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

Đề nghị của tôi là như sau:

Mấu chốt là để mong đợi số error bạn nhận được từ phương thức:

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

được gọi khi người dùng nhấn hủy sau khi hộp thoại đăng nhập xuất hiện để đăng nhập vào iTunes Store. Có rất nhiều tùy chỉnh là bạn có thể làm theo yêu cầu làm mới, vì vậy kết quả có thể khác nhau, nhưng đây là lỗi khác nhau mà bạn nhận được cho yêu cầu của tôi:

Khi không có kết nối vào iTunes:

Lỗi domain = SSErrorDomain Mã = 110 "không thể kết nối với iTunes Store" UserInfo = {NSLocalizedDescription = không thể kết nối với iTunes Store, NSUnderlyingError = 0x13c76d680 {Lỗi domain = NSURLErrorDomain Mã = -1009 "không thể kết nối với iTunes Store " UserInfo = {NSLocalizedDescription = Không thể kết nối với iTunes Store, NSErrorFailingURLStringKey =

{id sản phẩm của bạn và URI tương ứng here}

, _kCFStreamErrorCodeKey = 8, _kCFStreamErrorDomainKey = 12, NSLocalizedDescription = Kết nối Internet xuất hiện . được ẩn}}}

Khi các vòi sử dụng hủy:

Lỗi miền = SSErrorDomain Mã = 16 "Không thể kết nối với iTunes Store" UserInfo = {NSLocalizedDescription = Không thể kết nối với iTunes Store, NSUnderlyingError = 0x13c6ac7b0 {Lỗi miền = AKAuthenticationError Mã = -7003 "(null) "}}

Cách dễ nhất tôi nghĩ là kiểm tra error.code, nếu bạn muốn phức tạp hơn, bạn có thể chọn phân tích chuỗi lỗi đầy đủ để biết thêm chi tiết về lỗi.

Trong trường hợp của tôi, không có kết nối mã lỗi là 110 và khi người dùng hủy đăng nhập trong mã lỗi là 16. Xử lý lỗi.

+0

Tôi muốn biết thêm về các lỗi này và hỏi một câu hỏi tiếp theo tại đây http://stackoverflow.com/q/35851069/4018041 về SSErrorDomain. –

+0

Tôi không biết làm thế nào đáng tin cậy là sử dụng các mã lỗi như thế này nhưng vào tháng 1 năm 2017 mã lỗi 16 vẫn đang được trả lại khi hủy được nhấn. – Richard

+0

Không đáng tin cậy chút nào, nhưng tôi không biết cách nào khác để phát hiện điều này và đây là điều kiện mong muốn để phát hiện để làm cho trải nghiệm người dùng tốt hơn. Cảm ơn bạn đã xác minh rằng nó vẫn hoạt động. –

Các vấn đề liên quan