一.基础知识:
CoreData是对SQLite的封装,使用的时候比较方便,减少对SQL语句的使用。
CoreData中的核心对象
NSManagedObjectModel:代表Core Data 的模型文件,包含模型的数据结构;
NSManagedObjectContext:负责应用和数据库之间的交互(CRUD);
NSPersistentStoreCoordinator:添加持久的数据存储仓库,通常采用NSManagedObjectModel的对象来初始化,最经常用的是NSSQLiteStoreType;
NSEntityDescription:用来描述实体对象的;
Entity:定义一个实体;
Attribute:实体的一个属性;
Relationship:关联实体;
NSFetchRequest:用来设置一个查询的请求,可以指定查询顺序;
Predicate:设置查询的条件;
Sort Descriptor:设置排序。
二.具体步骤:
1.打开Xcode,按住shift+command+N新建一个工程,勾选 Use Core Data:
2.在Appdelegate.h和.m文件中 会自动生成以下文件:
#import <UIKit/UIKit.h> #import <CoreData/CoreData.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (void)saveContext; - (NSURL *)applicationDocumentsDirectory; @end
Appdelegate.m文件
#pragma mark - Core Data stack @synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory { // The directory the application uses to store the Core Data store file. This code uses a directory named "com.zhangyu.CoreDataTwo" in the application's documents directory. return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } - (NSManagedObjectModel *)managedObjectModel { // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTwo" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } // Create the coordinator and store _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataTwo.sqlite"]; NSLog(@"---url:%@",storeURL); NSError *error = nil; NSString *failureReason = @"There was an error creating or loading the application's saved data."; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { // Report any error we got. NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; dict[NSLocalizedFailureReasonErrorKey] = failureReason; dict[NSUnderlyingErrorKey] = error; error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; // Replace this with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; } - (NSManagedObjectContext *)managedObjectContext { // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { return nil; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; return _managedObjectContext; } #pragma mark - Core Data Saving support - (void)saveContext { NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { NSError *error = nil; if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } }
在工程文件中还会看到红色选框中的文件:然后单击打开创建一个model,我在这里创建一个Users,并添加相应的属性user_name,user_password两个属性,声明为字符串类型。
之后选择Editor-》Create NSManagedObject SubClass创建 会在工程里直接生成Users.h和Users.m文件。
4.准备条件完成后在Storyboard中设置两个Label和两个TextField、一个segmentControl控件,并拖拉控件在ViewControloler.h中:
@interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UITextField *username; @property (weak, nonatomic) IBOutlet UITextField *password; - (IBAction)segmentControl:(UISegmentedControl *)sender;
之后在ViewController中编写相应的代码:
#import "ViewController.h" #import "AppDelegate.h" #import "Users.h" @interface ViewController () @property (nonatomic,strong)AppDelegate *myDelegate; @property(nonatomic,strong) NSMutableArray *users; @property(nonatomic,assign)BOOL query; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.myDelegate = [UIApplication sharedApplication].delegate; self.query = NO; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)segmentControl:(UISegmentedControl *)sender { switch (sender.selectedSegmentIndex) { case 0: [self queryFromDB]; break; case 1:[self addToDB]; break; default: break; } } -(void)addToDB{ //@prames entityForName参数要与所建的Entity保持一致,如建的实体是Users Users *us = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:self.myDelegate.managedObjectContext]; us.user_name = self.username.text;//或者这种写法[us setValue:@"user_name" forKey:self.username.text]; us.user_password = self.password.text; NSError *error; //托管对象准备好后,调用托管对象上下文的save方法将数据写入数据库 BOOL isSaveSuccess = [self.myDelegate.managedObjectContext save:&error]; if (!isSaveSuccess) { [NSException raise:@"访问数据库错误" format:@"%@",[error localizedDescription]]; NSLog(@"Error: %@,%@",error,[error userInfo]); }else{ NSLog(@"Save successful!"); } } #pragma mark - 从数据库中查询数据 -(void)queryFromDB{ //创建取回数据请求 NSFetchRequest *request = [[NSFetchRequest alloc]init]; //设置要查询哪种实体的实体对象 //@prames entityForName参数要与所建的Entity保持一致 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users" inManagedObjectContext:self.myDelegate.managedObjectContext]; //设置请求实体 [request setEntity:entity]; //指定按照什么的排序方式,无排序 NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"user_name" ascending:NO]; NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sort, nil]; [request setSortDescriptors:sortDescriptions]; NSError *error; //执行获取数据请求,返回数组 NSMutableArray *mutableFetch = [[self.myDelegate.managedObjectContext executeFetchRequest:request error:&error]mutableCopy]; if (mutableFetch == nil) { NSLog(@"Error: %@,%@",error,[error userInfo]); } self.users = mutableFetch; NSLog(@"the count of users:%lu",(unsigned long)self.users.count); for (Users *user in self.users) { if ([self.username.text isEqualToString:user.user_name]) { if ([self.password.text isEqualToString:user.user_password]) { self.query = YES; break; } } NSLog(@"--name:%@---password:%@--",user.user_name,user.user_password); } if (!self.query) { [self showAlert:@"用户名或密码错误,请重新输入"]; } } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self.username resignFirstResponder]; [self.password resignFirstResponder]; } -(void)showAlert:(NSString*)infomation{ UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示:" message:infomation delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; } @end
效果如图所示:
点击Add按钮会输出:Save successful 点击query会输出如下图所示:
之所以有五条数据是因为之前添加了四条数据,已经保存在CoreDataTwo.sqlite数据库中