项目中数据缓存以及FMDB的使用

公司项目是用cocospod管理的第三方库:
podfile文件中加入 pod 'FMDB', '~> 2.6.2'引入FMDB就可以使用了

项目是新闻类的app,只有下拉刷新,缓存的思路:

屏幕快照 2016-09-19 下午6.14.22.png

设计NIPNewsDatabase类来管理数据库文件

  • 保存
  • 查找
  • 删除数据库文件

在保存的时候涉及到清除陈旧的数据,清除的思路:

  • 设定缓存的时间长 maxTime
    添加一个存储时间的字段,删除改频道下一周之前的数据
  • 设定缓存的新闻数 dbMaxCount
    计算当前频道下新闻数dbCount,如果dbCount > dbMaxCount,就删除旧的数据

这两种思路,我采用了第二种设定缓存的新闻数目,第一种更简单

NIPNewsDatabase.h


#import <Foundation/Foundation.h>

@interface NIPNewsDatabase : NSObject
/**
 *  保存新闻数据到数据库
 *
 *  @param json       json
 *  @param categoryId 新闻的频道
 */
+ (void)saveData:(NSDictionary *)json categoryId:(NSInteger)categoryId;

/**
 *  根据频道返回新闻数据
 *
 *  @param categoryId 新闻频道
 */
+ (NSArray *)getJsonWithCategoryId:(NSInteger)categoryId;

/**
 *  删除数据库
 */
+ (void)removeDatabase;
@end

NIPNewsDatabase.m

#import "NIPNewsDatabase.h"
#import "FMDB.h"

@implementation NIPNewsDatabase

static FMDatabase *_db;

#define path [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"newsApiResponse.sqlite"]

+ (void)initialize
{
    // 1.打开数据库
    _db = [FMDatabase databaseWithPath:path];
    [_db open];
    
    // 2.创表
    [_db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_newsApiResponse (id integer PRIMARY KEY, newsApiResponse blob NOT NULL, categoryId integer NOT NULL ,time integer NOT NULL);"];
}

+ (NSArray *)getJsonWithCategoryId:(NSInteger)categoryId
{
    NSString * categoryIdStr = [NSString stringWithFormat:@"%ld",(long)categoryId];
    FMResultSet * set = [_db executeQuery:@"SELECT * FROM t_newsApiResponse WHERE categoryId=?;",categoryIdStr];
    NSMutableArray * resultArr = [NSMutableArray array];
    while (set.next) {
        NSData * newsData = [set objectForColumnName:@"newsApiResponse"];
        NSDictionary * result = [NSKeyedUnarchiver unarchiveObjectWithData:newsData];
        [resultArr addObject:result];
    }
    return resultArr;
}

+ (void)saveData:(NSDictionary *)json categoryId:(NSInteger)categoryId
{
    // 1.保存最新的数据
    NSData * newsData = [NSKeyedArchiver archivedDataWithRootObject:json];
    [_db executeUpdateWithFormat:@"INSERT INTO t_newsApiResponse(newsApiResponse, categoryId, time) VALUES (%@, %ld, %@);", newsData, (long)categoryId, @((NSInteger)[[NSDate date] timeIntervalSince1970])];

    // 2.设置最大缓存数;
    int dbMaxCount = 10;
    
    // 3.获得数据库中的条数
    int dbCount = 0;
    NSMutableArray * dbIDs = [NSMutableArray array];
    FMResultSet * set = [_db executeQuery:@"SELECT * FROM t_newsApiResponse WHERE categoryId = ?;",[NSString stringWithFormat:@"%ld",(long)categoryId]];
    while (set.next) {
        dbCount ++;
        int ID = [set intForColumnIndex:0];
        [dbIDs addObject:@(ID)];
    }
    
    // 4.删除多余的数据
    if (dbCount > dbMaxCount) {
        int beyondID = [dbIDs[dbCount-dbMaxCount] intValue];
        NSString * deleteSql = [NSString stringWithFormat:@"DELETE FROM t_newsApiResponse WHERE categoryId = '%ld' AND id < '%d'",categoryId,beyondID];
        if (![_db executeUpdate:deleteSql]) {
            NIPLog(@"数据库删除失败");
        }
    }
}

+ (void)removeDatabase
{
    NSFileManager * fileManager = [[NSFileManager alloc] init];
    [fileManager removeItemAtPath:path error:nil];
}

在VC中

// 从数据中加载数据
- (void)loadDataFromeDB
{
    // 进入界面先从数据库中取数据
    NSArray * responses = [NIPNewsDatabase getJsonWithCategoryId:[self.categoryId integerValue]];
    
    if (responses.count) {
        for (NSDictionary * dict in responses) {
            NSArray<NIPNews *> * array = [NIPNews mj_objectArrayWithKeyValuesArray:dict[@"News"]];
            [self.newsArray addObjectsFromArray:array];
            [self.tableView reloadData];
        }
    }else{ // 数据库中不存在数据,执行网络刷新
        [self.tableView.mj_header beginRefreshing];
    }
}
// 网络请求
- (void)loadNewsData
{
    [NIPHttpManager.tasks makeObjectsPerformSelector:@selector(cancel)];
    
    NSString * urlStr ;
    NSMutableDictionary * param = [NSMutableDictionary dictionary];
    
    if (self.categoryId.intValue == 0 && self.newsArray.count == 0) {
        urlStr = @"News?count=15";
        param = nil;
    }
    
    if (self.categoryId.intValue == 0 && self.newsArray.count) {
        urlStr = @"News?fromUser=true";
        param = nil;
    }
    
    if (self.categoryId.intValue && self.newsArray.count == 0) {
        urlStr = @"News";
        param[@"categoryId"] = self.categoryId;
        param[@"count"] = @(15);
    }
    
    if (self.categoryId.intValue && self.newsArray.count) {
        urlStr = @"News";
        param[@"categoryId"] = self.categoryId;
        param[@"count"] = @(8);
    }
    
    [NIPHttpManager GET:NIPURL(urlStr) parameters:param progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 保存到数据库
        [NIPNewsDatabase saveData:responseObject categoryId:[self.categoryId integerValue]];
        
        NSArray<NIPNews *> * array = [NIPNews mj_objectArrayWithKeyValuesArray:responseObject[@"News"]];
        NSRange range = NSMakeRange(0, array.count);
        NSIndexSet * set = [NSIndexSet indexSetWithIndexesInRange:range];
        [self.newsArray insertObjects:array atIndexes:set];
        [self.tableView reloadData];
        
        [self showNewStatusCount:array.count];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self showNewStatusCount:0];
        [self.tableView.mj_header endRefreshing];
    }];
}

调试用了SimPholder 和 Navicat for SQLite两个软件

realm数据缓存新贵,性能高,操作简单。在json转模型的时候配合使用jsonmodel工具可以将复杂的json(嵌套多层)直接转成realm格式的model类,之前想尝试用realm做缓存的,因为模型都已经建好,不想再按照realm的格式改,所以就继续用了FMDB。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,654评论 4 61
  • 梦想是丰满的,现实是骨感的。餐饮人的舞台越大也意味着风险越大,有无数的暗礁与险滩在等着笑话你,在等着你失败。 这不...
    保尔感悟阅读 4,410评论 0 2
  • 在地铁上,和一个女孩坐得很近。 她长发及腰,不靓丽但让人看着也不烦的那种。 她正啜泣着对电话那端说,“为什么那样对...
    龙少之说阅读 1,706评论 3 5
  • 很多时候,好多事情做起来总比说起来容易得多。就在说起来很简单的语气里,随着年轮的烟波消散了。我们都太年轻,还有很多...
    白色蔷薇香阅读 2,425评论 0 0

友情链接更多精彩内容