2019独角兽企业重金招聘Python工程师标准>>>

之前一篇文章《iOS开发20:使用Settings Bundle为程序添加设置项》中简单介绍了怎样在Settings程序中设置自己的程序,并实现保存,使得下次运行自己的程序时显示的还是上次的设置项。而上一篇文章介绍SandBox时,我们看到其实使用Settings程序设置后,数据是保存在一个plist文件的。

想要永久保存数据,我们当然可以使用plist文件,当退出程序时,我们执行将数据写入plist文件的操作,使用writeToFile:atomically:方法。

具有这个方法的类有:

NSArray
NSMutableArray
NSDictionary
NSMutableDictionary
NSData
NSMutableData
NSString
NSMutableString
NSNumber
NSDate

例如,我们的数据存储在NSArray的一个对象array中,保存数据时执行:

[array writeToFile:filePath atomically:YES];

其中filePath是放在SandBox中的一个plist文件的完整路径。

不过,使用plist文件还是有局限性的,例如,我们不好将一个图片存储在plist中。

这次的小例子中,我们将会通过归档实现数据的保存。当程序运行时,先检查归档文件是否存在,如果存在的话就从归档文件中读取数据显示在界面上;如果归档文件不存在,就使用默认设置。当程序关闭时,会将数据存储在归档文件中,这样下次运行程序时就会显示上次的设置了。

1、运行Xcode 4.3,新建一个Single View Application,名称为:Archiving Test:

然后将准备好的两张图片添加到工程中。

2、先进行界面设计:

单击ViewController.xib,向其中添加控件:

然后向ViewController.h中为控件建立Outlet映射和Action映射,具体是为所有的TextField、ImageView、UISlider控件和UISwitch控件建立Outlet映射,为Button建立Action映射:

3、新建一个类,用于存储我们的数据:

在菜单栏依次选择File — New — File…,在打开的窗口选择Objective-C Class:

单击Next,输入类名:ArchivingData,选择super class为NSObject:

单击Next,选好位置和分组,点击创建,完成类的建立。

4、打开ArchivingData.h,向其中添加属性,以及协议:

#import <Foundation/Foundation.h>@interface ArchivingData : NSObject <NSCoding, NSCopying>@property (copy, nonatomic) UIImage *image;
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *gender;
@property (copy, nonatomic) NSString *vocation;
@property (copy, nonatomic) NSString *page;
@property float theSlider;
@property BOOL isSwitchOn;@end

5、打开ArchivingData.m,向其中添加代码:

5.1 在@implementation之前添加代码:

#define kImageKey @"ImageKey"
#define kNameKey @"NameKey"
#define kGenderKey @"GenderKey"
#define kVocationKey @"VocationKey"
#define kPageKey @"PageKey"
#define kTheSliderKey @"TheSliderKey"
#define kIsSwitchOn @"IsSwitchOnKey"

5.2 在@implementation之后添加代码:

@synthesize image;
@synthesize name;
@synthesize gender;
@synthesize vocation;
@synthesize page;
@synthesize theSlider;
@synthesize isSwitchOn;

5.3 在@end之前添加代码:

#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder {[aCoder encodeObject:image forKey:kImageKey];[aCoder encodeObject:name forKey:kNameKey];[aCoder encodeObject:gender forKey:kGenderKey];[aCoder encodeObject:vocation forKey:kVocationKey];[aCoder encodeObject:page forKey:kPageKey];[aCoder encodeFloat:theSlider forKey:kTheSliderKey];[aCoder encodeBool:isSwitchOn forKey:kIsSwitchOn];}- (id)initWithCoder:(NSCoder *)aDecoder {if (self = [super init]) {image = [aDecoder decodeObjectForKey:kImageKey];name = [aDecoder decodeObjectForKey:kNameKey];gender = [aDecoder decodeObjectForKey:kGenderKey];vocation = [aDecoder decodeObjectForKey:kVocationKey];page = [aDecoder decodeObjectForKey:kPageKey];theSlider = [aDecoder decodeFloatForKey:kTheSliderKey];isSwitchOn = [aDecoder decodeBoolForKey:kIsSwitchOn];}return self;
}

5.4 在@end之前添加代码:

#pragma mark NSCoping
- (id)copyWithZone:(NSZone *)zone {ArchivingData *copy = [[[self class] allocWithZone:zone] init];copy.image = self.image;copy.name = [self.name copyWithZone:zone];copy.gender = [self.gender copyWithZone:zone];copy.vocation = [self.vocation copyWithZone:zone];copy.page = [self.page copyWithZone:zone];copy.theSlider = self.theSlider;copy.isSwitchOn = self.isSwitchOn;return copy;
}

在ArchivingData类中,我们添加了几个属性,这些属性与上面创建的控件是一一对应的。之后实现了几个协议方法,这些方法分别用于编码、解码和复制。

6、打开ViewController.h,向其中添加属性和方法:

@property (copy, nonatomic) NSString *archivingFilePath;- (void)applicationWillResignActive:(NSNotification *)notification;

7、打开ViewController.m,添加代码:

7.1 在@implementation之后添加代码:

@synthesize archivingFilePath;

7.2 在#import之后添加代码:

#import "ArchivingData.h"#define kArchivingFileKey @"archivingFile"
#define kArchivingDataKey @"ArchivingDataKey"

7.3 在viewDidLoad方法中添加代码:

- (void)viewDidLoad
{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentsDirectory = [paths objectAtIndex:0];self.archivingFilePath = [documentsDirectory stringByAppendingPathComponent:kArchivingFileKey];NSFileManager *fileManager = [NSFileManager defaultManager];if ([fileManager fileExistsAtPath:self.archivingFilePath]) {//如果归档文件存在,则读取其中内容,显示在界面上NSData *data = [[NSMutableData alloc] initWithContentsOfFile:self.archivingFilePath];NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];ArchivingData *archivingData = [unarchiver decodeObjectForKey:kArchivingDataKey];[unarchiver finishDecoding];theImageView.image = archivingData.image;nameTextField.text = archivingData.name;genderTextField.text = archivingData.gender;vocationTextField.text = archivingData.vocation;pageTextField.text = archivingData.page;theSlider.value = archivingData.theSlider;theSwitch.on = archivingData.isSwitchOn;} else {//如果归档文件不存在,则设置imageView为boy.pngtheImageView.image = [UIImage imageNamed:@"boy.png"];}//当程序进入后台时,将当前设置项写入归档文件UIApplication *app = [UIApplication sharedApplication];[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(applicationWillResignActive:)name:UIApplicationWillResignActiveNotificationobject:app];
}

7.4 找到switchImage方法,添加代码:

- (IBAction)switchImage:(id)sender {UIImage *image1 = [UIImage imageNamed:@"boy.png"];UIImage *image2 = theImageView.image;if (![image1 isEqual:image2]) {theImageView.image = image1;} else {theImageView.image = [UIImage imageNamed:@"gemini.png"];}
}

7.5 在@end之前添加代码:

//程序进入后台时,保存设置
- (void)applicationWillResignActive:(NSNotification *)notification {ArchivingData *archivingData = [[ArchivingData alloc] init];archivingData.image = self.theImageView.image;archivingData.name = self.nameTextField.text;archivingData.gender = self.genderTextField.text;archivingData.vocation = self.vocationTextField.text;archivingData.page = self.pageTextField.text;archivingData.theSlider = theSlider.value;archivingData.isSwitchOn = theSwitch.on;NSMutableData *data = [[NSMutableData alloc] init];NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];[archiver encodeObject:archivingData forKey:kArchivingDataKey];[archiver finishEncoding];[data writeToFile:self.archivingFilePath atomically:YES];
}

8、最后,为了使得键盘可以关闭,我们还要添加关闭键盘的操作,参考《iOS开发4:关闭键盘》中的第2步。

9、运行程序

刚运行程序如下左图:

  

我们添加一些数据,更换头像,再调整Silder和Switch,如上图右。

之后,按模拟器上的Home建,使得程序在后台运行。

此时,查看程序的SandBox,可以看到程序的Documents目录下出现了文件archivingFile:

之后使用Xcode结束运行,再运行程序。程序第二次运行时,显示如上图左,这说明我们实现了数据的永久存储。

转载于:https://my.oschina.net/plumsoft/blog/57180

iOS开发23:通过归档永久存储数据相关推荐

  1. iOS开发之解析XML格式数据

    XML格式的数据是一种数据的传输格式.因为它方便编写.结构清晰,所以深受程序猿的喜爱,非常多人都喜欢使用XML格式数据传输或者作为程序的配置信息. 如今我将来实如今iOS中解析XML格式数据,语言使用 ...

  2. iOS开发小技巧--边接受数据边写入文件的两种方法

    一.NSFileHanle 使用注意点:在往文件写入数据时,必须创建一个空的文件 指定文件写入的方式 -- 覆盖还是追加 最后记得关闭 <1>代码是在大文件传输的练习中截取的.写入数据之前 ...

  3. 文顶顶iOS开发博客链接整理及部分项目源代码下载

    网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课 ...

  4. iOS开发系列--网络开发(转)

    iOS开发系列--网络开发 2014-10-22 08:34 by KenshinCui, 66365 阅读, 56 评论, 收藏, 编辑 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微 ...

  5. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  6. iOS开发之数据存取

    本文转载至 http://www.cocoachina.com/ios/20141111/10190.html 2014-11-11 13:43 编辑:suiling 分类:iOS开发 来源:崔江涛( ...

  7. iOS开发网络篇—数据缓存

    iOS开发网络篇-数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以 ...

  8. iOS开发简单高效的数据存储

    在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题,你是用什么方法来持久保存数据的?这是在几乎每一次关于iOS技术的交流或讨论都会被提到的问题,而且大家对这个问题的热情持续高涨.本文主要从概 ...

  9. iOS开发——网络使用技术OC篇网络爬虫-使用正则表达式抓取网络数据

    网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...

最新文章

  1. BZOJ4292 : [PA2015]Równanie
  2. 深入理解Binder机制4-bindService过程分析
  3. iOS消息推送机制原理与实现
  4. hdu 1700 (圆的内接三角形 要周长最大)
  5. iOS夯实:RunLoop
  6. 在“软件工程:研究与实践”研讨会上关于UML Use-Case的开放空间讨论
  7. ConcurrentHashMap能完全替代HashTable吗?
  8. POJ1155 TELE(树形DP)
  9. windows安装java环境
  10. 通过curl访问openstack各服务
  11. 如何知道PostgreSQL数据库下每个数据库所对应的目录
  12. openSUSE 安装 Torch
  13. 《MySQL必知必会》学习笔记——第五章(排序检索数据)
  14. 小数形式与科学计数法转换c语言,BUAA小数形式与科学计数法转换(简)
  15. visio画图复制粘贴到word_用VISIO画图 复制完之后粘贴到word中为什么只显示下面一部分?...
  16. 如何使用Xpose绕过APP自定义证书验证去抓Https包
  17. 如何处理图片放大后变模糊的情况?
  18. 阿里云容器镜像加速器
  19. 在VMware WorkStation中安装Windows Server 2016
  20. vite+ts+vue3 知识点(全局组件,局部组件,递归组件)

热门文章

  1. index.html图片弹窗,原生javascript实现图片弹窗交互效果
  2. CTF中遇到不知道文件类型_AE中你不知道的隐藏功能-Mask与特效
  3. mysql 禁止插入重复数据_防止MySQL重复插入数据的三种方法
  4. android给后台传递json,将服务中的JSON数据发送到Android中的UI
  5. 1的阶乘在c语言里咋表示,C语言编程求阶乘1到10并分别显示在屏幕上 – 手机爱问...
  6. class文件打成jar包
  7. python 画系统关联图_Python基于pyecharts实现关联图绘制
  8. anaconda3 win7_重装系统win7
  9. 某网站高度加密混淆的javascript的分析
  10. Hadoop常见异常及其解决方案