我想在iOS游戏中存储本地玩家的高分。接近它的最佳方法是什么?在这种情况下我应该使用NSUserDefaults
吗?保存高分是否足够安全?
提前致谢。
答案 0 :(得分:4)
NSUserDefaults不是存储此类信息的正确位置。最好的方法是隐藏Keychain中的用户分数,以便没有人可以破解它(可能游戏分数与您的货币化想法相关)。
其他好处是Keychain可通过iCloud无缝同步,"它只是工作"。
存储玩家高分的最佳方法是在项目中使用以下代码。 以下方法将帮助您在Keychain中保存一些值:
- (void) setValue: (NSData *) value forAccount: (NSString *) account service: (NSString *) service {
NSDictionary *searchDict = @{
(__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
(__bridge id) kSecMatchLimit: (__bridge id) kSecMatchLimitOne,
(__bridge id) kSecAttrService: service,
(__bridge id) kSecAttrAccount: account,
(__bridge id) kSecReturnData: @YES,
};
CFDataRef keyData = NULL;
SecItemCopyMatching ((__bridge CFDictionaryRef) searchDict, (CFTypeRef *) &keyData);
if (keyData) {
CFRelease (keyData);
NSDictionary *removeDict = @{
(__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
(__bridge id) kSecAttrService: service,
(__bridge id) kSecAttrAccount: account,
};
SecItemDelete ((__bridge CFDictionaryRef) removeDict);
}
if (value) {
NSDictionary *writeDict = @{
(__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
(__bridge id) kSecAttrService: service,
(__bridge id) kSecAttrAccount: account,
(__bridge id) kSecValueData: value,
};
SecItemAdd ((__bridge CFDictionaryRef) writeDict, NULL);
}
}
value
是您的用户得分存档到NSData 将整数打包到NSData:
NSUInteger score = <some number>;
NSData *dataValue = [NSData dataWithBytes:&score length:sizeof(score)];
解压缩:
NSUInteger score;
[dataValue getBytes:&score length:sizeof(score)];
account
- 是您的值的名称,例如@&#34; userScore&#34;,或某个用户的得分@&#34; ForzenHeart_Score&#34; service
- 是您的应用程序的名称,您可以使用您的包ID [[NSBundle mainBundle] bundleIdentifier]
要从Keychain获取保存的数据,请使用以下方法:
- (NSData *) valueForAccount: (NSString *) account service: (NSString *) service {
NSDictionary *searchDict = @{
(__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
(__bridge id) kSecMatchLimit: (__bridge id) kSecMatchLimitOne,
(__bridge id) kSecAttrService: service,
(__bridge id) kSecAttrAccount: account,
(__bridge id) kSecReturnData: @YES,
};
CFDataRef keyData = NULL;
SecItemCopyMatching ((__bridge CFDictionaryRef) searchDict, (CFTypeRef *) &keyData);
return (__bridge_transfer NSData *) keyData;
}
并且不要忘记在必要时忘记所有与用户相关的数据,只需将nil
作为上面列出的value
方法的-(void)setValue...
参数传递。
答案 1 :(得分:1)
NSUserDefaults
不安全,因为默认值实际上是键入应用程序文件夹中设备本地存储的.plist文件。这是目录:.../YourApp.app/Library/Preferences/appBundleName.plist
。这可以非常容易地通过设备内外的工具进行修改和查看,并且在设备外查看时不需要越狱。正如其他人所建议的那样,使用iOS Keychain可以增加安全性。此外,这里还有一个用于iOS安全默认设置的开源库:Secure-NSUserDefaults。
要直接回答您的问题,对于您不希望用户间接修改的任何敏感数据,不够安全。只需很少的努力即可轻松访问和修改NSUserDefaults
。不要将加密数据存储在NSUserDefaults
中,因为它也可以轻松访问。攻击者不会轻易解密数据,但他们仍然可以轻松访问它。 iOS Keychain也不是很安全,因为内容也可以轻松转储但不能解密。尽管如此,iOS Keychain还不错。
答案 2 :(得分:0)
NSUSerDefaults
。
使用iOS Keychain或将数据上传到您的服务器(最可靠的方式)
答案 3 :(得分:0)
没有NSUserDefaults
不安全。您可以使用Keychain
。
NSUserDefaults
的内容以纯文本格式存储。可以使用iExplorer
之类的工具访问和修改它们,而不用越狱。
如果不是问题,您可以选择NSUserDefaults
答案 4 :(得分:0)
通常,NSUserDefaults
应仅包含可由用户更改的设置。您的应用的内部数据不应存储在NSUserDefaults
中。
使用iOS Keychain
存储真正安全的数据。
或者,您可以使用加密算法(例如AES)加密存储在NSUserDefaults
中的数据,或将其保存在字典中并将其写入文件。
答案 5 :(得分:0)
请勿使用NSUserDefaults
在本地保存任何内容。这不安全。您应该将分数存储在keychain
加密的位置,这个小包装类可以将用户名/密码保存到keychain
非常简单:
答案 6 :(得分:0)
我经常选择类似这些情况的coredata。有很多方便的&amp;关于此的安全框架。现在我使用MagicalRecord框架。它是有用且常用的框架。
您只需创建模型并为AppDelegate.m文件重新设置魔法记录框架。您可以随时随地保存数据。