除了FMDB,Realm也是一种很流行的数据库方案。
1. 官方资料
- (最新版)Realm Objective‑C官方文档地址 https://realm.io/docs/objc/latest/
- (中文版)Realm Objective‑C官方文档地址(内容相对英文版不一定是最新的)https://realm.io/cn/docs/objc/latest/
- Realm官方API查阅手册 https://realm.io/docs/objc/latest/api/
- GitHub源码地址 https://github.com/realm/realm-cocoa
- 也可以直接点击压缩包下载
2. 用法示例
2.1 新建数据模型
Student.h
#import <Realm/Realm.h>
#import <UIKit/UIKit.h>
@interface Student : RLMObject
@property int age;
@property NSString *name;
@property (nonatomic,strong) NSData *showImgData;
@end
// This protocol enables typed collections. i.e.:
// RLMArray<Student>
RLM_ARRAY_TYPE(Student)
2.2 调用前初始化数据库
- (BOOL)initRealm {
self.isFisrtUser= YES;
[self setDefaultRealmForUser:[CommonUtils getStrValueInUDWithKey:@"account"]];
self.userNameLbl.text = @"user1";
config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]
URLByAppendingPathComponent:@"user1"]
URLByAppendingPathExtension:@"realm"];
NSLog(@"Realm file path: %@", config.fileURL);
NSError *error;
_realm = [RLMRealm realmWithConfiguration:config error:&error];
if (nil != error) {
NSLog(@"Create Realm Error");
return NO;
}
NSLog(@"create realm success");
return YES;
}
2.3 增数据
//增
- (IBAction)onAdd:(id)sender {
if (_nameTF.text.length ==0 || _ageTF.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty"
message:@"Name or Age is empty!"
delegate:self
cancelButtonTitle:@"Return"
otherButtonTitles:nil];
[alert show];
return ;
}
Student *s= [Student new];
s.name = _nameTF.text;
s.age = [_ageTF.text intValue];
s.showImgData = UIImagePNGRepresentation(self.showImgeView.image);
[_realm beginWriteTransaction];
[_realm addObject:s];
[_realm commitWriteTransaction];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sucess"
message:@"Add Sucess!"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
_allStudents = [Student allObjectsInRealm:_realm];
[_dataTV reloadData];
}
2.4 删数据
//删
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
Student *s = [_allStudents objectAtIndex:indexPath.row];
if (s == nil) {
NSLog(@"s is nil");
return;
}
[_realm beginWriteTransaction];
[_realm deleteObject:s];
[_realm commitWriteTransaction];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
2.5 改数据
- (IBAction)onModify:(id)sender {
if (_nameTF.text.length ==0 || _ageTF.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty"
message:@"Name or Age is empty!"
delegate:self
cancelButtonTitle:@"Return"
otherButtonTitles:nil];
[alert show];
return ;
}
[_realm beginWriteTransaction];
_student.name = _nameTF.text;
_student.age = _ageTF.text.intValue;
[_realm commitWriteTransaction];
UINavigationController *vc = (UINavigationController *)self.parentViewController;
[vc popViewControllerAnimated:YES];
}
2.6 查数据
//查
- (IBAction)onQuery:(id)sender {
if (_filterTF.text.length == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty"
message:@"Filter Age is empty!"
delegate:self
cancelButtonTitle:@"Return"
otherButtonTitles:nil];
[alert show];
return ;
}
NSString *filter = [NSString stringWithFormat:@"age > %d", [_filterTF.text intValue ]];
if (_realm) {
_allStudents = [Student objectsInRealm:_realm where:filter];
}
[_dataTV reloadData];
}
2.7 切换用户
很多App有这样一个需求:第一个账号保存第一个数据库,切换到第二个账号时,再新建第二个数据库,并且无法查看第一个用户的数据,当用户切换回第一个账号时,能继续使用第一个数据库。
- (void)setDefaultRealmForUser:(NSString *)username {
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
// 使用默认的目录,但是使用用户名来替换默认的文件名
config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]
URLByAppendingPathComponent:username]
URLByAppendingPathExtension:@"realm"];
// 将这个配置应用到默认的 Realm 数据库当中
[RLMRealmConfiguration setDefaultConfiguration:config];
}