SKReceiptRefreshRequest对象具有两个方法的委托:
- (void)requestDidFinish:(SKRequest *)request; - (void)request:(SKRequest *)request didFailWithError:(NSError *)error;
在我的代码中,如果用户执行或不按取消,则会调用requestDidFinish委托方法.
这对我来说很重要的原因是,如果用户按取消,我想取消恢复过程.如果刷新请求之后根本没有收据,这可能比较容易.但是,有时在SKReceiptRefreshRequest之前,应用程序中有收据(有些购买)),如果用户从登录对话框中取消,则会保留在应用程序中.
我有两个想法如何做到这一点:
1)在刷新请求之前删除捆绑包中的收据.明显的问题是应用程序无法从捆绑包中删除文件(例如,见Delete file from bundle after install).我试过了.不.
2)在刷新请求之前检查收据的字节;如果它们不同,则应该指示用户没有按取消.如果他们没有区别,我不确定是否表示他们按取消.如果收据包含购买,我认为字节将不同,因为刷新的收据应该具有不同的事务ID(但是相同的“原始”事务ID).如果收据不包含任何购买,我不确定.
更新,11/9/15;我刚刚注意到,按取消的用户的委托回复似乎已经改变了.现在,didFailWithError被调用.然而,检测用户取消的问题仍然存在.我们如何区分用户按取消和真正的错误?我已经在iOS8.4和iOS9.2(测试版)上进行了测试.我现在已经报告说这种缺乏可区分性是苹果的错误(bug#23476210).
更新,11/10/15; iOS 9.0.2不会出现此问题!我刚刚尝试使用所有三个系统,具有相同的应用程序二进制,在相同的大致间隔时间(所有三个系统的20分钟内):(A)iOS9.2(13C5050d):问题确实发生(didFailWithError被调用并且不能区分真实的错误和用户按取消),(B)iOS9.0.2,不发生问题(requestDidFinish被调用),和(C)iOS8.4.1,问题确实发生.使用所有三个系统版本,这是在真正的硬件上运行,而不是模拟器.
解决方法
我明白你2年前问过这个问题,但是最近我遇到这个问题,找到了一个解决方案,想在这里分享一下,以便别人节省一些时间.
1)您可以选择将收据存入钥匙串并访问其副本,这样您可以将其删除或刷新,因为您认为合适.
2)是的,你可以肯定检查它是否改变,我认为最简单的方法是使用:
[receipt isEqualToData:(NSData *)(copyReceiptObject)]
我的建议如下:
– (void)请求:(SKRequest *)请求didFailWithError:(NSError *)错误;
当登录对话框中的用户点击取消后,即可登录iTunes Store.有很多习惯是你可以做刷新请求,所以结果可能会有所不同,但是这是你的请求的不同错误:
当iTunes没有连接时:
Error Domain=SSErrorDomain Code=110 “Cannot connect to iTunes Store”
UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store,
NSUnderlyingError=0x13c76d680 {Error Domain=NSURLErrorDomain
Code=-1009 “Cannot connect to iTunes Store”
UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store,
NSErrorFailingURLStringKey={ your product ids and corresponding URIs here }
,_kcfStreamErrorCodeKey=8,_kcfStreamErrorDomainKey=12,
NSLocalizedDescription=The Internet connection appears to be offline.}}}
当用户点击取消时:
Error Domain=SSErrorDomain Code=16 “Cannot connect to iTunes Store”
UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store,
NSUnderlyingError=0x13c6ac7b0 {Error Domain=AKAuthenticationError
Code=-7003 “(null)”}}
最简单的我想是检查error.code,如果你想变得更复杂,你可以选择解析完整的错误字符串,以获得更多关于错误的详细信息.