iOS coredata的使用及版本升级

来源:互联网 发布:xboxone运行windows 编辑:程序博客网 时间:2024/05/07 13:23
//
//
//  AppDelegate.m
//  CoreData
//
//  Created by 王聪on 14/8/19.
//  Copyright (c) 2014年 Congwang. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
   
    //模型版本升级步骤:
    //1.新建模型版本 (选中可视化建模文件, 点击editor, 选择addModelVersion)
    //2.把当前新建的模型版本设置成选中状态 (先选中总的模型版本, 然后在属性检查器中的第一个标签有个current,选中新建的即可)
    //3.创建映射文件(cmd + n , 在coreData选项卡中, 选择mappingModel), 记住source是老的模型版本, target是新的模型版本
    //4.在数据连接器中的懒加载方法中, option选项由nil变成一个字典, key为NSMigrate, value为@{YES}, 该选项的意思是, 模型版本自动升级 (数据库升级)
   
   
 
    NSLog(@"%@",NSHomeDirectory());
    NSLog(@"%@", self.managedObjectContext);
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application terminates.
    [self saveContext];
}

#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.lanou.cong.CoreData" 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;
    }
    //找到可视化建模文件路径
    //xcdatamodeld在程序运行期间就转换成了momd类型 (了解就行)
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData" 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类型)
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    //参数: 1.指定真实存储文件的类型
    //2.一些配置信息, 一般我们用不到, 在这个参数中我们完成数据链接器的一些配置
    //3.指定数据链接器链接的存储文件的路径
    //4.选项设置: 比如我们可以在该选项中设置数据库升级
    //5.把捕捉到的错误信息放到error变量中
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSMigratePersistentStoresAutomaticallyOption:@YES} 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来进行调试
        abort();
    }
   
    return _persistentStoreCoordinator;
}

//数据管理器的懒加载 (重写getter方法)
- (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();
        }
    }
}

@end






//  ViewController.m
//  CoreData
//
//  Created by 王聪 on 14/8/19.
//  Copyright (c) 2014年 Congwang. All rights reserved.
//

#import "ViewController.h"
#import "Clothes.h"
#import "AppDelegate.h"

@interface ViewController ()<</span>UITableViewDelegate, UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) AppDelegate *myAppDelegate;
@property (strong, nonatomic) NSMutableArray *dataSource;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.myAppDelegate = [UIApplication sharedApplication].delegate;
    //初始化数组
    self.dataSource = [NSMutableArray array];    //进行数据查询 -- coreData查询
    //1.创建数据查询对象
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Clothes"];
    //2.创建排序描述对象(可选择, 想进行排序的时候在写)
    NSSortDescriptor *sortDescription = [[NSSortDescriptor alloc] initWithKey:@"price" ascending:YES];
    //2.1给request的排序属性赋值
    request.sortDescriptors = @[sortDescription];
//    //3.创建检索条件(可选择)
//    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@ and price > %@", @"Nike", [NSNumber numberWithFloat:1.0]];
//    request.predicate = predicate;
   
    NSError *error = nil;
   NSArray *resultArray = [self.myAppDelegate.managedObjectContext executeFetchRequest:request error:&error];
    //
    [self.dataSource addObjectsFromArray:resultArray];
   
   
}

#pragma mark - tableView的代理和dataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    Clothes *cloth = self.dataSource[indexPath.row];
    cell.textLabel.text = [NSString stringWithFormat:@"%@ -- %@", cloth.name, cloth.price];
    return cell;
   
}
//点击cell触发的代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    //修改数据
    Clothes *cloth = self.dataSource[indexPath.row];
    cloth.name = @"Nike";
    //将修改进行永久保存
    [self.myAppDelegate saveContext];
    //刷新单元格
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
   
}


//允许编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //1.先删除数据源
        Clothes *clothe = self.dataSource[indexPath.row];
        //在关于布局dataSource中, 删除数据
        [self.dataSource removeObject:clothe];
        //要在真实的文件中删除 (*coreData中的删除)
        [self.myAppDelegate.managedObjectContext deleteObject:clothe];
        //对数据管理器进行改变, 保存到真实的文件当中
        [self.myAppDelegate saveContext];
        //2.再删除单元格
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}







//添加数据
- (IBAction)addModel:(id)sender {
    // 1.先插数据源
    //coreData中持久化操作
   
   
    //快速插入方法 (推荐用)
    Clothes *clothNew = [NSEntityDescription insertNewObjectForEntityForName:@"Clothes" inManagedObjectContext:self.myAppDelegate.managedObjectContext];
    //给对象的属性赋值

    //实体描述
    NSEntityDescription *description = [NSEntityDescription entityForName:@"Clothes" inManagedObjectContext:self.myAppDelegate.managedObjectContext];
    //创建模型对象
    Clothes *clothe = [[Clothes alloc] initWithEntity:description insertIntoManagedObjectContext:self.myAppDelegate.managedObjectContext];
    clothe.name = @"Prada";
    float price = (arc4random() % 1000 +1) / 1.1;
    clothe.price = [NSNumber numberWithFloat:price];
    //添加到数据源中  插入数据源
    [self.dataSource addObject:clothe];
    // 2.插入单元格
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.dataSource.count - 1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    //对数据管理器中的数据进行永久保存 (保存在沙盒路径下的真是的文件中)
    [self.myAppDelegate saveContext];
}

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

@endiOS <wbr>coredata的使用及版本升级
0 0
原创粉丝点击