(一一六)新浪微博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 ...
随机推荐
- if 的理解
1. if 实现集合的划分 比如著名的 Prim 算法(最小生成树),从某一确定的点出发,每次新加入的点,都是在已访问过的结点(u∈U)和未访问过(v∈V−U)的结点之间的边.这里的未被访问(V−U) ...
- 19.Node.js EventEmitter
转自:http://www.runoob.com/nodejs/nodejs-tutorial.html Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里 ...
- 通过NFS、FTP、HTTP三种方法安装Redhat Linux (高清版)
本节教程讲述了通过在Red Hat Linux服务器端假设NSF Server来进行Linux系统安装的过程,并详细介绍了如何制作网络启动盘的细节.演示直观,讲解通俗易懂,特别适合初学者学 ...
- php学习笔记3
1.PHP 定界符 EOF 的作用就是按照原样,包括换行格式什么的,输出在其内部的东西: 2.在 PHP 定界符 EOF 中的任何特殊字符都不需要转义: 3.PHP 定界符 EOF
- CISP/CISA 每日一题 14
CISA 每日一题(答) 自动无人值守运行(LIGHTS-OUT)优势:1.信息系统运行成本的遏制/减少:2.持续运行(24/7):3.减少系统错误和中断次数. I/O 控制人员负责保证:1.批处理信 ...
- [React] Render Text Only Components in React 16
In this session we create a comment component to explore how to create components that only render t ...
- C Tricks(十八)—— 整数绝对值的实现
为正还是为负:(对 int 类型而言,第一位为符号位,其余为数值,则右移 31 位,再与 1 求与) 如果为正 ⇒ 返回原值 如果为负 ⇒ 对其二进制形式各位取反 + 1 int abs(int x) ...
- libcurl 通过http协议下载文件并显示下载进度
vc6 测试工程下载地址:http://download.csdn.net/detail/mtour/8068053 代码如下: size_t my_write_func(void *ptr, siz ...
- 含有打印、统计DataGridView(2)
/// <summary> /// 导出数据到Excel /// </summary> public void loa ...
- treap-名次树-树堆
#include <cstring> #include <cstdio> #include <cstdlib> using namespace std; struc ...