Key Words: Data Persistence, Property List, plist, Archiving, SQLite3
- Data Persistence Ways
- Property List
- Object Archive
- SQLite3 (Database)
- Other Ways
- Traditional way: fopen, fread, fwrite
- Cocoa's low-level file management tools
- ...
- Directories for Data Persistence
- Every application (Except some Apple applications, such as Settings) are restricted to store its own folder under application installation path.
- Directories for Application
- /Documents
Store application data (with exception of NSUserDefaults-based preference settings which is stored in /User/Library/Preferences)
- /tmp
Store temporary files. Files under this folder will not be backed up by iTunes when your iPhone syncs, but your application need to take responsibility for deleting the files in this folder once they are no longer needed, to avoid filling up the file system. - ...
- Get Directories
- Get Path of /Documents With NSSearchPathForDirectoriesInDomains
ie,
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirecotory, NSUserDomainMask, YES];
NSString *documentsDir = [paths objectAtIndex:0]; // We used index 0 since we know the array paths only contains one element.
NSString *fileName = [documentsDir stringByAppendingPathComponent:@"theFile.txt"];
- Get Path of /tmp With NSTemporaryDirectory
NSString *tempDir = NSTEmporaryDirectory();
NSString *fileName = [tempDir
stringByAppendingPathComponent:@"theFile.txt"];
- ...
- ...
- Property List
- Property list file name end with extensions .plist
- Property list file can be edited with XCode, or Properties List Editor
- NSDictionary and NSArray can be used to hode persistence date in property list approch
- Only objects of following classed can be serialized into properties list file, user custom objects or other Cocoa Touch objects (such as NSURL, NSImage, NSColor) can't be used directly.
- NSDictionary
- NSMutableDictionary
- NSData
- NSMutableData
- NSNumber
- NSDate
- Details
About how to property list file into NSDictionary/NSArray, and how to store data holded in NSDictionary/NSArray into property list file, and how to parse data in property file list, please refer to offical document Property List Programming Guide.
- ...
- Archiving Model Objects
- Objective
Let you easily write complex objects to a file and then read them back in
- Objects That Can Be Archived
- Scalars: like int, float
- Instance of a class that conforms to NSCoding protocol (In such approach, it is recommended to implement another protocol NSCopying to allow your object can be copied)
- Define Data Model
- Implement NSCoding Methods (Required)
NSCoding defines 2 methods to encode and decode objects, you can encode and decode both objects and scalars using key-value coding.
Implement mehtod encodeWithCoder. To support archiving in your object, you have to encode each of your instalce variables into encoder using the appropriate encoding method.
Implement method initWithCoder, initialize an object instance using [super init] or [super initWithCoder:decoder] (decoder is argument of NSCoding:initWithCoder).
- Implement NSCopying Methods (Optional)
Implement copyWithZone
- Sample
//==================================================
//Declare Data Model class in MyDataModel.h
#define kFieldNameKey @"FieldName"
#define kFieldSalaryKey @"FieldSalary"
#define kFieldYearKey @"FieldYear"
#import
@nterface MyDataModel : NSObject
{
NSString *fieldName;
NSString *fieldSalary;
int fieldYear;
}
@property (nonatomic, retain NSString *fieldName;
@property (nonatomic, retain NSString *fieldSalary;
@end
//==================================================
//Define Data Model class in MyDataModel.m
@import "MyDataModel.h"
@implementation MyDataModel
@synthesize fieldName;
@synthesize fieldSalary;
#pragma mark NSCoding
- (void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:fieldName forKey:kFieldNameKey];
[encoder encodeObject:fieldSalary forKey:kFieldSalaryKey];
[encoder encodeObject:fieldYear forKey:kFieldYearKey];
}
- (id) initWithCoder:(NSCoder *) decoder
{
if (self = [super init]) // of if (self = [super initWithCoder:decoder)
{
fieldName = [decoder decodeOBjectForKey:kFieldNameKey];
fieldSalary = [decoder decodeOBjectForKey:kFieldSalaryKey];
fieldYear = [decoder decodeOBjectForKey:kFieldYearKey];
}
}
#pragma mark NSCopying
- (void) copyWithZone:(NSZone *) zone
{
MyDataModel *copy = [[[self class] allocWithZone:zone] init];
copy.fieldName = [self.fieldName copy];
copy.fieldName = [self.fieldName copy];
copy.fieldYear = self.fieldYear;
return copy;
}
- ...
- Archving and Unarchiving
@import "MyDataModel.h"
#define kFileName @"archive"
#define kDataKey @"Data"
//==============================
//Archiving
MyDataModel *myData = [[MyDataModel alloc] init];
myData.fieldName = @"Jimmy";
myData.fieldSallary = @"200000";
myData.fieldYear = 1980;
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver endoceObject:myData forKey:kDataKey];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
[myData release];
[archiver release];
[data release];
//==============================
//Unarchiving
NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
MyDataModel *myData = [unarchiver decodeObjectForKey:kDataKey];
String *name = myData.fieldName;
String *salary = myData.fieldSalary;
int year = myData.fieldYear;
[unarchiver finishDecoding];
[unarchiver release];
[data release];
[myData release];
- ...
- SQLite3
- SQLite3 is embedded SQL database, it uses Structured Query Language (SQL)
- Dependency
- Header
/usr/include/sqlite3.h
- Library
/usr/lib/libsqlite3.dylib
- Go to XCode, select Frameworks in Groups & Files pane
- Select Add to Project ... from the Project menu
- Navigate to /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.1.sdk/usr/lib, and find the file called libaqlite3.dylib
- When you are prompted, make sure
uncheck Copy items into destination groups's folder (if needed).
change Reference Type to Current SDK
- ...
- Basic
use sqlite2_xxx APIs,
- String
SQLite3 was written in portable C, not Objective-c, so it use C string, not NSString, you need to convert between C string and NSString
C String -> NSString
char *pszData = "This is C String";
NSString *strData = [[NSString alloc] initWithUTF8String:pszData];
NSString -> C String
NSString *strData = @"This is NSString";
char *pszData = [strData UTF8String];
- Datebase
Data Type:
sqlite3
APIs:
sqlite3_open //Open databases, or create a new one if it doesn't exist
sqlite3_close //Close datebase - Run Command That Doesn't Return Data
sqlite3_exec //Perform Create/Delete/AddColumn on Table, update, insert ...
- Retrive Data
Data Type:
sqlite_stmt
APIs:
sqlite3_prepare_v2
|
|----sqlite3_step
|----sqlite3_column_int
|----sqlite3_column_text
|----sqlite3_column_xxxx
|----sqlite3_column_finalize
- Advanced
- ...
- ...
Reference:- Beginning iPhone Development: Exploring the iPhone SDK
Chapter: Basic Data Persistence
Page: P329~359 - ...
阅读(1293) | 评论(0) | 转发(0) |