目录
- 1、FMDB-第三方SQLite数据库框架
- 1.1 现状
- 1.2 线程安全问题
- 1.2.1 FMDatabase
- 1.2.2 FMDatabaseQueue
- 1.2.3 FMDatabasePool
- 2、进程间通信
- 2.1 URL Scheme
- 2.2 keyChain
- 2.3 UIPasteboard
- 2.4 UIDocumentInteractionController
- 2.5 local socket
- 2.6 AirDrop
- 2.7 UIActivityViewController
- 2.8 App Groups
- 3、实例分析
- 3.1 代码段
- 3.2 数据库
- 3.3 基本操作
- 3.4 存储文件路径
1、FMDB-第三方SQLite数据库框架
1.1 现状
目前项目中采用的是是FMDatabase实例化一个对象,缺点是只适合在单线程per thread中使用,在多线程下是不安全的。在使用过程需要用大量的代码拼接SQL、拼装Object。
现有项目数据库存储使用的是FMDB。
(1)文件系统数据库:指定一个文件系统路径,FMDB会尝试打开该文件。如果文件不存在,会创建该文件。
(2)临时数据库:指定一个空字符串@“”,FMDB会创建一个临时数据库。当FMDatabase实例关闭连接,就自动删除该数据库。
(3)内存数据库:当用户不指定数据库路径,FMDB会在内存中创建一个数据。当FMDataBase关闭连接,该数据库会被自动销毁。
1.2 线程安全问题
多线程环境下应该使用FMDatabaseQueue对象替代,以保证数据库的安全访问。
1.2.1 FMDatabase
一个对象对应一个sqlite,自己持有并保证进行单线程操作。
1.2.2 FMDatabaseQueue
多线程环境下应该使用FMDatabaseQueue对象替代,以保证数据库的安全访问。
1、把对应的操作封装成block的形式添加到一个serial的线程队列中,以保证所有异步添加进来的数据库操作都会在serial队列中按顺序执行,保证多线程环境下的数据安全。执行操作主要是通过serial queue的dispatch_sync()同步操作API完成的,这样就避免了访问数据时异步操作的可能性,从而保证多线程下的安全访问。
2、虽然多个block都是放到同一个队列里,但是其实是跑在不同的thread里,只要把block放到合适的队列里,GCD就会完成线程的创建,分配与回收。同一个队列可以对应多个thread。
3、FMDatabaseQueue可以多线程访问,但是都是使用同一个FMDatabase对象,保证同时只有一个线程持有FMDatabase对象,排起队来一个一个访问操作。
1.2.3 FMDatabasePool
FMDatabasePool,不同线程使用同一个FMDatabasePool对象,而使用不同的FMDatabase对象来进行数据库操作,后续研究下再补充。
2、进程间通信
由于沙箱运行,iOS内不同应用之间高度隔离,一些IPC方法,例如管道、邮槽、共享内存、Socket用不了。
2.1 URL Scheme
URL Call的处理函数,参数url是传进的url sourceApplication是呼叫应用的bundle identifier,通过此参数,应用可以对呼叫的应用进行过滤。annotation是呼叫过程中可以附加的额外参数。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
}
如教师派下的支付,在教师派中,使用的应用调用协议是URL Schema,教师派可以声明自定义的调用协议,当支付宝或者微信打算在应用内打开教师派时,可以打开使用教师派自定义的协议开头的URL来打开教师派,除了协议头,URL中还可以附加其他参数。在app内加载网页内支付,去微信zf,支付完返回app时刷新网页
使用URL Scheme,同一时刻只能有一个进程在前台,主动呼叫的应用在调用成功后必须进入后台,所以能传递的只有URL中所带的参数或annotation中所带的参数,调用的过程中会出现应用之间的切换。
2.2 keyChain
keyChain是一个sqlite数据库,里面的所有数据都是经过加密的。Keychain的信息是存在于每个应用(app)的沙盒之外的。app的信息保存在keyChain中,即使app删除,keyChain里的数据也不会删除,因此可以用于同一账户的多平台登录。例如交易ID、积分在银行和教师下的数据是可以保存下来的。
这个数据是存在系统的,所以就算卸载软件,也照样存在机器中,除非恢复系统。每个ios程序都有一个独立的keychain存储。
用于储存一些私密信息,比如密码、证书等等,Keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效。
同样也适用于应用之间数据共享。KeyChain相当于是一个Dictionary,所有数据都以key-value的形式存储,可以对这个Dictionary进行add、update、get、delete这四个操作。
2.3 UIPasteboard
多个app之间,是可以共享剪贴板里的数据的
从剪贴板里写入和读取数据
2.4 UIDocumentInteractionController
实现app中文档共享
2.5 local socket
这种方式不太常见,也是很容易被iOS开发者所忽略但是特别实用的一种方法。它的原理很简单,一个App1在本地的端口port1234进行TCP的bind和listen,另外一个App2在同一个端口port1234发起TCP的connect连接,这样就可以建立正常的TCP连接,进行TCP通信了,那么就想传什么数据就可以传什么数据了。
这种方式最大的特点就是灵活,只要连接保持着,随时都可以传任何相传的数据,而且带宽足够大。它的缺点就是因为iOS系统在任意时刻只有一个app在前台运行,那么就要通信的另外一方具备在后台运行的权限,像导航或者音乐类app。
它是常用使用场景就是某个App1具有特殊的能力,比如能够跟硬件进行通信,在硬件上处理相关数据。而App2则没有这个能力,但是它能给App1提供相关的数据,这样APP2跟App1建立本地socket连接,传输数据到App1,然后App1在把数据传给硬件进行处理。
2.6 AirDrop
2.7 UIActivityViewController
2.8 App Groups
App Group用于同一个开发团队开发的App之间,包括App和Extension之间共享同一份读写空间,进行数据共享。同一个团队开发的多个应用之间如果能直接数据共享,大大提高用户体验。
3、实例分析
3.1 代码段
● (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// <iOS9.0
KGLog(@"++++ %@ %@", url, sourceApplication);
//在app内加载网页内支付,去微信zf,支付完返回app时刷新网页
if ([url.absoluteString isEqualToString:KGWXWebReferer]) {
[[NSNotificationCenter defaultCenter] postNotificationName:KGSaleWXToAPPNotification object:nil];
return YES;
}
if ([url.absoluteString hasPrefix:@"jiaoshipai"]) {
[[KGWebOpenAppTool shareInstance] handleOpenURL:url];
return YES;
}
// BOOL canHandleURL = [Pingpp handleOpenURL:url withCompletion:nil];
if ([[KGPKit defaultManager] handleOpenURL:url]) {
return YES;
}
return NO;
}
3.2 数据库
1、lessonTime数据库
数据表及字段(教师、银行、综合)
1、seektime(课程ID、视频ID、这节课看的总时间)
2、time()
3.3 基本操作
教师/银行
1、建表,seektime(观看时间),time(本地观看数据)
2、提交本地观看数据
3、保存观看时间
4、获取上次的观看时间,继续看
综合
1、建表,seektime(观看时间),字段包含课程ID、视频ID、这节课看的总时间
2、保存观看时间
3、获取上次的观看时间,继续看
4、获取某classid下最近学习的vid(KGLookVideoData-%@.plist),显示“最近学习”
3.4 存储文件路径
沙盒地址:KGLessonTimeDataBasePath = /var/mobile/Containers/Data/Application/XXXXXXXXXXXX/Documents/lessonTime.db
1、Document:持久的数据
2、Library:设置程序的默认设置和其他状态信息
3、temp:临时文件的目录,当iOS设备重启时,文件会被自动清除