使用NSUserDefaults跨App间通信
NSUserDefaults是什么想必我应该不用多说了,相信每一个iOS开发都是知道并且能够熟练使用的(NSUserDefaults在Foundation框架中被定义,用来存储和读取一些轻量级数据。其本质是操作plist文件)。当然,说这些基础意义不大,今天我想说一点大部分人不知道的,那就是使用NSUserDefaults跨App间通信。
巧用SuiteName
- (nullable instancetype)initWithSuiteName:(nullable NSString *)suitename NS_AVAILABLE(10_9, 7_0) NS_DESIGNATED_INITIALIZER;
这个方法可能大部分人没有用过,它的作用是跨App间通信或者主App与Extension共享数据,一般配合使用的是App Groups。
App Groups数据共享
在两个项目Target
里面的Signing & Capabilities
中,将App Groups
的SuiteName设置成一致的标识字符串(将两个App加入同一个Group)。
然后在两个App分别使用
- (NSUserDefaults *)userDefaults
{
return [[NSUserDefaults alloc] initWithSuiteName:@"group.urwork.autosignin"]; //name需要是Group的id
}
来存储和读取数据,即可实现数据共享。
超微型简单方便易用数据库
假设我们需要将用户的历史搜索记录保存到本地,当接到这个需求的时候,你的脑海里可能闪过的想法:简单,本地存个字典(或者Plist文件),每个key是一个用户id,value是一个数组,数组里的每个元素是一个字典,这个字典里有articleId、title、imgUrl、...。结构大概是这样:
{
"10086" : [
{
"articleId" : 1,
"imgUrl" : "https://img.xxx.com/abcdefg.png",
"title" : "中国历史",
...
},
{
"articleId" : 2,
"imgUrl" : "https://img.xxx.com/abcdefg.png",
"title" : "中国教育",
...
},
...
],
"10087" : [
{
"articleId" : 2,
"imgUrl" : "https://img.xxx.com/abcdefg.png",
"title" : "中国教育",
...
},
...
]
}
看起来OK,但是小伙伴们,性能问题还是要考虑的。我想获取某个用户的浏览历史,需要把文件整体读到内存中,然后用dict[@"10086"]
的方法,得到这个用户的浏览历史Array,用户少还好,多了,每次读取的IO操作会很耗时,对性能有影响。
可能你会说用数据库啊什么的,当然可以,但是又是需要依赖一堆第三方,还要写好多代码,创建好多类。我就是想简单实现一下,有没有更好的方法呢?当然有,超微型简单方便易用数据库。
每个用户都可以用一个NSUserDefaults
来代替,每个用户的浏览历史,可以直接用setObject:forKey:
的方式来存储,如:
//这个跟App Groups没有关系
//已有则读取,没有则创建
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"10086"];
//存储
[userDefaults setObject:history forKey:@"ArticleBrowsingHistory"];
//读取
NSArray *history = [userDefaults objectForKey:@"ArticleBrowsingHistory"];
所有用户相对独立,每个用户是一个plist文件,在沙盒目录/Library/Preferences/中,
想删除也很容易,直接删除这个文件即可。
其实这个超微型简单方便易用数据库还可以实现好多功能,看你怎么操作了。如果你的App没有后台,不同用户的主题设置、语言设置可能不同,都可以通过这个来存储。