Nic*_*ari 19 itunes in-app-purchase ios
正如本问题和其他任何地方所讨论的,Apple现在要求应用程序为用户提供一种方法来恢复In App Purchase的已完成交易.
我全力以赴.我的应用程序的第一个版本以某种方式让它在没有它的情况下进行了审核(当时我还没有意识到这个规则,和/或它还没有被强制执行),但后来我开始接收来自用户的大量电子邮件询问缺少的内容(也有数据存储指南,并且不会备份繁重的可下载内容).
所以,假设我在我的UI中的某处包含了一个"恢复"按钮,当点击调用时:
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.用户被提示他的AppleID和/或密码,并且恢复过程开始.
我遇到的问题是:如果没有要恢复的事务,在AppleID提示之后我的应用程序基本上没有任何反应,这可能会让用户感到困惑或使应用程序看起来没有响应或损坏.
我希望能够显示"所有购买都是最新的"或类似的警报视图.
我可以在我的Transaction Observer代码中做些什么来检测这种情况吗?
有没有人认为这将是一个糟糕的设计,UX明智?
您还可以实现以下委托函数:
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
Run Code Online (Sandbox Code Playgroud)
然后,您将知道还原过程何时完成或失败.您可以在paymentQueueRestoreCompletedTransactionsFinished中混合使用queue.transactions.count来查看是否已恢复任何事务.
请记住处理SKPaymentTransactionStateRestored
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
Run Code Online (Sandbox Code Playgroud)
您可能还希望以与使用SKPaymentTransactionStatePurchased事务相同的方式处理已恢复的事务.
我对恢复购买的正确/最佳措辞感兴趣.
我已经看到了足够的"未知错误"警报,只是[error localizedDescription]在内部使用-(void)paymentQueue:restoreCompletedTransactionsFailedWithError:.(todo:填充雷达)
所以我看看Apple如何做到这一点.Apple现在购买非消费类应用程序的唯一应用程序是GarageBand(2014年12月).
而不是"恢复购买","恢复以前的购买"或......他们一起去"Already Purchased?".
但是这里是我更感兴趣的屏幕,"Already Purchased?"当没有什么可以恢复时按下的结果 :

"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];
}
Run Code Online (Sandbox Code Playgroud)
OS X:
我对OS X上的相同文本不满意.只有messageText和没有informativeText的NSAlert看起来空洞和错误.
对我来说,一个选择是让用户知道他需要购买它,例如"To use it, you need to buy “%@”.".
我想出的另一个选择是让他们浏览购买历史记录.我发现你可以直接链接到它itms://phobos.apple.com/purchaseHistory.老实说,iTunes Store中的购买历史是一件糟糕的事情,它会让你永远找到一些东西.
但也许它有助于再保险人员,我们不会试图让他们重新购买一些东西.始终假设您的客户不知道或不能区分非消耗品和消耗品.并且不知道他们不能为非消耗品收取两次费用.
- (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];
}
}
Run Code Online (Sandbox Code Playgroud)
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}
Run Code Online (Sandbox Code Playgroud)
什么都没有恢复时:
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
Error Domain=SKErrorDomain Code=0 "Unknown Error." UserInfo=0x60800007fb80 {NSLocalizedDescription=Unknown Error.}
Run Code Online (Sandbox Code Playgroud)
这仍然是最新的SDK/xCode 8.0,Swift 3中的一个问题 - 如果未进行任何购买的用户尝试"恢复",则使用以下方法:
SKPaymentQueue.default().restoreCompletedTransactions()
Run Code Online (Sandbox Code Playgroud)
不会触发处理购买/恢复的常用委托方法:
paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {...}
Run Code Online (Sandbox Code Playgroud)
有趣的是,也可能没有调用可能应该捕获错误的方法:
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error){...}
Run Code Online (Sandbox Code Playgroud)
相反,触发了可选方法,就好像恢复工作正常:
func paymentQueueRestoreCompletedTransactionsFinished()
Run Code Online (Sandbox Code Playgroud)
这可能会导致应用看起来像挂起/没做任何事情.
正如其他答案中所讨论的,原因是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)
}
}
Run Code Online (Sandbox Code Playgroud)
重要的是,如果用户先前已购买,则事务队列将不为空,因此将调用updateTransaction委托方法,并将正常处理还原请求.
| 归档时间: |
|
| 查看次数: |
5248 次 |
| 最近记录: |