概述

在很多社交App手机在手机没有网络时,重新启动应用,依然能否展示上次访问的数据,提高用户体验,这个就是离线数据存储的运用场景。在iOS开发中常见的离线存储技术有Plist存储、个人偏好存储、解归档、CoreData、SQLite。

Plist存储

Plist存储就是将数据写入一个指定沙盒路径的Plist文件中。如果想要更新已经写入Plist文件中的数据需要全部重新写入,因此不适合大量数据存储。并且Plist存储写入的指定类型中的数据Array、 Dictionary、 String、 Boolean、 Date 、Data 、Number

示例:

- (void)plistCache
{
// Plist存储
// 指定写入Plist文件路径 "/Library/Caches"
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
NSLog(@"%@", cachePath); // 字符串写入plist存储
NSString *str = @"123";
[str writeToFile:[cachePath stringByAppendingPathComponent:@"test.plist"] atomically:YES encoding:NSUTF8StringEncoding error:nil]; // 数组写入plist存储
[@[@"jake", @"roes"] writeToFile:[cachePath stringByAppendingPathComponent:@"array.plist"] atomically:YES]; // 字典写入plist存储
NSDictionary *dict = @{@"name":@"jake", @"age":@13, @"height": @1.98};
[dict writeToFile:[cachePath stringByAppendingPathComponent:@"dict.plist"] atomically:YES]; // NSData写入plist存储
NSData *imgData = UIImagePNGRepresentation([UIImage imageNamed:@"timg.jpeg"]);
[imgData writeToFile:[cachePath stringByAppendingPathComponent:@"data.jpeg"] atomically:YES]; }

执行代码,查看沙盒,数据被写入指定的Plist文件中。

偏好设置

偏好设置本质就是Plist存储,系统提供了一个单例NSUserDefaults,每次可以将单个类型value写入沙盒的/Library/Preference目录下的Plist文件中。该Plist命名是应用的Bundle Id。

由于个人偏好设置本质也是Plist存储,因此可以写入数据的基本数据类型只能是Array、 Dictionary、 String、 Boolean、 Date 、Data 、Number

- (void)NSUserDefaultsCache
{
// NSUserDefaults(个人偏好存储)
[[NSUserDefaults standardUserDefaults] setObject:@"jake" forKey:@"name"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"sex"];
[[NSUserDefaults standardUserDefaults] setDouble:1.78 forKey:@"height"];
// 立即同步
[[NSUserDefaults standardUserDefaults] synchronize]; // 移除个人偏好存储plist中的key-value
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"name"]; // 反归档从沙盒获取数据
[NSKeyedUnarchiver unarchiveObjectWithFile:@"name"];
}

在实际的开发中我们可能存储我们自定对象中的数据,这种需求上面的Plist存储和个人偏好设置存储就不能满足需求了,需要用到下面介绍的解归档存储

解归档

解归档就是将遵守NSCoding对象的数据写入指定沙盒路径的二进制文件。如果利用解归档技术将内存中自定义对象中数据写入沙盒指定文件需要先遵守NSCoding协议。

NSCoding协议

这里我定义Person类,实现NSCoding协议,并将Person实例中的数据通过反归档写入沙盒

/***********************************Person.h*********************************************/
#import <Foundation/Foundation.h> @interface Person : NSObject<NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) double height;
@property (nonatomic, assign) BOOL sex;
@end /***********************************Person.m*********************************************/
#import "Person.h" @implementation Person
- (void)encodeWithCoder:(NSCoder *)aCoder
{
// 告诉系统哪些属性需要归档
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeDouble:self.height forKey:@"height"];
[aCoder encodeInt:self.age forKey:@"age"];
[aCoder encodeBool:self.sex forKey:@"sex"];
} - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.height = [aDecoder decodeDoubleForKey:@"height"];
self.age = [aDecoder decodeIntForKey:@"age"];
self.sex = [aDecoder decodeBoolForKey:@"sex"];
}
return self;
} - (NSString *)description
{
NSString *string = [NSString stringWithFormat: @"name=%@, height=%f, age=%d, sex=%d", self.name, self.height, self.age, self.sex];
return string;
} 解归档Person示例
- (void)archiverCache
{
// 获取路径
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; // 归档
// 对于开发中自定义的数据模型的储存,我们可以考虑使用归档储存方案。
Person *p = [[Person alloc] init];
p.name = @"jake";
p.height = 1.78;
p.age = 18;
p.sex = YES;
[NSKeyedArchiver archiveRootObject:p toFile:[cachePath stringByAppendingPathComponent:@"pData"]]; // 返归档从沙盒中取出Person示例对象
id person = [NSKeyedUnarchiver unarchiveObjectWithFile:[cachePath stringByAppendingPathComponent:@"pData"]];
NSLog(@"%@", person);
}

CoreData

CoreData 是一个纯粹面向对象的框架,可以管理实体以及实体之间的关联关系的持久化,也就是我们常说的数据持久化。

但是由于它是一个重量级的数据库管理,产生很多代码量。对于复杂的联合表查询不适用 并且出错不容易解决或找到问题,需要有很深的开发功底。

目前开发一般使用嵌入式数据库SQLite替代。这里就不详细介绍了。

SQLite

SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。

SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。

SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运

SQLite数据类型

SQLite数据类型 对应OC类型
INTEGER 整型
TEXT 文本
REAL 浮点型
BLOB 二进制数据

注意:SQLite这里没有对应OC中的BOOL类型。

SQLite语句

对于SQLite的语句已基本与MySQLite一直,可以参考我的博客MySQL

这里有两点需要注意下,设置主键自动增长使用AUTOINCREMENT,不要使用MySQL的auto_increment带下划线的样式。

SQLite在应用

对于iOS程序使用SQLite苹果提供了静态库

sqlite3提供的接口纯C语言,开发起来比较费劲,一般我们使用GitHub的对其封装的第三方库FMDB

对于FMDB的使用可以参考我简书上的博客FMDB使用

iOS开发系列-常见离线存储方式的更多相关文章

  1. 怎样实现IOS开发中的数据存储方式

    iOS 开发中,一般有如下几种数据存储方式.需要根据具体的业务场景,选择 合适的数据存储方式. (1)  用户默认设置 – 这种情况通常不需要用户干预,如游戏通关信息,Video 播放记录,或者 Ap ...

  2. 【Xamarin 挖墙脚系列:IOS 开发界面的3种方式】

    原文:[Xamarin 挖墙脚系列:IOS 开发界面的3种方式] xcode6进行三种基本的界面布局的方法,分别是手写UI,xib和storyboard.手写UI是最早进行UI界面布局的方法,优点是灵 ...

  3. iOS开发系列--App扩展开发

    概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...

  4. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  5. iOS开发系列--让你的应用“动”起来

    --iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...

  6. iOS开发系列--让你的应用“动”起来

    --iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...

  7. IOS开发系列 --- 核心动画

    原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...

  8. iOS开发系列--让你的应用“动”起来【转载】

    概览 原文链接:http://www.cnblogs.com/kenshincui/p/3972100.html 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...

  9. iOS开发系列之app的一天

    本文主要讲述我对 iOS 开发的一些理解,希望能通过 app 从启动到退出,将一些的知识整合起来,形成一条知识链,目前涉及到的知识点有 runloop.runtime.文件存储.界面布局.离线推送.内 ...

随机推荐

  1. python_way day15 HTML-DAY2、 回顾HTML-CSS 标签(css强制生效),JS(数据类型,时间处理,作用域)

    python_way day15 HTML-DAY2 html-css回顾 javascript 一.html-css回顾 增加默认值: . 强制生效,就算在上面,被覆盖上了也会生效 解决缩小页面混乱 ...

  2. svn 类似.gitignore功能实现

    svn propset -R svn:ignore -F .cvsignore .

  3. CodeForces-1249D2-Too Many Segments (hard version) -STL+贪心

    The only difference between easy and hard versions is constraints. You are given nn segments on the ...

  4. PAT_A1096#Consecutive Factors

    Source: PAT A1096 Consecutive Factors (20 分) Description: Among all the factors of a positive intege ...

  5. HCW 19 Team Round (ICPC format) H Houston, Are You There?(极角排序)

    题目链接:http://codeforces.com/gym/102279/problem/H 大致题意: 你在一个定点,你有个长度为R的钩子,有n个东西在其他点处,问你能勾到的东西的数量是多少? 思 ...

  6. Java服务定位器模式

    当我们想要使用JNDI查找来定位各种服务时,使用服务定位器设计模式. 考虑到为服务查找JNDI的高成本,所以在服务定位器模式使用缓存技术. 首次需要服务时,服务定位器在JNDI中查找并缓存服务对象. ...

  7. ImsConference.java中会议成员更新处理详解

    public class ConferenceParticipant implements Parcelable { //自定义数据结构 private static final String ANO ...

  8. C# Windows服务相关

    代码及注释 ServiceController sc = new ServiceController("gupdatem"); sc.Stop();//停止服务 sc.Start( ...

  9. 2019-7-15-WPF-测试触摸设备发送触摸按下和抬起不成对

    title author date CreateTime categories WPF 测试触摸设备发送触摸按下和抬起不成对 lindexi 2019-7-15 9:3:51 +0800 2019-0 ...

  10. IDEA 创建Spring cloud Eureka 注册中心

    IDEA 创建Spring cloud Eureka 注册中心 一. 首先创建一个maven project Next之后填好groupId与artifactId,Next之后填好项目名与路径,点击F ...