iOS離線緩衝

來源:互聯網
上載者:User

標籤:

為了節省流量和更好的使用者體驗,目前很多應用都使用本機快取機制,不需要每次開啟app的時候都載入資料,或者重新向伺服器請求資料,因此可以把每次瀏覽的資料儲存到沙箱中,當下次開啟軟體的時候,首先從沙箱載入緩衝的資料,或者當app未連網的時候,從沙箱中載入之前緩衝的舊資料。

離線資料的方法選擇
  1. plist檔案
  2. Document路徑
  3. 資料庫

由於儲存的是大批量資料,且會不停的重新整理新資料,因此應該選擇資料庫來儲存。使用資料庫可以快速地進行資料的讀取操作。

1.設計思路

如,說明了離線緩衝的流程:


離線緩衝
  1. 當第一次開啟app的時候,把從伺服器擷取到的資料儲存到沙箱中;
  2. 當下一次進入app的時候,首先從沙箱中找,如果沙箱中儲存了之前的資料,則顯示沙箱中的資料;
  3. 如果沒有網路,直接載入儲存到沙箱中的資料。
2.實際應用
樣本

下面使用一個樣本程式來介紹離線緩衝。樣本程式用到的架構有FMDB,SDWebImage,AFNetworking,資料是由彙總資料提供的開放API。

JSON返回樣本
{    "resultcode": "200",    "reason": "Success",    "result": {        "data": [            {                "id": "1001",                "title": "糖醋小排",                "tags": "浙菜;熱菜;兒童;酸甜;快手菜",                "imtro": "糖醋小排,我估計愛吃的人太多了,要想做好這道菜,關鍵就是調料汁的配置,老抽不能放的太多,那樣顏色太重, 不好看,調料汁調好後,最好嘗一下,每個人的口味都會不同的,可以適當微調一下哈!",                "ingredients": "肋排,500g",                "burden": "蔥,適量;白芝麻,適量;鹽,3g;生粉,45g;料酒,30ml;雞蛋,1個;蔥,1小段;薑,3片;老抽,7ml;醋,30ml;白糖,20g;番茄醬,15ml;生抽,15ml;生粉,7g;薑,適量",                "albums": [                    "http://img.juhe.cn/cookbook/t/1/1001_253951.jpg"                ],                "steps": [                    {                        "img": "http://img.juhe.cn/cookbook/s/10/1001_40ec58177e146191.jpg",                        "step": "1.排骨剁小塊,用清水反覆清洗,去掉血水"                    },                    {                        "img": "http://img.juhe.cn/cookbook/s/10/1001_034906d012e61fcc.jpg",                        "step": "2.排骨放入容器中,放入醃料,攪拌均勻,醃制5分鐘"                    },                    {                        "img": "http://img.juhe.cn/cookbook/s/10/1001_b04cddaea2a1a604.jpg",                        "step": "3.鍋中放適量油,燒至5成熱,倒入排骨,炸至冒青煙時撈出,關火,等油溫降至五成熱時,開火,再次放入排骨,中火炸至焦黃、熟透撈出"                    },                    {                        "img": "http://img.juhe.cn/cookbook/s/10/1001_56b92264df500f01.jpg",                        "step": "4.鍋中留少許底油,放入蔥花、薑片爆香"                    },                    {                        "img": "http://img.juhe.cn/cookbook/s/10/1001_d78c57536a08dc4b.jpg",                        "step": "5.放入適量炸好的排骨,倒入調料汁,煮至湯汁濃稠時,關火,撒入蔥花、白芝麻點綴即可"                    }                ]            }        ],        "totalNum": 1,        "pn": 0,        "rn": 1    },    "error_code": 0}
在SQLiteManager.m中

單例:

// 單例+(SQLiteManager *)sharedInstance {    @synchronized(self) {        if (shareObj == nil) {            shareObj = [[self alloc] init];        }    }    return shareObj;}

資料庫初始化:

// 初始化資料庫-(instancetype)init {    if (self = [super init]) {        //檔案路徑        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"step.sqlite"];        //初始化資料庫        self.database = [FMDatabase databaseWithPath:path];        //開啟資料庫        [self.database open];        if ([self.database open]) {            //將step採用blob類型來儲存            NSString *create = @"CREATE TABLE IF NOT EXISTS t_step(id integer PRIMARY KEY, step blob NOT NULL);";            [self.database executeUpdate:create];        }    }    return self;}

從資料庫擷取資料:

//從資料庫擷取資料-(NSArray *)stepsFromSqlite {    NSString *sql = @"SELECT * FROM t_step";    FMResultSet *set = [self.database executeQuery:sql];    NSMutableArray *steps = [NSMutableArray array];    while (set.next) {        NSData *data = [set objectForColumnName:@"step"];        Steps *step = [NSKeyedUnarchiver unarchiveObjectWithData:data];        [steps addObject:step];    }    return steps;}

儲存資料到資料庫:

// 儲存資料到資料庫-(void)saveSteps:(Steps *)step {    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:step];    [self.database executeUpdateWithFormat:@"INSERT INTO t_step(step) VALUES (%@);", data];}
MenuTableViewController.m中

擷取伺服器資料:

//擷取伺服器資料-(void)getData {    AFHTTPSessionManager *session = [[AFHTTPSessionManager alloc] init];    NSString *url = @"http://apis.juhe.cn/cook/queryid";    NSMutableDictionary *params = [NSMutableDictionary dictionary];    params[@"id"] = self.menuID;    params[@"key"] = self.appKey;    params[@"dtype"] = self.dtype;    //從資料庫擷取資料    NSArray *steps = [[SQLiteManager sharedInstance] stepsFromSqlite];    if (steps.count) {        self.stepsArray = [NSMutableArray arrayWithArray:steps];    } else {        //get請求,從伺服器擷取資料        [session GET:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {            NSDictionary *result = responseObject[@"result"];            NSArray *data = result[@"data"];            for (NSDictionary *dict in data) {                Menu *menu = [[Menu alloc] initWithDict:dict];                self.stepsArray = menu.steps;            }            [self.tableView reloadData];        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {            NSLog(@"error=%@",error);        }];    }}
3.清除圖片

如:


清除圖片

SDImageCache中提供了擷取當前緩衝大小和清除緩衝的的方法。

MenuTableViewController.m中

擷取當前緩衝大小:

//位元組大小int byteSize = (int)[SDImageCache sharedImageCache].getSize;//M大小CGFloat cacheSize = byteSize / 1000.0 / 1000.0;UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"清理緩衝" message:[NSString stringWithFormat:@"緩衝大小%.1fM",cacheSize] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];[alert show];

清除緩衝:

//清除緩衝[[SDImageCache sharedImageCache] clearDisk];
4.檔案操作

使用SDImageCache可以清除圖片的緩衝,但是有些緩衝並不是圖片緩衝,例如使用者臨時看的視頻檔案或mp3檔案,如果想要清除這些檔案,就要使用檔案操作的方法,遍曆沙箱中的Library/Cache檔案夾,自己算出快取檔案夾的大小,把所有快取檔案清除。

註:檔案夾是沒有大小的,只有檔案有大小屬性。
//計算當前檔案夾的大小-(NSInteger)cachesFileSize {    //檔案管理者    NSFileManager *mgr = [NSFileManager defaultManager];    //判斷是否為檔案    BOOL dir = NO;    BOOL exists = [mgr fileExistsAtPath:self isDirectory:&dir];    if (!exists) return 0;//說明檔案或檔案夾不存在    if (dir) { //self是一個檔案夾        //遍曆caches裡面的內容 -- 直接和間接內容        NSArray *subpaths = [mgr subpathsAtPath:self];        NSInteger totalBytes = 0;        //如果self是一個檔案夾,則遍曆該檔案夾下的檔案        for (NSString *subpath in subpaths) {            //獲得全路徑            NSString *fullpath = [self stringByAppendingPathComponent:subpath];            BOOL directory = NO;            [mgr fileExistsAtPath:fullpath isDirectory:&directory];            if (!directory) { // self不是檔案夾,計算檔案的大小                totalBytes += [[mgr attributesOfItemAtPath:fullpath error:nil][NSFileSize] integerValue];            }        }        return totalBytes;    } else { //self是一個檔案        return [[mgr attributesOfItemAtPath:self error:nil][NSFileSize] integerValue];    }}



文/hrscy(簡書作者)
原文連結:http://www.jianshu.com/p/426c66e46f9e
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

iOS離線緩衝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.