您的位置:首页 > 数据库

iOS数据下载及本地数据库缓存策略

2015-03-19 11:20 267 查看
在移动开发中,数据的下载与缓存是常见的需求。由于需要根据网络状态读取服务器或本地资源,这就涉及到请求与缓存的策略问题。
下面以新闻的下载与缓存为例,需求是用户打开应用从服务器分页加载最新新闻,如果没有网络,则读取本地缓存的新闻。
我的开发思路如下:
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;方法就可以完成请求与缓存工作了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: