数据存储梳理记录

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设备重启时,文件会被自动清除

猜你喜欢

转载自blog.csdn.net/ancientear/article/details/130744064