(一一六)新浪微博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 ...
随机推荐
- Java学习笔记三
1.面向过程思想,强调的是过程(即动作,函数):面向对象思想,强调的是对象. 2.类与对象关系:类是对事物的描述(属性和行为-方法),对象是类的实例.对象通过new生成.属性也称成员变量;方法也称成员 ...
- android组件
SlidingDrawer http://www.cnblogs.com/renyuan/archive/2012/09/16/2687929.html autocompletetextview / ...
- InstallShield详细制作说明(一)
虽然网上关于InstallShield的制作说明已经很多,但是看的时候还是会有些晕乎乎的,不得不说很复杂.前段时候做了一次,后面需要升级,在重新做的时候发现有些地方自己又忘了,所以有必须将自己看的教程 ...
- Codefroces 812 B. Sagheer, the Hausmeister
http://codeforces.com/problemset/problem/812/B B. Sagheer, the Hausmeister time limit per test 1 sec ...
- Codeforces Round #194 (Div. 2) 部分题解
http://codeforces.com/contest/334 A题意:1-n^2 平均分成 n 份,每份n个数,且和相同 解法 : 构造矩阵1-n^2的矩阵即可 ][]; int main() ...
- 字符设备驱动-----Linux中断处理体系结构
一.中断处理体系结构的初始化 Linux内核将所有的中断统一编号,使用一个irq_desc结构数组来描述这些中断;每个数组项对应一个中断,也可能是一组中断,它们共用相同的中断号,里面记录了中断的名称. ...
- @转EXT2->EXT3->EXT4
Linux文件系统第一篇—从Ext2到Ext3再到Ext4 1 概述 Linux继承了UNIX一切皆文件的设计哲学,用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文 ...
- HTML基础第十讲---排版卷标
转自:https://i.cnblogs.com/posts?categoryid=1121494 网页的排版部份也是很重要的一环,有些现成的卷标就可以让您轻易的完成缩排或是一些特殊格式的编排喔! [ ...
- Sql Server服务 远程过程调用失败
问题: 今天SQL数据库登录不上了,然后想启动Sql实例,却发现如下问题(配置环境:win7旗舰版x64,SqlServer2008R2,同时安装VS2012): 以前出现过这个问题,那时候是因为把实 ...
- js常用数据转换&判断
数组转字符串 var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); //"0-1-2-3-4" 字符串转数组 ...