iOS下提供了几种能力用来保存数据:
- 保存简单数据类型:string、number、boolean、date和array等,这部分数据可以直接保存到property lists(也就是常见的.plist文件,类似于java的.properties文件)中;
- 应用程序的设置和偏好,以前的有些程序的设置都是集成到IOS的Setting中的,但现在更多的是自己提供一个Setting页面,设置自己的设置选项(例如stock程序);
- SQLite数据库,这是一个轻量级的数据库,Android中也有用到;
- Core Data,Core Data是一个功能强大的层,位于SQLite数据库之上,它避免了SQL的复杂性,能让我们以更自然的方式与数据库进行交互。Core Data将数据库行转换为OC对象(托管对象)来实现,这样无需任何SQL知识就能操作他们;
- iCloud Storage,Apple提供的云存储服务,可以在不同设备中共享数据;
下面我们需要考虑的是:我们需要把数据保存在哪里?这个问题是和我们具体的需求相关的:
- iOS不提供文件系统存储的读写能力,这样你就无法通过文件形式读写数据;
- 你的应用可以读写自己应用的配置信息和资源文件(但注意不是通过标准的file的形式),且仅仅只能读取和写入自己的数据;
- 例外是应用可以读取系统提供的一些数据,例如:媒体库、通讯录、日历等;
最后一个问题:你何时保存和何时加载数据?分成如下几种情况:
- 你的数据保存操作不需要人机交互操作:applicationDidEnterBackground里面的操作,例如游戏被切换到后台时自动保存,同时需要处理applicationWillEnterForeground;
- 其他情况;
下面是我们的第一个例子,演示保存数据,即使程序被关闭或者手机重启:
- 我们建立一个单视图项目,界面中添加一个textField、一个button、一个date picker;
- 对ViewController做改造,头文件改造如下:
// 控件关联字段
@property (strong, nonatomic) IBOutlet UITextField *myTextField;
@property (strong, nonatomic) IBOutlet UIDatePicker *myDatePicker;
// 控件关联事件(使得软键盘消失)
- (IBAction)dismissKeyboard:(id)sender;
// 自定义方法
-(NSString *) getFilePath;
-(void) saveData;
-(void) loadData;
- 实现文件改造如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// 加载View时加载数据
[self loadData];
}
// 使得textField关联的软键盘消失
- (IBAction)dismissKeyboard:(id)sender {
[myTextField resignFirstResponder];
}
// 得到配置文件名,这里的配置文件存放到Documents目录,可以被iTunes备份恢复。
-(NSString *) getFilePath {
// NSDocumentDirectory -- Documents目录,应用中用户数据可以放在这里,iTunes备份和恢复的时候会包括此目录
// NSCachesDirectory -- Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex: 0] stringByAppendingPathComponent:@"saved.plist"];
}
// 保存数据
-(void) saveData {
NSArray *value = [[NSArray alloc] initWithObjects: [myTextField text], [myDatePicker date], nil];
[value writeToFile:[self getFilePath] atomically:YES];
}
// 加载数据
-(void) loadData {
NSString *myPath = [self getFilePath];
BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath: myPath];
if (isFileExists) {
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
[myTextField setText:[values objectAtIndex:0]];
[myDatePicker setDate:[values objectAtIndex:1]];
}
}
- 最后AppDelegate一样做个改造,对于程序切换到后台和从后台恢复到前台响应:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.viewController saveData];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self.viewController loadData];
}
就可以实现基本的设置保存和在程序关闭甚至系统重启后再次进入程序直接加载已保存的数据的功能。