My recommendation is to use Keychain for any data that you'd like to protect from being edited by user. That might look complicated at first, but it's not that complicated: Keychain can store arbitrary NSData
, so you can write a function that will take your NSPropertyList
, serialise it, and store into Keychain.
Function to store arbitrary NSData
into keychain will look like this:
+(BOOL)setKeychainData:(NSData*)value forAccount:(NSString*)account {
if (account == nil || value == nil) {
return false;
}
NSDictionary* query = @{
(__bridge id) kSecClass : (__bridge id) kSecClassGenericPassword,
(__bridge id) kSecAttrAccessible : (__bridge id) kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, // <- read about this in docs and pick the right one
(__bridge id) kSecAttrService : @"MyServiceName",
(__bridge id) kSecAttrAccount : account,
(__bridge id) kSecValueData : value,
};
OSStatus err = SecItemAdd((__bridge CFDictionaryRef) query, NULL);
if (err != errSecSuccess) {
NSLog(@"SecItemAdd(): %d", (int) err);
}
return (err == errSecSuccess);
}
Alternative way of ensuring integrity of your data would be to continue to store it in property list files and compute digest of those files (e.g. SHA-1 or SHA-256) and store those digests in the Keychain. Your app will have to recompute digest every time it writes the file and it will have to verify the digest when loading data from the property list.