Monday, March 11, 2013

Data persistence in iOS Development

Ways to persist data
*NSUserDefaults -- save user data in property list. Non-sensitive info, e.g. user settings
*SQLite 3 -- embedded data in iOS
*Core Data -- object oriented for SQLite3
*Keychain access -- for sensitive information

----------------------------
NSUserDefaults

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Read from NSUserDefaults object
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    _myTextField.text = [defaults objectForKey:@"TextFieldText"];
    
    NSNumber *switchNumValue = [defaults objectForKey:@"SwitchValue"];
    _mySwitch.on = [switchNumValue boolValue];
    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)saveButtonPressed:(id)sender {
    
    // Get a reference to NSUserDefaults object
    // alloc init doesn't work because NSUserDefaults is a singleton
    // every single app only has 1 instance of NSUserDefaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    [defaults setObject:_myTextField.text forKey:@"TextFieldText"];
    [defaults setObject:[NSNumber numberWithBool:_mySwitch.on] forKey:@"SwitchValue"];
    // need to cast the switch value to number because NSUserDefaults only accept string or int
    
    [defaults synchronize]; // this is to write changes to disk
}
@end


---------------------------------
Keychain access

References:
http://software-security.sans.org/blog/2011/01/05/using-keychain-to-store-passwords-ios-iphone-ipad/
http://developer.apple.com/library/ios/#documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html%23//apple_ref/doc/uid/TP30000897-CH204-TP9 

"KeyChainItemWrapper" package downloadable from Apple
http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_h.html

After the login button is pressed

KeychainItemWrapper *keychainItem = [AppDelegate keychainItem];
[keychainItem setObject:username forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:password forKey:(__bridge id)(kSecValueData)];

AppDelegate.h
// declare static method for KeyChainItemWrapper class
+ (KeychainItemWrapper *)keychainItem;


AppDelegate.m
// Instantiate KeyChainItemWrapper class as a singleton through AppDelegate
static KeychainItemWrapper *_keychainItem;

@implementation AppDelegate

+ (KeychainItemWrapper *)keychainItem{
    return _keychainItem;
}



No comments:

Post a Comment