我正在创建这个将使用耗材应用内购买的新应用。
我的问题是:这是如何运作的?我的意思是,想象用户购买消费品。因此,在完成销售后,我在应用程序的数据库上设置了一个标志,授权使用该对象。我读到某个地方,我必须为用户提供一个按钮来恢复旧的交易,以防用户出于某种原因失去他的设备并且必须恢复所有内容。
想象一下,用户已经使用了该购买,之后他恢复了旧的应用内购买。那么会发生什么?用户是否会再次使用相同的资源,这样他可以第二次使用而无需付费?它是如何工作的,我应该如何处理?
感谢
答案 0 :(得分:67)
我想分享一个有点非正统的解决方案,我发现这个问题具有不需要服务器的巨大优势。此方法允许用户在删除并重新安装应用程序时恢复其消耗品,但不允许他们将项目移动到新设备(除非他们的所有应用程序数据都被复制)。
删除并重新安装应用时,存储在钥匙串中的数据仍然存在。钥匙串用于存储用户名和密码,但您也可以在那里存储有关消耗品购买的信息。我使用了KeychainItemWrapper类,可以在这里找到:https://developer.apple.com/library/content/samplecode/GenericKeychain/Introduction/Intro.html
以下是一些示例代码,用于存储和检索用户剩余的付费提示数量:
//Storing the consumable hint item count
int hintsLeft = 100;
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Hints" accessGroup:nil];
NSString *hintsString = [NSString stringWithFormat:@"%i",hintsLeft];
[wrapper setObject:hintsString forKey:(id)kSecValueData];
[wrapper release];
//Retrieving it
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Hints" accessGroup:nil];
NSString *numHints = [wrapper objectForKey:(id)kSecValueData];
[wrapper release];
int retrievedHints = [numHints intValue];
注意:
键(id)kSecValueData不能是任意字符串,有一组可用作键的常量列表。
您需要添加安全框架
答案 1 :(得分:28)
StoreKit仅为非消耗品提供恢复功能(在某种程度上为订阅提供)。因此,对于消耗品,使用restoreCompletedTransactions
进行恢复将不会在您的情况下进行任何交易。任何有关消耗品的恢复信息的处理都必须在您的应用程序和/或服务器中完成。
有关各种产品性质的参考,请查看In App Purchase Programming Guide:Designing Your App’s Products。每次都必须购买消费品产品,非消费品产品只购买一次并提供给与该用户的iTunes帐户相关的所有设备自动续订订阅和不续订订阅
答案 2 :(得分:5)
对于那些在iOS中搜索本地存储耗材的方式的人,请查看PDKeychainBindingsController(https://github.com/carlbrown/PDKeychainBindingsController)。
它与NSUserDefaults类似,可用于在iDevice的钥匙串中存储购买的耗材项目(存储在钥匙串中的项目在删除应用程序时不会被删除)。
使用类似下面的代码来存储和检索钥匙串中的值:
- (NSUInteger)hintCount {
PDKeychainBindings *wrapper=[PDKeychainBindings sharedKeychainBindings];
NSString *valueString = [wrapper objectForKey:@"hintCount"];
int value = [valueString intValue];
return value;
}
- (void)setHintCount:(NSUInteger)starCount {
PDKeychainBindings *wrapper=[PDKeychainBindings sharedKeychainBindings];
NSString *valueString = [NSString stringWithFormat:@"%i",starCount];
[wrapper setObject:valueString forKey:@"hintCount"];
}