在应用程序钥匙链中存储应用程序购买收据
我从来没有实现过在应用程序购买之前,所以我使用了MKStoreKit包装,并有一个工作的实施。 MKStoreKit将UserDefaults .plist中的所有收据保留为BOOL,因此盗版者在“破解”状态下分发应用内购买非常简单。 一旦第一次购买,可以分发捆绑包,并且可以重新创build.plist来启用IAP解锁。
我想扩展MKStoreKit来在iOS钥匙串中创buildIn App Purchasevalidation数据。 是否有任何缺点或可能的原因,这是为了付费用户失败,是不可靠的,或者其他原因为什么这将是一个整体坏主意呢? 我知道盗版是不可避免的,我绝对不想疏远付费用户,但是我觉得UserDefaults .plist是一个很简单的方法。
在我的情况下,一个简单的string将被放入购物时进入钥匙串。 这样,如果二进制文件得到分发,那么unlockables还没有启用。 当然,可以想出一个解决方法,但是需要花费更多的精力,并且知道如何findTRUE / FALSE标志并使其始终返回正确的值。 通过模糊处理,我甚至可以稍微追查一下。
感谢您的所有见解,我很欣赏答案,避免了强制性的不可避免的盗版,与交易对应的答复。 我对这个解决scheme的技术可行性更感兴趣。
我们正是在我们的应用程序中完成的,而且效果非常好。它是一个免费的应用程序,您可以升级到完整版本,并将升级指示器存储在钥匙串中。 升级指标是您select的任意string,但对于密钥链而言,它被视为密码,即kSecValueData的值在密钥链中encryption。 这种方法的一个好处是,如果用户删除应用程序,然后重新安装它,一切都像魔术一样重新启用,因为钥匙串项目与应用程序分开存储。 而且在存储用户默认设置方面的额外工作非常less,我们认为这是值得的。
以下是如何创build安全项目:
NSMutableDictionary* dict = [NSMutableDictionary dictionary]; [dict setObject: (id) kSecClassGenericPassword forKey: (id) kSecClass]; [dict setObject: kYourUpgradeStateKey forKey: (id) kSecAttrService]; [dict setObject: kYourUpgradeStateValue forKey: (id) kSecValueData]; SecItemAdd ((CFDictionaryRef) dict, NULL);
以下是如何find安全项目来检查其值:
NSMutableDictionary* query = [NSMutableDictionary dictionary]; [query setObject: (id) kSecClassGenericPassword forKey: (id) kSecClass]; [query setObject: kYourUpgradeStateKey forKey: (id) kSecAttrService]; [query setObject: (id) kCFBooleanTrue forKey: (id) kSecReturnData]; NSData* upgradeItemData = nil; SecItemCopyMatching ( (CFDictionaryRef) query, (CFTypeRef*) &upgradeItemData ); if ( !upgradeItemData ) { // Disable feature } else { NSString* s = [[[NSString alloc] initWithData: upgradeItemData encoding: NSUTF8StringEncoding] autorelease]; if ( [s isEqualToString: kYourUpgradeStateValue] ) { // Enable feature } }
如果upgradeItemData为零,那么密钥不存在,因此您可以假设升级不在那里,或者我们所做的是放入一个值,意味着不升级。
更新
增加了kSecReturnData(谢谢@Luis指出)
GitHub上的代码(ARC变体)