(一一六)新浪微博client的离线缓存实现思路
上一节(一一五)利用NSKeyedArchiver实现随意对象转为二进制介绍了将随意对象转化为二进制数据和还原的方法。可用于实现本节介绍的微博数据离线缓存。
通过新浪官方的API能够发现,返回的微博数据例如以下样式:
{
"statuses": [
{
"created_at": "Tue May 31 17:46:55 +0800 2011",
"id": 11488058246,
"text": "求关注。 ",
"source": "<a href="http://weibo.com" rel="nofollow">新浪微博</a>",
"favorited": false,
"truncated": false,
"in_reply_to_status_id": "",
"in_reply_to_user_id": "",
"in_reply_to_screen_name": "",
"geo": null,
"mid": "5612814510546515491",
"reposts_count": 8,
"comments_count": 9,
"annotations": [],
"user": {
"id": 1404376560,
"screen_name": "zaku",
"name": "zaku",
"province": "11",
"city": "5",
"location": "北京 朝阳区",
"description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。 ",
"url": "http://blog.sina.com.cn/zaku",
"profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
"domain": "zaku",
"gender": "m",
"followers_count": 1204,
"friends_count": 447,
"statuses_count": 2908,
"favourites_count": 0,
"created_at": "Fri Aug 28 00:00:00 +0800 2009",
"following": false,
"allow_all_act_msg": false,
"remark": "",
"geo_enabled": true,
"verified": false,
"allow_all_comment": true,
"avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
"verified_reason": "",
"follow_me": false,
"online_status": 0,
"bi_followers_count": 215
}
},
...
],
"ad": [
{
"id": 3366614911586452,
"mark": "AB21321XDFJJK"
},
...
],
"previous_cursor": 0, // 暂未支持
"next_cursor": 11488013766, // 暂未支持
"total_number": 81655
}
当中的statuses是微博字典数组,微博client通过字典数组转为微博模型WeiboStatus,然后通过微博模型创建微博尺寸模型StatusFrame模型,最后Cell通过尺寸模型StatusFrame拿到应该显示的内容和尺寸。这是client实现的功能。
获取数据的关键,在于statuses的抓取上,通常情况下我们向新浪的server发送请求,接收到响应体,取出statuses字典数组后进行处理。如今我们要实现的是进入client时先推断有没有缓存过数据。缓存过则直接显示已经缓存的数据。而不直接通过网络请求。
离线缓存通过iOS自带的SQLite3实现。
关于数据库的使用请參考文章使用FMDB操作SQLite数据库,本文重点是缓存思路。
微博有一个唯一标志idstr用于标识微博的先后顺序,idstr越大的微博越新,我们的缓存思路是把微博字典数组中的每一条微博都用NSKeyedArchiver转化为二进制存入数据库的status字段,然后再把idstr存储到idstr字段,通过对idstr排序、和当前要求的id范围比較就能够正确推断出数据的新旧关系。
在给新浪发送数据时,假设是载入新数据。会在參数中增加一个since_id,表示仅仅载入这个id之后的微博。假设是载入旧数据,会在參数中增加一个max_id,表示仅仅载入这个之前的。
因此在缓存数据时,仅仅接收微博字典数组就可以。在读取缓存时,传入请求參数,推断參数中有无since_id、max_id就可以。缓存方法均为类方法,为了能拿到数据库,使用一个静态成员变量管理。而且在类的公共初始化方法中打开数据库,假设没有创建过表则创建。
数据库的打开:
static FMDatabase *_db;
+ (void)initialize{ // 公共类初始化方法
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"statuses.sqlite"];
_db = [FMDatabase databaseWithPath:path];
[_db open];
[_db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_status (id integer PRIMARY KEY, status blob NOT NULL, idstr text NOT NULL)"];
}
缓存的方法:
+ (NSArray *)statusesWithParams:(NSDictionary *)params{ NSString *sql = nil; if (params[@"since_id"]) {
// 载入最新
sql = [NSString stringWithFormat:@"SELECT * FROM t_status WHERE idstr > %@ ORDER BY idstr DESC LIMIT 20",params[@"since_id"]];
}else if(params[@"max_id"]){
// 载入旧数据
sql = [NSString stringWithFormat:@"SELECT * FROM t_status WHERE idstr <= %@ ORDER BY idstr DESC LIMIT 20",params[@"max_id"]];
}else{
// 无条件载入最前面20条
sql = [NSString stringWithFormat:@"SELECT * FROM t_status ORDER BY idstr DESC LIMIT 20"];
} // 运行查询
FMResultSet *set = [_db executeQuery:sql];
NSMutableArray *statuses = [NSMutableArray array];
while (set.next) {
NSData *dictData = [set objectForColumnName:@"status"];
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:dictData];
[statuses addObject:dict];
} return statuses; } + (void)saveStatuses:(NSArray *)statuses{ for (NSDictionary *statusDict in statuses) {
NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:statusDict];
[_db executeUpdateWithFormat:@"INSERT INTO t_status (status, idstr)VALUES(%@,%@)",dictData,statusDict[@"idstr"]];
} }
在运行网络请求时。调用读取缓存的方法。假设得到的数组中有元素,则不进行网络请求。而是对缓存的字典转模型。然后进一步操作,这样就完毕了缓存。
(一一六)新浪微博client的离线缓存实现思路的更多相关文章
- 使用html5的离线缓存技术
突然想用html5的离线缓存,但是一直没有成功,在各种群里问发现很多人都没什么经验,最终终于在各种论坛找到解决方案了.下面就简单记录一下相关情况. 一.离线缓存的优点 我们都知道离线缓存主要是用来减少 ...
- iOS---数据离线缓存
离线缓存 为了用户的体验,不需要每次打开App都加载新数据,或者重新请求数据,因此需要把每次浏览的数据保存起来,当下次打开软件时,首先从沙盒中加载数据:或者当软件未联网时,也只能从沙盒中加载旧数据. ...
- HTML5 离线缓存管理库
一.HTML5离线缓存技术 支持离线缓存是HTML5中的一个重点,离线缓存就是让用户即使在断网的情况下依然可以正常的运行应用.传统的本地存储数据的方式有 localstorage,sessionsto ...
- 使用 jQuery Mobile 与 HTML5 开发 Web App —— HTML5 离线缓存
本文要介绍的,是 HTML5 离线网络应用程序的特性,离线网络应用程序在 W3C 中的实际名称是 "Offline Web applications" ,也称离线缓存.当用户打开浏 ...
- iOS开发:一个高仿美团的团购ipad客户端的设计和实现(功能:根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除等)
大致花了一个月时间,利用各种空闲时间,将这个客户端实现了,在这里主要是想记录下,设计的大体思路以及实现过程中遇到的坑...... 这个项目的github地址:https://github.com/wz ...
- HTML5新特性之离线缓存技术
一.离线缓存的起因. HTML5之前的网页,都是无连接,必须联网才能访问,这其实也是web的特色,这其实对于PC是时代问题并不大,但到了移动互联网时代, 设备终端位置不再固定,依赖无线信号,网络的可靠 ...
- HTML5离线缓存(Application Cache)
HTML5离线缓存又名Application Cache,是从浏览器的缓存中分出来的一块缓存区,要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源. ...
- HTML5离线缓存问题
HTML5离线缓存问题 1.应用程序缓存 什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. ...
- HTML5离线缓存
参考文档:http://www.w3cschool.cc/html/html5-app-cache.html HTML5 应用程序缓存 又称离线缓存 ,即使断线了,刷新后也还是缓存了原来的页面,不会4 ...
随机推荐
- 63.当当网txt数据按行切割与合并
获取文件有多少行 //获取文件有多少行 int getN(char *path) { FILE *pf = fopen(path, "r"); if (pf==NULL) { ; ...
- MD5和sha1加密算法--散列加密技术 MD5:128bit的大整数
在很多电子商务和社区应用中,我们都要存放很多的客户的资料,其中包括了很多的隐私信息和客户不愿被别人看到的信息,当然好有客户执行各种操作的密码,此时就需要对客户的信息进行加密再存储,目前有两种比较好的加 ...
- Atcoder At Beginner Contest 068 D - Decrease (Contestant ver.)
D - Decrease (Contestant ver.) Time limit : 2sec / Memory limit : 256MB Score : 600 points Problem S ...
- 【习题 7-1 UVA-208】Firetruck
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 预处理一下终点能到达哪些点. 暴力就好. 输出结果的时候,数字之间一个空格.. [代码] /* 1.Shoud it use lon ...
- 【2017 Multi-University Training Contest - Team 6】Inversion
[链接]h在这里写链接 [题意] 给出一个序列,求2~n每一个数,下标不是这个数倍数的最大值是什么? [题解] 把a数组从大到小排序. 每个位置i,逆序枚举b数组,找到第一个对应下标不是i的倍数的,直 ...
- 腾讯官网生成qq在线客服代码
http://jingyan.baidu.com/article/e2284b2b42ce8ce2e6118ddd.html
- wmi 一些配置(参考)
http://www.bubuko.com/infodetail-1937463.html
- C语言速度优化之指针赋值与if推断
近期在写的一个项目须要优化处理速度,我写了一下程序来測试指针赋值与指针推断的速度比較.结果让我大吃一惊. #include <stdio.h> #include <stdlib.h& ...
- 洛谷 P1808 单词分类_NOI导刊2011提高(01)
P1808 单词分类_NOI导刊2011提高(01) 题目描述 Oliver为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类. 两个单词可以分为一类当且仅当 ...
- Android 监听电量的状态
监控手机电量的变化和充电状态 在BatteryManager中有一个粘性广播,不需要BroadcastReceiver作为接收器,在注册时将传入null IntentFilter filter = n ...