我想在 iOS 游戏中存储本地玩家的高分。处理它的最佳方法是什么?在这种情况下我应该使用 NSUserDefaults
吗?存储高分是否足够安全?
提前致谢。
最佳答案
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
- 是您的值的名称,例如@"userScore",或某个用户的分数@"ForzenHeart_Score"service
- 是您的应用程序的名称,您可以使用您的 bundle 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
作为 -(void)setValue 的
上面列出的方法。value
参数传递即可。 ..
关于ios - 存储本地玩家高分的最佳方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24851196/