05-自己创建mapmodel自定义迁移方式
自动创建Mapping
如果模型的改变很大或者不支持轻量级数据迁移的条件,则我们需要进行自定义迁移。
使用映射模型 适用于更加复杂的数据的迁移
NSMappingModel
类似于数据模型
NSEntityMapping
告知迁移过程如何在目标数据存储中处理源实体的映射。
映射类型决定了如何处理目标数据存储中的特定实体。映射类型有添加 移除 复制 变换。
- 添加映射:一个目标中的新实体添加到目标数据存储中
- 移除映射:实体不存在目标映射中,只存在于源中。
- 复制映射:将源对象完全相同地复制到目标
- 变换映射: 实体存在于源和目标中并且映射应该以某种方式将源变换到目标。
NSPropertyMapping
告知迁移过程如何将源属性映射到目标属性。
在从源数据存储到目标数据存储移动数据是可以提供一个值表达式来转换值。
开始一个自定义的迁移方式
1 新建一个mapModel
- 确保Data Model 处于选中状态
- File > New > File> iOS > Core Data > Mapping Model , 并点击Next 按钮
- 将旧版本的设置为Source Data Model 并点击Next 按钮 ,将新建的设置为Target Data Model, 并点击Next 按钮
- 保存mappingModel
2 代码的实现
首先要判断本地数据库文件和当前使用数据模型的结构是否相同。
如果不相同的话进行迁移。
1 在打开本地数据库的时候就要进行判断
// 判断是否需要迁移 是否已经迁移过了
- (BOOL)isHaveMigration
{// 原来的数据库路径 不存在直接进行返回NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString *sqlPath = [docStr stringByAppendingPathComponent:@"student.sqlite"];NSURL *sqlURL = [NSURL fileURLWithPath:sqlPath];if (![[NSFileManager defaultManager] fileExistsAtPath:sqlPath]) {return NO;}// 比较存在模型数据的元数据NSError *error = nil;// 数据库的数据结构NSDictionary *sourceMetaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:sqlURL options:nil error:&error];// 比较数据库的数据 和目标数据是否相同 如果相同 不需要迁移操作NSManagedObjectModel *destinationModel = _coord.managedObjectModel;if ([destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetaData]) {return NO;}return YES;}
2 如果需要迁移 则进行迁移操作
- (BOOL)startMigration
{BOOL success = NO;NSError *error = nil;// 旧的数据库路径NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString *sqlPath = [docStr stringByAppendingPathComponent:@"student.sqlite"];NSURL *sqlURL = [NSURL fileURLWithPath:sqlPath];// 原来的数据模型信息NSDictionary *sourceMetaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:sqlURL options:nil error:&error];// 原来的数据模型NSManagedObjectModel *soureceModel = [NSManagedObjectModel mergedModelFromBundles:nil forStoreMetadata:sourceMetaData];// 当前的数据模型信息NSManagedObjectModel *destinationModel = _coord.managedObjectModel;// 加载数据迁移的模型 mappingModelNSMappingModel *mapModel = [NSMappingModel mappingModelFromBundles:nil forSourceModel:soureceModel destinationModel:destinationModel];if (mapModel) {// 迁移管理器NSMigrationManager *mgr = [[NSMigrationManager alloc]initWithSourceModel:soureceModel destinationModel:destinationModel];// 监听的数据迁移的进度// 监听的进度可以用来给用户进行展示 例如说QQ新版本更新完之后打开之后,有一个进度条会更新数据,应该就是这个操作[mgr addObserver:selfforKeyPath:@"migrationProgress"options:NSKeyValueObservingOptionNewcontext:NULL];// 先把模型存储到临时的sqlite 迁移完成再进行替换操作// 目的路径NSString *destPath = [docStr stringByAppendingPathComponent:@"temp2.sqlite"];NSURL *destURL = [NSURL fileURLWithPath:destPath];success = [mgr migrateStoreFromURL:sqlURL type:NSSQLiteStoreType options:nil withMappingModel:mapModel toDestinationURL:destURL destinationType:NSSQLiteStoreType destinationOptions:nil error:&error];if (success) {// 证明数据迁移成功[self replaceStore:sqlURL withStore:destURL];}else{// 迁移数据失败NSLog(@"%@",error.description);}}return success;
}// 响应监听的方法
- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(void *)context {if ([keyPath isEqualToString:@"migrationProgress"]) {dispatch_async(dispatch_get_main_queue(), ^{float progress =[[change objectForKey:NSKeyValueChangeNewKey] floatValue];int percentage = progress * 100;NSString *string =[NSString stringWithFormat:@"Migration Progress: %i%%",percentage];NSLog(@"%@",string);});}
}// 将旧的移除新的放置在旧的上面
-(BOOL)replaceStore:(NSURL *)old withStore:(NSURL *)new
{BOOL success = NO;NSError *error = nil;if ([[NSFileManager defaultManager] removeItemAtURL:old error:&error]) {error = nil;if ([[NSFileManager defaultManager] moveItemAtURL:new toURL:old error:&error]) {success = YES;}}return success;
}
相关文章:

Linux内核之内存管理(4)--缺页处理程序
本文主要解说缺页处理程序,凝视足够具体,不再解释。 //以下函数将一页内存页面映射到指定线性地址处,它返回页面的物理地址 //把一物理内存页面映射到线性地址空间指定处或者说把线性地址空间指定地址address处的页面映射到主内存区页面page上…

WebSocket协议分析
点击上方↑↑↑蓝字[协议分析与还原]关注我们“ 解析websocket数据格式。”好久不见,一晃一年又过去了,祝大家新年好运。今天,给大家分析一个常见的协议——WebSocket,这是一个标准协议,虽然没有HTTP历史悠久ÿ…

《postfix邮件服务下mailq、postmap、postqueue 、 postsuper等用法》
1、Mailq 功能说明:显示待寄邮件的清单。 语 法:mailq [-q] 补充说明:mailq可列出待寄邮件的清单,包括邮件ID,邮件大小,邮件保存时间,寄信人,收信人,以及邮件无法寄出…

[deviceone开发]-一个很炫的手势动画示例
一、简介 这是iOS下的效果,android下完全一致。通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手势控制图片上下动画滑动实现开合效果,还支持声音效果。 二、效果图 三、相关下…
iOS lldb调试
LLDB 初始 LLDB 是一个有着 REPL 的特性和 C ,Python 插件的开源调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令,并且按照你所认为合适的…

万物之中,希望至美
一觉醒来,虎年就这么来了。感谢各位朋友过去的一年与我同在。在新的一年到来之际,我首先做个检讨,过去的一年,我们这个公众号,更新不够频繁,属于三天打鱼两天晒网型公众号,没有为大家带来足够丰…

[转]VS2015编译的程序在其他机器上缺少msvcp120.dll
http://www.lai18.com/content/1159618.html 1、 今天分享一个自己在开发过程中遇到的困难。用VS2015开发了一个windows客户端(win32项目),在自己的机器上运行很流畅。当你得意的把releas版本进行打包,并进行发布后,问…

Discuz!的cookie机制
最近在做Discuz!的插件,需要用到cookie,一直觉得奇怪的一个问题,Discuz!大量使用了cookie,但是我在编写插件的时候如果不加入session_start函数cookie就无法使用,按理说Discuz!使用了这么多cookie它的核心应该有调用se…

iOS infoplist 权限设置
<dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSBluetoothPeripheralUsageDescription</key> <string>需要使用您的蓝牙</string> <key>NSCalendarsUsageDes…

python使用socket实现协议TCP长连接框架
点击上方↑↑↑蓝字[协议分析与还原]关注我们“ 使用python实现协议中常见的TCP长连接框架。”分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用长连接的方式,来保持客户端与服务器的联系,这…

哈夫曼编码与解码
这是我的第一篇博客,希望大神们批评指正。 首先介绍以下什么是哈夫曼树(来自百度百科) 哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一…

012-python基础-数据运算
1、算数运算: 2、比较运算 3、赋值运算 4、逻辑运算 5、成员运算: 6、身份运算: 7、位运算: 8、运算符优先级: 转载于:https://www.cnblogs.com/chhphjcpy/p/6064572.html

优化XCode的编译速度
1.将Debug Information Format改为DWARF 在工程对应Target的Build Settings中,找到Debug Information Format这一项,将Debug时的DWARF with dSYM file改为DWARF。 这一项设置的是是否将调试信息加入到可执行文件中,改为DWARF后,如…

给windows装个Mac黑苹果虚拟机
点击上方↑↑↑蓝字[协议分析与还原]关注我们“ windows下安装使用苹果Mac虚拟机。”平常的生活工作中,我大部分时候使用Windows,偶尔用用Mac。实在是用不惯Mac,但有的时候,有些工作还是需要在Mac上搞,不得不用&#x…

Ajax基础讲解 1
随着web的不断发展,Ajax的运用越来越普及,但是对很多同学来说Ajax稍微有些难懂,今天呢就简单给大家讲解一下Ajax的一些基础入门的知识,希望可以帮到刚学习Ajax的同学。 第一步:首先就是服务器的搭建,关于服…

在虚拟机linux环境下编译windows版adb fastboot
原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html我根据虚拟机编译遇到的问题进行一些添加【前提条件】Linux Android源码完整虚拟机磁盘空间100G左右(60G用来存放代码和编译后的文件)swap 30G左右,若太小会导致…

PC端微信小程序wxapkg解密
sh点击上方↑↑↑蓝字[协议分析与还原]关注我们“ 解密PC端wxapkg文件。”用过微信pc版的应该都知道,PC上也可以使用微信小程序。这个小程序用起来和手机端差不多,不过,在分析时,确是有差别的——PC上的wxapkg文件是加密的。无论如…

cron 定时器简单入门
cron:计划任务,是任务在约定的时间执行已经计划好的工作,根据配置文件约定的时间来执行特定的任务。 编写测试类继承 IJob ,实现Execute 此方法就是用于定时的任务 配置定时时间: 先创建windows服务,服务创建详情 Inst…

PHP5.5.13 + Apache2.4.7安装配置流程详解
---恢复内容开始--- 自学PHP的这段时间里,真是倍感辛酸,相信广大的菜鸟们应该很我感同身受吧,在查阅了网上和众多数资料后,总结出来想当比较全面的安装方法,拿出来与广大的编程爱好者一起分享哈。 首先到官网上下载相关…

cocos2dx小游戏数据签名算法破解
点击上方↑↑↑蓝字[协议分析与还原]关注我们“ 快速破解小游戏常见的数据签名算法。”最近在分析各种小游戏的协议,本文以《我不是无双》这款小游戏为样例介绍这类小游戏的分析方法。01—抓包在分析开始,首先明确分析的目的是学习这款游戏的网络协议算法…

laravel5 MAC is invalid
如果本机的环境更换过,项目中用来加密Crypt组件中的参数会变更. 如果出现这个问题,得更换数据库中加密后的变量 stackoverflow上找到的解决方法都是 composer dump-autoload composer clear-cache 之后再清空浏览器缓存 其实最简单的解决方法是将数据库中的所有数据重新encrpt一…

不大于N的所有素数
算法如下: #include<stdio.h> #include<math.h> void Sieve(int n) {int p,j,i;int A[n1],L[n1];for(p2;p<n;p)A[p]p;for(p2;p<sqrt(n);p){if(A[p]!0){jp*p;while(j<n){A[j]0;jjp;}}}i0;for(p2;p<n;p){if(A[p]!0){L[i]A[p];i;}}for(p0;p<…

3集合与函数类型
import UIKit var str “Hello, playground” // 1 数组 // 创建一个空的数组 var arr1 Int; arr1.append(6); // 创建一个特定大小 并且所有数据都被默认的构造方法 // 以下数组有6个5 var arr2 Array(repeating: 5, count: 6); // 通过两个数组相加创建一个数组 var a…

非凡推崇_2015年值得推崇的25位编码者
非凡推崇by freeCodeCamp通过freeCodeCamp 2015年值得推崇的25位编码者 (25 Coders Worth Following on Twitter in 2015) Our community upvoted the following 25 coders, in no particular order, as “Coders Worth Following in 2015”:我们的社区对以下25位编码员进行了…
CSS中各种各样居中方法的总结
在开发前端页面的时候,元素的居中是一个永远都绕不开的问题。看似简单的居中二字,其实蕴含着许许多多的情况,对应着很多的处理方法,本文就试图对页面布局中的居中问题进行总结~~ 居中问题分为水平居中和竖直居中两种;而…

iOS 流式播放音频文件
方式一: https://github.com/tumtumtum/StreamingKit 方式二: https://github.com/AlexanderYeah/SK_PlayOnWavFileDemo

java 创建 HMAC 签名
ava 创建 HMAC 签名 psd素材 1. []ComputopTest.java package com.javaonly.hmac.test; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import …

2014年数字:我的人生在命令行中
by freeCodeCamp通过freeCodeCamp 2014年数字:我的人生在命令行中 (2014 in Numbers: My Life Behind the Command Line) For 2014, I decided to simplify my life. Rather than pursuing a variety of human experiences, as I had previously, I wanted to focu…

c# unity PlayerPrefs 游戏存档,直白点就是讲游戏数据本地保存下来
在游戏会话中储存和访问游戏存档。这个是持久化数据储存,比如保存游戏记录。 我的理解是通过某个特殊的标签来保存在本地,而且该标签为key的意思,初始值不用赋值。 在游戏开发中较为实用。 暂时用到了 SetInt(string key, int value); 还有Ge…

4-类和结构体和可选类型
import UIKit var str “Hello, playground” // 1 枚举语法 // 与 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值 // 书写方式一 enum sizeType{ case small case middle case large } // 书写方式二 enum sizeNumber { case x,…