存储本地玩家高分的最佳方法是什么

时间:2014-07-20 13:56:30

标签: ios objective-c cocoa-touch

我想在iOS游戏中存储本地玩家的高分。接近它的最佳方法是什么?在这种情况下我应该使用NSUserDefaults吗?保存高分是否足够安全?

提前致谢。

7 个答案:

答案 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非常简单:

Click here to Know more

答案 6 :(得分:0)

我经常选择类似这些情况的coredata。有很多方便的&amp;关于此的安全框架。现在我使用MagicalRecord框架。它是有用且常用的框架。

您只需创建模型并为AppDelegate.m文件重新设置魔法记录框架。您可以随时随地保存数据。