ios - 存储本地玩家高分的最佳方式是什么

标签 ios objective-c cocoa-touch

我想在 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/

相关文章:

ios - 核心剧情: Make x-axis ticks evenly spaced

android - 无需身份验证即可获取 Twitter 主页时间线(仅应用程序身份验证)

ios - iPad 显示从弹出窗口中选择的图片

ios - Kiwi iOS 上下文 block 的奇怪排序

ios - 如何加载 View "properly"iOS

objective-c - AQGridViewCell透明背景

objective-c - 在 UIView 之间拖动 UIView

ios - SpriteKit : How to blur the movement of a node like a shooting star

Iphone - 用歌词写一个媒体播放器

objective-c - 将 CGRect 存储到 plist 时出现问题