【原文地址:http://blog.sina.com.cn/s/blog_ecad0c6b0101hw7x.html】
原文地址:iOS中SQLite数据库云存储的实现
作者:坐隐在线
iOS中实现SQLite数据库云存储(iCloud)大概需要三步:
一、设置项目支持iCloud
二、persistentStoreCoordinat or中设置对iCloud存取
三、设置iCloud数据变化时的一个通知监听,以便在数据变化时同步本地用户界面。
下面进行看图说话:
1,新建一个Master-Detail iOS项目。
2,设置项目名称为TestiCloud,勾选Use Core Data,项目将自动创建一个SQLite数据库,便于测试。然后一路下一步完成项目创建。
3,登录苹果的开发者中心:developer.apple.com,点击iOS Provisioning Portal,使项目支持iCloud
4,建立一个新的App ID,如果是使原有项目支持iCloud,则跳过第4、5步。
5,填写描述及Bundle ID,这里是TestiCloud和net.zuoyin.TestiCloud
6,创建成功后列表中将出现新建的App ID(如果是原来的项目则在此直接修改),点击configure
7、勾选Enable for iCloud,弹出一个对话框,提示项目需重建provisioning,点击OK
8,点击左栏的Provisioning,然后点New Profile(如果是老项目,删掉原来的provisioning,重建)
9,建立provisioning,注意App ID的选择
10,下载新建的provisioning,拖到Organizer中,然后打开新建项目的Code signing,设置为相应的provisioning.
11,打开targets的Summary设置面板,向下拉,找到Entitlements,勾选Entitlements File(你会发现勾选后项目导航栏会增加一个名为TestiCloud.entitlements的文件),然后勾选Enable iCloud,key-Value Store程序中没用,所以不管这个(这是另外两种使用iCloud的方式中的一种,Key-Value Store类似于 NSUserDefaults的保存键值对,另一种是使用NSDocument管理文档,使用方法可查看Apple文档)。下面的Ubiquity Containners对SQLite很重要,点加号会自动增加一个Container,够测试用了。
12,现在如果没有出现错误,iCloud应该可用了,先在YTAppDelegat.m中增加一个测试iCloud的方法:
#define UBIQUOUTY_CONTAINER_IDENTITY @"TEAM_ID.net.zuoyin.TestiCloud"
下面进行第二步:修改persistentStoreCoordinat or方法以增加对iCloud的存取,修改部分我已经加红了。
(![_persistentStoreCoordinat
or
addPersistentStoreWithTy
pe:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error]) 新定义的options变量取代了原来的nil。
下面进行第三步:设置iCloud数据变化监听,修改
等了大约有一分钟,哇!手机上数据更新了,My iCloud!但是怎么只有两行呢?iPad上填加了四行啊?程序问题?网络问题?iCloud问题?还没搞明白。
抽了根烟,继续等,还是那样。算了,都删掉,再加四行。这次在iPhone上先加:
这次数据对了(iPad闪退了四次,看来数据是一条一条从iCloud更新回来的
)
小结:
SQLite(Core Data)进行云存储还是挺简单的,没增加多少代码。当然这只是个测试,具体实现上还会有一些问题,比如我还发现这个测试启动时非常慢(看来启动就测试云是否可用不是好办法)。
一、设置项目支持iCloud
二、persistentStoreCoordinat
三、设置iCloud数据变化时的一个通知监听,以便在数据变化时同步本地用户界面。
下面进行看图说话:
1,新建一个Master-Detail iOS项目。
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/ae46973f7ac636728bf9dde2ccb21030.jpeg)
2,设置项目名称为TestiCloud,勾选Use Core Data,项目将自动创建一个SQLite数据库,便于测试。然后一路下一步完成项目创建。
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/72f7dd82c7ee301a2a6f750140ffc50a.jpeg)
3,登录苹果的开发者中心:developer.apple.com,点击iOS Provisioning Portal,使项目支持iCloud
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/fec0d5c9efb339488fbbe763cd85b023.jpeg)
4,建立一个新的App ID,如果是使原有项目支持iCloud,则跳过第4、5步。
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/f06d497c0ef7c0737ece63a34a3942ed.jpeg)
5,填写描述及Bundle ID,这里是TestiCloud和net.zuoyin.TestiCloud
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/e437db764f8bf2af6b9d125cc1bc12ce.jpeg)
6,创建成功后列表中将出现新建的App ID(如果是原来的项目则在此直接修改),点击configure
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/f1742d083e5ebcdf8074ad875609a5ae.jpeg)
7、勾选Enable for iCloud,弹出一个对话框,提示项目需重建provisioning,点击OK
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/82e28d2ec7c36351aeb0ea1c26d78e73.jpeg)
8,点击左栏的Provisioning,然后点New Profile(如果是老项目,删掉原来的provisioning,重建)
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/393a181e8f46839ac404374a3c38130a.jpeg)
9,建立provisioning,注意App ID的选择
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/c1f3c013cca456cd48fbaa6fc81e82a2.jpeg)
10,下载新建的provisioning,拖到Organizer中,然后打开新建项目的Code signing,设置为相应的provisioning.
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/a2b8387474b2abc5e81a18531095ad06.jpeg)
11,打开targets的Summary设置面板,向下拉,找到Entitlements,勾选Entitlements File(你会发现勾选后项目导航栏会增加一个名为TestiCloud.entitlements的文件),然后勾选Enable iCloud,key-Value Store程序中没用,所以不管这个(这是另外两种使用iCloud的方式中的一种,Key-Value Store类似于 NSUserDefaults的保存键值对,另一种是使用NSDocument管理文档,使用方法可查看Apple文档)。下面的Ubiquity Containners对SQLite很重要,点加号会自动增加一个Container,够测试用了。
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/6dd4153a46784ead93c26560201c8a58.jpeg)
12,现在如果没有出现错误,iCloud应该可用了,先在YTAppDelegat.m中增加一个测试iCloud的方法:
#define
@interface YTAppDelegate()
- (BOOL)isiCloudAvailable;
@end
- (BOOL)isiCloudAvailable
{
NSURL *dbURL=[[NSFileManager defaultManager] URLForUbiquityContainerI dentifier:UBIQUOUTY_CONTAINER_IDENTITY];
if (dbURL)
{
return YES;
}
else return NO;
}
注意常量定义中的TEAM_ID是形如“179DVMTAP1”这样的字符,可在Provisioning Portal中查找。
然后在application:didFinishLauchingWithOpt ions方法中加入两行代码:
if
(self.isiCloudAvailable)
NSLog(@"Good
job!");
else
NSLog(@"Sorry,You
must
work
harder...");
进行测试,修改后的代码是这样的。
-
@end
-
{
}
注意常量定义中的TEAM_ID是形如“179DVMTAP1”这样的字符,可在Provisioning Portal中查找。
然后在application:didFinishLauchingWithOpt
进行测试,修改后的代码是这样的。
-
(BOOL)application:(UIApplication
*)application
didFinishLaunchingWithOp
tions:(NSDictionary
*)launchOptions
{
//
Override
point
for
customization
after
application
launch.
if
([[UIDevice
currentDevice]
userInterfaceIdiom]
==
UIUserInterfaceIdiomPad)
{
UISplitViewController
*splitViewController
=
(UISplitViewController
*)self.window.rootViewController;
UINavigationController
*navigationController
=
[splitViewController.viewControllers
lastObject];
splitViewController.delegate
=
(id)navigationController.topViewController;
UINavigationController
*masterNavigationControll
er
=
splitViewController.viewControllers[0];
YTMasterViewController
*controller
=
(YTMasterViewController
*)masterNavigationControll
er.topViewController;
controller.managedObjectContext
=
self.managedObjectContext;
}
else
{
UINavigationController
*navigationController
=
(UINavigationController
*)self.window.rootViewController;
YTMasterViewController
*controller
=
(YTMasterViewController
*)navigationController.topViewController;
controller.managedObjectContext
=
self.managedObjectContext;
}
if (self.isiCloudAvailable) NSLog(@"Good job!");
else NSLog(@"Sorry,You must have made some mistakes...");
return
YES;
}
确定程序不会产生诸如使显示器爆炸等恶劣后果,运行程序,输出如下图,电脑夸你干得好,说明前面进行的设置没有问题^_^,iCloud可正常使用。现在完成了第一步。
{
}
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/693c0b0eeb93048bad8e11e64738cdb2.jpeg)
下面进行第二步:修改persistentStoreCoordinat
-
(NSPersistentStoreCoordin
ator
*)persistentStoreCoordinat
or
{
if
(_persistentStoreCoordinat
or
!=
nil)
{
return
_persistentStoreCoordinat
or;
}
NSDictionary *options=nil;
if ([self isiCloudAvailable])
{
NSURL *dbURL=[[NSFileManager defaultManager] URLForUbiquityContainerI dentifier:UBIQUOUTY_CONTAINER_IDENTITY];
options=[NSDictionary dictionaryWithObjectsAnd Keys:@"net.zuoyin.TestiCloud.SQLite",NSPersistentStoreUbiquit ousContentNameKey,dbURL,NSPersistentStoreUbiquit ousContentURLKey, nil];
}
NSURL
*storeURL
=
[[self
applicationDocumentsDire
ctory]
URLByAppendingPathCompon
ent:@"TestiCloud.sqlite"];
NSError
*error
=
nil;
_persistentStoreCoordinat
or
=
[[NSPersistentStoreCoordin
ator
alloc]
initWithManagedObjectMod
el:[self
managedObjectModel]];
if
(![_persistentStoreCoordinat
or
addPersistentStoreWithTy
pe:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error])
{
NSLog(@"Unresolved
error
%@,
%@",
error,
[error
userInfo]);
abort();
}
return
_persistentStoreCoordinat
or;
}
注意:if
{
}
下面进行第三步:设置iCloud数据变化监听,修改
-
(NSManagedObjectContext
*)managedObjectContext
{
if
(_managedObjectContext
!=
nil)
{
return
_managedObjectContext;
}
NSPersistentStoreCoordin
ator
*coordinator
=
[self
persistentStoreCoordinat
or];
if
(coordinator
!=
nil)
{
NSManagedObjectContext
*managedObjectContext
=
[[NSManagedObjectContext
alloc]
initWithConcurrencyType:NSMainQueueConcurrencyTy
pe];
[managedObjectContext
performBlockAndWait:^(void){
[managedObjectContext
setPersistentStoreCoordi
nator:coordinator];
if([self isiCloudAvailable])
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(iCloudDataDidChange)
name:NSPersistentStoreDidImpo rtUbiquitousContentChang esNotification
object:coordinator];
}
}];
_managedObjectContext=managedObjectContext;
}
return
_managedObjectContext;
}
增加相应的调用方法:
//Very very bad code!
{
}
增加相应的调用方法:
//Very very bad code!
- (void)iCloudDataDidChange{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
YTMasterViewController *controller = (YTMasterViewController *)navigationController.topViewController;
controller.fetchedResultsController =nil;
[controller fetchedResultsController ];
[controller.tableView reloadData];
}
iCloudDataDidChange方法只是为了测试,千万别在程序中直接这样做(iPad这样更新tableView数据会直接闪退
)
对了,模拟机上不能进行iCloud测试,所以必须用两台实际的设备进行测试。
运行程序,先在iPad上点击加号,会增加数据。
}
iCloudDataDidChange方法只是为了测试,千万别在程序中直接这样做(iPad这样更新tableView数据会直接闪退
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/9172587e03b6fb31020b30d30bd4322e.gif)
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/9172587e03b6fb31020b30d30bd4322e.gif)
对了,模拟机上不能进行iCloud测试,所以必须用两台实际的设备进行测试。
运行程序,先在iPad上点击加号,会增加数据。
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/1afa817b0252ab19c476611079141d69.jpeg)
等了大约有一分钟,哇!手机上数据更新了,My iCloud!但是怎么只有两行呢?iPad上填加了四行啊?程序问题?网络问题?iCloud问题?还没搞明白。
抽了根烟,继续等,还是那样。算了,都删掉,再加四行。这次在iPhone上先加:
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/58c7a3eb9fbeb01b5261d0f1e689d8a8.jpeg)
这次数据对了(iPad闪退了四次,看来数据是一条一条从iCloud更新回来的
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/9172587e03b6fb31020b30d30bd4322e.gif)
![[转载]iOS中SQLite数据库云存储的实现 [转载]iOS中SQLite数据库云存储的实现](https://i-blog.csdnimg.cn/blog_migrate/94bcde9c83ea09bd9d7f1213afe96f3b.jpeg)
小结:
SQLite(Core Data)进行云存储还是挺简单的,没增加多少代码。当然这只是个测试,具体实现上还会有一些问题,比如我还发现这个测试启动时非常慢(看来启动就测试云是否可用不是好办法)。