iOS数据下载及本地数据库缓存策略
2015-03-19 11:20
267 查看
在移动开发中,数据的下载与缓存是常见的需求。由于需要根据网络状态读取服务器或本地资源,这就涉及到请求与缓存的策略问题。
下面以新闻的下载与缓存为例,需求是用户打开应用从服务器分页加载最新新闻,如果没有网络,则读取本地缓存的新闻。
我的开发思路如下:
1.进入页面优先发送请求,读取最新文章列表。
2.如果有新文章,在页面上显示并将其保存到本地数据库。
3.当请求失败或网络不可用时,读取本地缓存数据。
4.本地缓存数据过多时,将旧数据删除。
代码的实现分为两个部分,一是本地数据库操作,二是网络请求。我在项目中所采用的主要框架是FMDB,AFN,JSONModel。
CREATE TABLE IF NOT EXISTS t_news(id INTEGER PRIMARY KEY AUTOINCREMENT, article_createDate TEXT,article_articleId TEXT ,article_dict blob NOT NULL);
article_createDate是新闻创建时间,article_articleId是服务器上的新闻id,article_dict代表归档后的新闻对象。
//读取文章
+ (NSArray*)selectArticleWithStart:(NSInteger)start
andEnd:(NSInteger)end
{
NSMutableArray *articles = [NSMutableArrayarray];
//查询
FMResultSet *set =nil;
set = [_dbexecuteQuery:@"SELECT * FROM t_news ORDER BY article_createDate
DESC"];
while (set.next) {
NSData *articleDictData = [setobjectForColumnName:@"article_dict"];
NewsReqJSONModel *article = [NSKeyedUnarchiverunarchiveObjectWithData:articleDictData];
// 添加模型到数组中x
[articles addObject:article];
}
//截取文章列表
NSInteger count = articles.count ;
if (start >= count) {
returnnil;
}elseif (end > count){
return [articlessubarrayWithRange:NSMakeRange(start, count - start)];
}else{
return [articlessubarrayWithRange:NSMakeRange(start, end-start)];
}
}
所以保存文章的方法应该有三步。
1).获取数据库已保存的文章id
2).当文章id不在数据库中,则将其保存
3).文章保存完毕后,删除旧文章
//保存新闻数据
+ (void)saveArticleWithArray:(NSArray *)articleArray
{
1).获取数据库已保存的新闻id
NSMutableArray *ids = //SELECT * FROM t_news ORDER BY article_createDate DESC
2).当新闻id不在数据库中,则将其保存
for (NewsReqJSONModel *articlein articleArray) {
if (![idscontainsObject:article.articleId]) {
// 对象序列化成NSData二进制数据
NSData *data = [NSKeyedArchiverarchivedDataWithRootObject:article];
[_dbexecuteUpdate:@"INSERT INTO t_news(article_articleId,article_createDate,,article_dict)
VALUES(? , ?, ?);"
article.articleId,article.createDate,data];
}
}
3).新闻保存完毕后,删除旧新闻,这里我讲缓存的新闻数量设定为50
//DELETE FROM t_news WHERE id NOT IN (SELECT id FROM t_news ORDER BY article_createDate DESC limit 50)
}
1).无网络:从本地数据库读取缓存
2).网络请求成功:展示并存储新闻
3).网络请求失败:读取本地缓存
- (void)newsReqWithStart:(NSInteger)start
andEnd:(NSInteger)end
success:(void (^)(id))success
failure:(void (^)(NSError *,NSArray *array))failure
{
if (!isReached) {
1).无网络:从本地数据库读取缓存
NSArray *cacheNews = //selectArticleWithStart:(NSInteger)start andEnd:(NSInteger)end;
success(cacheNews);
}else{
[HttpToolpost:urlparams:params
success:^(id responseObj) {
2).网络请求成功:展示并存储新闻
NSMutableArray *cacheNews = [NewsReqJSONModelarrayOfModelsFromDictionaries:responseObj];
// 缓存文章字典数组
//saveArticleWithArray:(NSArray *)articleArray;
success(cacheNews);
} failure:^(NSError *error){
//请求失败,从缓存加载数据
NSArray *cacheNews = //selectArticleWithStart:(NSInteger)start andEnd:(NSInteger)end;
failure(error,cacheNews);
}
];
}
}
这样每次只要 每次请求调用
- (void)newsReqWithStart:(NSInteger)start
andEnd:(NSInteger)end
success:(void (^)(id))success
failure:(void (^)(NSError *,NSArray *array))failure;方法就可以完成请求与缓存工作了。
下面以新闻的下载与缓存为例,需求是用户打开应用从服务器分页加载最新新闻,如果没有网络,则读取本地缓存的新闻。
我的开发思路如下:
1.进入页面优先发送请求,读取最新文章列表。
2.如果有新文章,在页面上显示并将其保存到本地数据库。
3.当请求失败或网络不可用时,读取本地缓存数据。
4.本地缓存数据过多时,将旧数据删除。
代码的实现分为两个部分,一是本地数据库操作,二是网络请求。我在项目中所采用的主要框架是FMDB,AFN,JSONModel。
一,数据库操作
1.创建数据库
不同框架采用的创表语句大同小异,建表sql如下:CREATE TABLE IF NOT EXISTS t_news(id INTEGER PRIMARY KEY AUTOINCREMENT, article_createDate TEXT,article_articleId TEXT ,article_dict blob NOT NULL);
article_createDate是新闻创建时间,article_articleId是服务器上的新闻id,article_dict代表归档后的新闻对象。
2.数据库分页读取新闻
将新闻按创建时间降序排序,并根据开始位置和结束位置两个参数截取部分新闻,即可实现分页读取。//读取文章
+ (NSArray*)selectArticleWithStart:(NSInteger)start
andEnd:(NSInteger)end
{
NSMutableArray *articles = [NSMutableArrayarray];
//查询
FMResultSet *set =nil;
set = [_dbexecuteQuery:@"SELECT * FROM t_news ORDER BY article_createDate
DESC"];
while (set.next) {
NSData *articleDictData = [setobjectForColumnName:@"article_dict"];
NewsReqJSONModel *article = [NSKeyedUnarchiverunarchiveObjectWithData:articleDictData];
// 添加模型到数组中x
[articles addObject:article];
}
//截取文章列表
NSInteger count = articles.count ;
if (start >= count) {
returnnil;
}elseif (end > count){
return [articlessubarrayWithRange:NSMakeRange(start, count - start)];
}else{
return [articlessubarrayWithRange:NSMakeRange(start, end-start)];
}
}
3.数据库新闻保存
保存文章时要考虑两点。一是如果数据库中已存在文章将不保存,二是数据库中缓存的文章数量应该是有限的,当新文章保存后,要将旧文章从数据库删除。所以保存文章的方法应该有三步。
1).获取数据库已保存的文章id
2).当文章id不在数据库中,则将其保存
3).文章保存完毕后,删除旧文章
//保存新闻数据
+ (void)saveArticleWithArray:(NSArray *)articleArray
{
1).获取数据库已保存的新闻id
NSMutableArray *ids = //SELECT * FROM t_news ORDER BY article_createDate DESC
2).当新闻id不在数据库中,则将其保存
for (NewsReqJSONModel *articlein articleArray) {
if (![idscontainsObject:article.articleId]) {
// 对象序列化成NSData二进制数据
NSData *data = [NSKeyedArchiverarchivedDataWithRootObject:article];
[_dbexecuteUpdate:@"INSERT INTO t_news(article_articleId,article_createDate,,article_dict)
VALUES(? , ?, ?);"
article.articleId,article.createDate,data];
}
}
3).新闻保存完毕后,删除旧新闻,这里我讲缓存的新闻数量设定为50
//DELETE FROM t_news WHERE id NOT IN (SELECT id FROM t_news ORDER BY article_createDate DESC limit 50)
}
二,网络请求
网络请求有三种情况1).无网络:从本地数据库读取缓存
2).网络请求成功:展示并存储新闻
3).网络请求失败:读取本地缓存
- (void)newsReqWithStart:(NSInteger)start
andEnd:(NSInteger)end
success:(void (^)(id))success
failure:(void (^)(NSError *,NSArray *array))failure
{
if (!isReached) {
1).无网络:从本地数据库读取缓存
NSArray *cacheNews = //selectArticleWithStart:(NSInteger)start andEnd:(NSInteger)end;
success(cacheNews);
}else{
[HttpToolpost:urlparams:params
success:^(id responseObj) {
2).网络请求成功:展示并存储新闻
NSMutableArray *cacheNews = [NewsReqJSONModelarrayOfModelsFromDictionaries:responseObj];
// 缓存文章字典数组
//saveArticleWithArray:(NSArray *)articleArray;
success(cacheNews);
} failure:^(NSError *error){
//请求失败,从缓存加载数据
NSArray *cacheNews = //selectArticleWithStart:(NSInteger)start andEnd:(NSInteger)end;
failure(error,cacheNews);
}
];
}
}
这样每次只要 每次请求调用
- (void)newsReqWithStart:(NSInteger)start
andEnd:(NSInteger)end
success:(void (^)(id))success
failure:(void (^)(NSError *,NSArray *array))failure;方法就可以完成请求与缓存工作了。
相关文章推荐
- javascript数据缓存策略之本地存储
- ADO.NET访问数据-(2) DataSet本地缓存与数据库的交互过程,以及应用
- java、Extjs导出数据库里的数据至Excel并下载至本地进行数据备份方法之二——使用Action
- iOS 【Multithreading-多图下载数据展示案例(二级缓存)/模拟SDWebImage内部实现】
- iOS开发------实现图片下载缓存到本地
- 【Java】数据库查询的数据直接以指定文件类型下载到本地(弹出下载框)
- iOS本地缓存数据方式有五种
- iOS中,关于UIWebView网页数据本地缓存原理和实际使用。
- iOS - LocalCache 本地数据缓存
- iOS 本地缓存 归档数据模型化 .m
- iOS开发本地缓存(数据离线缓存、读取、释放)
- iOS开发本地缓存(数据离线缓存、读取、释放)
- iOS基础8:自定义MyData/自定义SQLite用于网络判断,版本判断,图片缓存处理,下载或者上传的GET或POST请求,加密手段,.数据解析
- iOS五种本地缓存数据方式
- ADO.NET访问数据-(2) DataSet本地缓存与数据库的交互过程,以及应用
- java、Extjs导出数据库里的数据至Excel并下载至本地进行数据备份方法之一——使用servlet
- ios 手动清除本地沙盒中的缓存数据
- iOS开发 数据缓存-数据库
- iOS本地缓存数据方式有五种
- iOS开发本地缓存(数据离线缓存、读取、释放)