IOS_数据存取_沙盒+plist+archiver+偏好设置

H:/0723/01_数据存取_Sandbox dir_AppDelegate.h
//
//  AppDelegate.h
//  001.Sandbox Dirs
//
//  Created by liufan on 13-7-22.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

H:/0723/01_数据存取_Sandbox dir_AppDelegate.m
//
//  AppDelegate.m
//  001.Sandbox Dirs
//
//  Created by liufan on 13-7-22.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // 1、获取程序的Home目录
    NSString *home = NSHomeDirectory();
    NSLog(@"应用程序目录:%@", home);
    
    // 2、获取Documents目录
    // NSUserDomainMask 代表从用户文件夹下找
    // YES 代表展开路径中的波浪字符“~”
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 只有一个匹配目录,所以这个集合里面只有一个元素
    NSString *doc = documents[0];
    NSLog(@"文档目录:%@", doc);
    
    // 使用字符串拼接的方式获取目录名
    // 不建议采用,因为新版本的操作系统可能会修改目录名
    NSString *doc2 = [home stringByAppendingPathComponent:@"Documents"];
    NSLog(@"拼接文档目录:%@", doc2);
    
    // 3、获取Cache目录
    NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cache = caches[0];
    NSLog(@"缓存目录:%@", cache);
    
    // 4、获取Tmp目录
    NSString *tmpDir = NSTemporaryDirectory();
    NSLog(@"临时目录:%@", tmpDir);
    
    return YES;
}
							
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

H:/0723/01_数据存取_沙盒目录_MJAppDelegate.h
//
//  MJAppDelegate.h
//  01.沙盒目录
//
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MJAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

H:/0723/01_数据存取_沙盒目录_MJAppDelegate.m
//  MJAppDelegate.m
//  01.沙盒目录
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "MJAppDelegate.h"
@implementation MJAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // 取app所在的主目录,即文件夹名是UUID
    NSString *home = NSHomeDirectory();
    NSLog(@"主目录:%@", home);
    // 取文档目录,第2个参数,代表在用户的范围内,最后一个YES,显示全路径,若写No,则前面的所有用一个波浪号代替~/Documents
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	// 只有一个Documents目录,所数组长度为1
    NSString *docDir = documents[0];
    NSLog(@"文档目录:%@", docDir);
	// 不建议拼接字符串,万一苹果改名了呢?
    NSString *docDir2 = [home stringByAppendingPathComponent:@"Documents"];
    NSLog(@"文档目录2:%@", docDir2);
// [ 左移 ] 右移 Control + I ctrl + T  ctrl+shift + []
    // 取缓存目录
    NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);    
    NSString *cacheDir = caches[0];
    NSLog(@"缓存目录:%@", cacheDir);
    // 取临时目录
    NSString *tmpDir = NSTemporaryDirectory();
    NSLog(@"临时目录:%@", tmpDir);
    return YES;
}














- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

H:/0723/02_数据存取_XML属性列表_MainTableViewController.h
//
//  MainTableViewController.h
//  Plist & Table
//
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MainTableViewController : UITableViewController

@end

H:/0723/02_数据存取_XML属性列表_MainTableViewController.m
//
//  MainTableViewController.m
//  Plist & Table
//
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "MainTableViewController.h"

@interface MainTableViewController ()
{
    // 1. ViewDidLoad New array; 注意判断文件是否已经存在,如果有直接加载,不需要new;
    // 2. 写入Documents目录;
    // 3. 加载到表格;
    // 4. 做一个button,去修改Array内容,并且写入到plist文件;
    // 5. 刷新表格显示。
    NSMutableArray *_dataList;
}
@end

@implementation MainTableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
 
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    NSString *path = [[NSBundle mainBundle]pathForResource:@"users.plist" ofType:nil];
    NSLog(@"path %@", path);
    
    _dataList = [[NSMutableArray alloc]initWithContentsOfFile:path];
    
    [_dataList writeToFile:path atomically:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [_dataList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
    // Configure the cell...
    [cell.textLabel setText:_dataList[indexPath.row][@"userName"]];
    
    return cell;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}

@end

H:/0723/02_数据存取_XML属性列表_users.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>userName</key>
        <string>张三</string>
        <key>age</key>
        <integer>21</integer>
        <key>phone</key>
        <string>110</string>
    </dict>
    <dict>
        <key>userName</key>
        <string>李四</string>
        <key>age</key>
        <integer>25</integer>
        <key>phone</key>
        <string>114</string>
    </dict>
    <dict>
        <key>userName</key>
        <string>王五</string>
        <key>age</key>
        <integer>18</integer>
        <key>phone</key>
        <string>120</string>
    </dict>
    <dict>
        <key>userName</key>
        <string>小芳</string>
        <key>age</key>
        <integer>19</integer>
        <key>phone</key>
        <string>119</string>
    </dict>
</array>
</plist>

H:/0723/02_数据存取_XML属性列表_ViewController.h
//
//  ViewController.h
//  Plist Demo
//
//  Created by liufan on 13-7-22.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>

// 用户姓名
@property (weak, nonatomic) IBOutlet UITextField *userNameText;
// 年龄
@property (weak, nonatomic) IBOutlet UITextField *ageText;
// 手机号码
@property (weak, nonatomic) IBOutlet UITextField *phoneText;
// 用户头像
@property (weak, nonatomic) IBOutlet UIImageView *userImageView;

// 保存用户信息
- (IBAction)saveUserData:(id)sender;
// 读取用户信息
- (IBAction)readUserData:(id)sender;

@end

H:/0723/02_数据存取_XML属性列表_ViewController.m
//
//  ViewController.m
//  Plist Demo
//
//  Created by liufan on 13-7-22.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

// 清空字符串
- (NSString *)trimString:(NSString *)str
{
    return [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - UITextField委托方法
// 键盘焦点切换
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField == self.userNameText) {
        [self.ageText becomeFirstResponder];
    } else if (textField == self.ageText) {
        [self.phoneText becomeFirstResponder];
    } else {
        [textField resignFirstResponder];
    }
    
    return YES;
}

#pragma mark - IBActions
// 保存用户信息
- (IBAction)saveUserData:(id)sender
{
    // 文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = documents[0];
    // 临时目录
    NSString *tmpDir = NSTemporaryDirectory();
    // 缓存目录
    NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cacheDir = caches[0];
    
    /**
     1. NSArray保存至文件
     */
    NSString *arrayFilePath = [docDir stringByAppendingPathComponent:@"arrayFile.txt"];
    // 使用NSArray保存
    NSArray *userArray = @[_userNameText.text, _ageText.text, _phoneText.text];
    // 写入文件
    [userArray writeToFile:arrayFilePath atomically:YES];
    
    /**
     2. NSDictionary保存至文件
     */
    NSString *dictFilePath = [docDir stringByAppendingPathComponent:@"dictFile.txt"];
    // 定义键值数组
    NSArray *keyArray = @[@"姓名", @"年龄", @"电话"];
    // 建立数据字典
    NSDictionary *userDict = [[NSDictionary alloc]initWithObjects:userArray forKeys:keyArray];
    // 写入文件
    [userDict writeToFile:dictFilePath atomically:YES];

    //--------------------------------------------------------------------------
    // NSDictionary演练(2)
    NSString *path = [docDir stringByAppendingPathComponent:@"users.plist"];
    // 将数据封装成字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:_userNameText.text forKey:@"姓名"];
    // 转换年龄数据格式
    NSNumber *age = [NSNumber numberWithInteger:_ageText.text.integerValue];
    [dict setObject:age forKey:@"年龄"];
    [dict setObject:_phoneText.text forKey:@"电话"];
    // 将字典写入users.plist文件
    [dict writeToFile:path atomically:YES];
    
    /**
     3. NSString保存至文件
     */
    // 文件保存路径
    NSString *strPath = [tmpDir stringByAppendingPathComponent:@"strFile.txt"];
    // 写入用户的三个信息
    NSString *content = [NSString stringWithFormat:@"姓名:%@|年龄:%@|电话:%@\n",
                         [self trimString:_userNameText.text],
                         [self trimString:_ageText.text],
                         [self trimString:_phoneText.text]];
    // 使用UTF8格式编码
    [content writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    /**
     4. NSData保存至文件
     */
    // 将图像保存至Documents
//    UIImage *image = [UIImage imageNamed:@"头像1.png"];
    UIImage *image = [_userImageView image];
    // 生成图像数据
    NSData *data = UIImagePNGRepresentation(image);
    // 保存路径
    NSString *dataPath = [cacheDir stringByAppendingPathComponent:@"image1.png"];
    // 将图像数据写入文件
    [data writeToFile:dataPath atomically:YES];
}

// 读取用户信息
- (IBAction)readUserData:(id)sender
{
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = documents[0];
    NSString *path = [docDir stringByAppendingPathComponent:@"users.plist"];
    
    // 将plist文件加载至数据字典
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

    [_userNameText setText:dict[@"姓名"]];
    // 将 NSNumber 转换为 NSString
    [_ageText setText:[dict[@"年龄"]stringValue]];
    [_phoneText setText:dict[@"电话"]];
}

@end

H:/0723/03_数据存取_Archiver & 偏好设置_AppDelegate.m
//
//  AppDelegate.m
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 用户偏好
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    [defaults setObject:@"王二麻子" forKey:@"UserName"];
    [defaults setFloat:18.5 forKey:@"fontSize"];
    [defaults setBool:NO forKey:@"purchased"];
    
    [[NSUserDefaults standardUserDefaults]setObject:@"110" forKey:@"Phone"];
    // 默认不是立即写入,为了数据安全,建议加上同步命令
    [[NSUserDefaults standardUserDefaults]synchronize];
    
    return YES;
}
							
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

H:/0723/03_数据存取_Archiver & 偏好设置_Author.h
//
//  Author.h
//  Archiver Demo
//
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"

@interface Author : Person <NSCoding>

@property (strong, nonatomic) NSString *bookName;

// 工厂方法,初始化用户信息实例
+ (id)initPersonWithName:(NSString *)name
                   image:(UIImage *)image
                     age:(int)age
                   phone:(NSString *)phone
                bookName:(NSString *)bookName;

@end

H:/0723/03_数据存取_Archiver & 偏好设置_Author.m
//
//  Author.m
//  Archiver Demo
//
//  Created by apple on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "Author.h"

@implementation Author

// 工厂方法
+ (id)initPersonWithName:(NSString *)name image:(UIImage *)image age:(int)age phone:(NSString *)phone bookName:(NSString *)bookName
{
    Author *person = [[Author alloc]init];
    
    [person setName:name];
    [person setAge:age];
    [person setPhone:phone];
    [person setUserImage:image];
    [person setBookName:bookName];
    
    return person;
}

// 编码
- (void)encodeWithCoder:(NSCoder *)aCoder
{
	//必须,先调用父类的序列化
    [super encodeWithCoder:aCoder];
    //再执行子类的序列化
    [aCoder encodeObject:_bookName forKey:@"bookName"];
}

// 解码
- (id)initWithCoder:(NSCoder *)aDecoder
{
	//必须,先执行父类的反序列化
    self = [super initWithCoder:aDecoder];
    //再执行子类的反序列化
    if (self) {
        _bookName = [aDecoder decodeObjectForKey:@"bookName"];
    }
    
    return self;
}

@end

H:/0723/03_数据存取_Archiver & 偏好设置_Person.h
//
//  Person.h
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

// 用户姓名
@property (strong, nonatomic) NSString *name;
// 用户头像
@property (strong, nonatomic) UIImage *userImage;
// 年龄
@property (assign, nonatomic) int age;
// 电话
@property (strong, nonatomic) NSString *phone;

// 工厂方法,初始化用户信息实例
+ (id)initPersonWithName:(NSString *)name
                   image:(UIImage *)image
                     age:(int)age
                   phone:(NSString *)phone;


@end

H:/0723/03_数据存取_Archiver & 偏好设置_Person.m
//  Person.m
//  Archiver Demo
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "Person.h"
@implementation Person
// 工厂方法
+ (id)initPersonWithName:(NSString *)name image:(UIImage *)image age:(int)age phone:(NSString *)phone
{
    Person *person = [[Person alloc]init];
    [person setName:name];
    [person setAge:age];
    [person setPhone:phone];
    [person setUserImage:image];
    return person;
}
// 归档 NSCoding协议里面的方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    // 图像数据,不能直接对UIImage进行编码
    NSData *imageData = UIImagePNGRepresentation(_userImage);
    [aCoder encodeObject:imageData forKey:@"imageData"];
	//因为成员变量,年龄是int类型,所以编码Int
    [aCoder encodeInt:_age forKey:@"age"];
    [aCoder encodeObject:_phone forKey:@"phone"];
}
// 恢复 NSCoding协议里面的方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        [self setName:[aDecoder decodeObjectForKey:@"name"]];
        NSData *imageData = [aDecoder decodeObjectForKey:@"imageData"];
        [self setUserImage:[UIImage imageWithData:imageData]];
        [self setAge:[aDecoder decodeIntForKey:@"age"]];
        [self setPhone:[aDecoder decodeObjectForKey:@"phone"]];
    }
    return self;
}
@end

H:/0723/03_数据存取_Archiver & 偏好设置_ViewController.h
//
//  ViewController.h
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>

// 用户姓名
@property (weak, nonatomic) IBOutlet UITextField *userNameText;
// 年龄
@property (weak, nonatomic) IBOutlet UITextField *ageText;
// 手机号码
@property (weak, nonatomic) IBOutlet UITextField *phoneText;
// 用户头像
@property (weak, nonatomic) IBOutlet UIImageView *userImageView;

// 归档用户信息
- (IBAction)archiverPersonInfo:(id)sender;

// 恢复用户信息
- (IBAction)unarchiverPersonInfo:(UIButton *)sender;

@end

H:/0723/03_数据存取_Archiver & 偏好设置_ViewController.m
//  ViewController.m
//  Archiver Demo
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "ViewController.h"
#import "Person.h"
#import "Author.h"
@interface ViewController ()
// 归档多个个人信息
- (void)archiverMultiPersonInfo;
// 使用数组归档多个对象
- (void)archiverMultiPersonWithArray;
@end
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // 获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = documents[0];
    // 完整保存路径
    NSString *path = [docDir stringByAppendingPathComponent:@"array.plist"];
    // 初始化数组
    NSArray *array = @[@"张三", @"李四", @"王五"];
    // 重点!!!!!!!!!!!!归档数组 演练1 键归档 归档根对象: 到文件:
    [NSKeyedArchiver archiveRootObject:array toFile:path];
    // 重点!!!!!!!!!!!! 从文件中,反序列化,生成数组对象
//    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSArray *array1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"%@", array1);
//    Person *person1 = [Person initPersonWithName:@"张三" image:[UIImage imageNamed:@"头像1.png"] age:18 phone:@"110"];
    [self archiverMultiPersonInfo];
    [self archiverMultiPersonWithArray];
	//???????????????NSUserDefaults用户偏好!
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	NSString *userName = [defaults objectForKey:@"UserName"];
    //NSString *userName = [[NSUserDefaults standardUserDefaults]objectForKey:@"UserName"];
    NSLog(@"!!!!!--%@", userName);
}
//触摸事件
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
	//如果点击了头像,换头像
    if ([touch view] == _userImageView) {
        if (_userImageView.tag == 1) {
            [_userImageView setImage:[UIImage imageNamed:@"头像2.png"]];
            [_userImageView setTag:2];
        } else {
            [_userImageView setImage:[UIImage imageNamed:@"头像1.png"]];
            [_userImageView setTag:1];
        }
    }
}
#pragma mark - 键盘切换~~~~~TextField委托方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField == _userNameText) {
        [_ageText becomeFirstResponder];
    } else if (textField == _ageText) {
        [_phoneText becomeFirstResponder];
    } else {
        [_phoneText resignFirstResponder];
    }
    return YES;
}

#pragma mark - IBActions
// 演练2 自定义对象的归档和恢复
// 响应 点击,归档用户信息
- (void)archiverPersonInfo:(id)sender
{
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];
    
    // 新建Person对象
    Person *person = [Person initPersonWithName:_userNameText.text image:_userImageView.image age:_ageText.text.intValue phone:_phoneText.text];
    
    // 归档用户数据,序列化对象到文件
    [NSKeyedArchiver archiveRootObject:person toFile:path];
}

// 响应点击,恢复用户信息
- (void)unarchiverPersonInfo:(UIButton *)sender
{
    // 演练2 自定义对象的归档和恢复
//    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];
//    
//    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
//    
//    [_userNameText setText:person.name];
//    [_ageText setText:[NSString stringWithFormat:@"%d", person.age]];
//    [_phoneText setText:person.phone];
//    [_userImageView setImage:person.userImage];
    
    // 演练3 使用NSData归档多个对象
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo.plist"];
    
    NSData *data = [NSData dataWithContentsOfFile:path];
    // 根据二进制数据,解析成一个NSKeyedUnarchiver对象
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
    // 恢复对象
    Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
    Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
    // 恢复完毕(一定要调用这个方法,如同编码完毕~)
    [unarchiver finishDecoding];
    
    if (sender.tag == 1) {
        [_userNameText setText:person1.name];
        [_ageText setText:[NSString stringWithFormat:@"%d", person1.age]];
        [_phoneText setText:person1.phone];
        [_userImageView setImage:person1.userImage];
    } else {
        [_userNameText setText:person2.name];
        [_ageText setText:[NSString stringWithFormat:@"%d", person2.age]];
        [_phoneText setText:person2.phone];
        [_userImageView setImage:person2.userImage];
    }
    
    // 演练4
    NSString *path2 = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo2.plist"];
    NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
    for (Author *author in array) {
        NSLog(@"%@ %@", author.name, author.bookName);
    }
}

// 自定义方法,归档多个个人信息
- (void)archiverMultiPersonInfo
{
	//获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	//生成绝对路径
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo.plist"];
    Person *person1 = [Person initPersonWithName:@"张三" image:[UIImage imageNamed:@"头像1.png"] age:18 phone:@"110"];
    Person *person2 = [Person initPersonWithName:@"李四" image:[UIImage imageNamed:@"头像2.png"] age:32 phone:@"120"];
    
    // 重点!!!!!新建一块可变的空白二进制数据区
    NSMutableData *data = [NSMutableData data];
    
    // 利用空白的可变二进制数据区生成一个NSKeyedArchiver对象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    
    // 开始利用key,存档对象,存档的数据都会存储到NSMutableData中
    [archiver encodeObject:person1 forKey:@"person1"];
    [archiver encodeObject:person2 forKey:@"person2"];
    
    // 存档完毕(一定要调用这个方法!!!)
    [archiver finishEncoding];
    
    // 最后,将存档的二进制数据写入文件
    [data writeToFile:path atomically:YES];
}

// 使用数组归档多个对象
- (void)archiverMultiPersonWithArray
{
	//获得文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo2.plist"];
    Author *person1 = [Author initPersonWithName:@"张老师" image:[UIImage imageNamed:@"头像1.png"] age:32 phone:@"110" bookName:@"C语言基础"];
    Person *person2 = [Author initPersonWithName:@"李老师" image:[UIImage imageNamed:@"头像2.png"] age:28 phone:@"120" bookName:@"C++入门"];
    NSArray *array = @[person1, person2];
	//直接序列化对象数组,到文件
    [NSKeyedArchiver archiveRootObject:array toFile:path];
}

@end

H:/0723/03_数据存取_Archiver Demo_Author.h
//
//  Author.h
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "Person.h"

@interface Author : Person <NSCoding>

// 书籍名称
@property (strong, nonatomic) NSString *bookName;

// 工厂方法,初始化作者信息实例
+ (id)initPersonWithName:(NSString *)name
                   image:(UIImage *)image
                     age:(int)age
                   phone:(NSString *)phone
                bookName:(NSString *)bookName;

@end

H:/0723/03_数据存取_Archiver Demo_Author.m
//
//  Author.m
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "Author.h"

@implementation Author

// 工厂方法,初始化作者信息实例
+ (id)initPersonWithName:(NSString *)name image:(UIImage *)image age:(int)age phone:(NSString *)phone bookName:(NSString *)bookName
{
    Author *author = [[Author alloc]init];
    
    [author setName:name];
    [author setUserImage:image];
    [author setAge:age];
    [author setPhone:phone];    
    [author setBookName:bookName];
    
    return author;
}

// 归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [super encodeWithCoder:aCoder];
    
    [aCoder encodeObject:_bookName forKey:@"bookName"];
}

// 恢复
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        _bookName = [aDecoder decodeObjectForKey:@"bookName"];
    }
    
    return self;
}

@end

H:/0723/03_数据存取_Archiver Demo_Person.h
//
//  Person.h
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

// 用户姓名
@property (strong, nonatomic) NSString *name;
// 用户头像
@property (strong, nonatomic) UIImage *userImage;
// 年龄
@property (assign, nonatomic) int age;
// 电话
@property (strong, nonatomic) NSString *phone;

// 工厂方法,初始化用户信息实例
+ (id)initPersonWithName:(NSString *)name
                   image:(UIImage *)image
                     age:(int)age
                   phone:(NSString *)phone;

@end

H:/0723/03_数据存取_Archiver Demo_Person.m
//
//  Person.m
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "Person.h"

@implementation Person

// 工厂方法,初始化用户信息实例
+ (id)initPersonWithName:(NSString *)name image:(UIImage *)image age:(int)age phone:(NSString *)phone
{
    Person *person = [[Person alloc]init];
    
    [person setName:name];
    [person setUserImage:image];
    [person setAge:age];
    [person setPhone:phone];

    return person;
}

// 归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    // 图像数据
    NSData *imageData = UIImagePNGRepresentation(_userImage);
    [aCoder encodeObject:imageData forKey:@"imageData"];
    [aCoder encodeInt:_age forKey:@"age"];
    [aCoder encodeObject:_phone forKey:@"phone"];
}

// 恢复
- (id)initWithCoder:(NSCoder *)aDecoder
{
    [self setName:[aDecoder decodeObjectForKey:@"name"]];
    // 图像数据
    NSData *imageData = [aDecoder decodeObjectForKey:@"imageData"];
    [self setUserImage:[UIImage imageWithData:imageData]];
    [self setAge:[aDecoder decodeIntForKey:@"age"]];
    [self setPhone:[aDecoder decodeObjectForKey:@"phone"]];
    
    return self;
}

@end

H:/0723/03_数据存取_Archiver Demo_ViewController.h
//
//  ViewController.h
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>

// 用户姓名
@property (weak, nonatomic) IBOutlet UITextField *userNameText;
// 年龄
@property (weak, nonatomic) IBOutlet UITextField *ageText;
// 手机号码
@property (weak, nonatomic) IBOutlet UITextField *phoneText;
// 用户头像
@property (weak, nonatomic) IBOutlet UIImageView *userImageView;

// 归档用户信息
- (IBAction)archiverPersonInfo:(id)sender;

// 恢复用户信息
- (IBAction)unarchiverPersonInfo:(UIButton *)sender;

@end

H:/0723/03_数据存取_Archiver Demo_ViewController.m
//
//  ViewController.m
//  Archiver Demo
//
//  Created by liufan on 13-7-23.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "ViewController.h"
#import "Person.h"
#import "Author.h"

@interface ViewController ()

// 演练3. 归档多个对象
- (void)archivedMultiObjects;

// 演练4. 使用NSArray归档多个对象
- (void)archivedMultiObjectsWithArray;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    // 获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = documents[0];
    
    // 演练1 NSArray归档
    // 注意,可以通过修改文件名查看归档文件内容
    NSString *path = [docDir stringByAppendingPathComponent:@"array.archive"];
    // 定义数组
    NSArray *array = @[@"张三", @"李四", @"王五"];
    // 归档数组
    [NSKeyedArchiver archiveRootObject:array toFile:path];
    // 恢复数组
    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"%@", unarchivedArray);
    
    // 演练3. 归档多个对象
    [self archivedMultiObjects];
    
    // 演练4. 使用NSArray归档多个对象
    [self archivedMultiObjectsWithArray];
    
    // 写入偏好设置
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:@"itcast.cn" forKey:@"userName"];
    [defaults setFloat:18.0f forKey:@"fontSize"];
    [defaults setBool:YES forKey:@"autoLogin"];
    
    [defaults synchronize];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    
    if ([touch view] == _userImageView) {
        if (_userImageView.tag == 1) {
            [_userImageView setImage:[UIImage imageNamed:@"头像2.png"]];
            [_userImageView setTag:2];
        } else {
            [_userImageView setImage:[UIImage imageNamed:@"头像1.png"]];
            [_userImageView setTag:1];
        }
    }
}

#pragma mark - TextField委托方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField == _userNameText) {
        [_ageText becomeFirstResponder];
    } else if (textField == _ageText) {
        [_phoneText becomeFirstResponder];
    } else {
        [_phoneText resignFirstResponder];
    }
    
    return YES;
}

#pragma mark - IBActions
// 演练2 自定义对象的归档和恢复
// 演练3 使用NSData归档多个对象
// 归档用户信息
- (void)archiverPersonInfo:(id)sender
{
    // 归档文件路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];

    // 新建Person对象
    Person *person = [Person initPersonWithName:_userNameText.text image:_userImageView.image age:_ageText.text.intValue phone:_phoneText.text];

    // 归档用户数据
    [NSKeyedArchiver archiveRootObject:person toFile:path];
}

// 恢复用户信息
- (void)unarchiverPersonInfo:(UIButton *)sender
{
//    // 演练2
//    // 恢复文件路径
//    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];
//
//    // 恢复Person对象
//    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
//
//    [_userNameText setText:person.name];
//    [_userImageView setImage:person.userImage];
//    [_ageText setText:[NSString stringWithFormat:@"%d", person.age]];
//    [_phoneText setText:person.phone];
    // 演练3. 恢复NSData归档的多个数据
    // 获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 存档路径
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers.plist"];
    
    // 演练4. 使用NSArray归档多个对象
    NSString *path2 = [documents[0]stringByAppendingPathComponent:@"multiUsers2.plist"];
    NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
    for (Author *author in array) {
        NSLog(@"%@ %d %@ %@", author.name, author.age, author.phone, author.bookName);
    }

    // 从文件读取数据
    NSData *data = [NSData dataWithContentsOfFile:path];
    // 根据数据,解析成一个NSKeyedUnarchiver对象
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
    // 恢复对象
    Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
    Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
    // 恢复完毕(一定要调用这个方法)
    [unarchiver finishDecoding];

    // 根据按钮Tag设置UI
    if (sender.tag == 0) {
        [_userNameText setText:person1.name];
        [_userImageView setImage:person1.userImage];
        [_ageText setText:[NSString stringWithFormat:@"%d", person1.age]];
        [_phoneText setText:person1.phone];
    } else {
        [_userNameText setText:person2.name];
        [_userImageView setImage:person2.userImage];
        [_ageText setText:[NSString stringWithFormat:@"%d", person2.age]];
        [_phoneText setText:person2.phone];
    }
}

// 演练3. 归档多个对象
- (void)archivedMultiObjects
{
    // 获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 存档路径
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers.plist"];

    Person *person1 = [Person initPersonWithName:@"张三" image:[UIImage imageNamed:@"头像1.png"] age:18 phone:@"110"];
    Person *person2 = [Person initPersonWithName:@"李四" image:[UIImage imageNamed:@"头像2.png"] age:32 phone:@"120"];

    // 新建一块可变的数据区
    NSMutableData *data = [NSMutableData data];
    // 将数据区连接到一个NSKeyedArchiver对象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    // 开始存档对象,存档的数据都会存储到NSMutableData中
    [archiver encodeObject:person1 forKey:@"person1"];
    [archiver encodeObject:person2 forKey:@"person2"];
    // 存档完毕(一定要调用这个方法)
    [archiver finishEncoding];
    // 将存档的数据写入文件
    [data writeToFile:path atomically:YES];
}

// 演练4. 使用NSArray归档多个对象
- (void)archivedMultiObjectsWithArray;
{
    // 获取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // 存档路径
    NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers2.plist"];

    Author *author1 = [Author initPersonWithName:@"张大师" image:[UIImage imageNamed:@"头像1.png"] age:30 phone:@"110" bookName:@"C语言基础"];
    Author *author2 = [Author initPersonWithName:@"张大师" image:[UIImage imageNamed:@"头像1.png"] age:30 phone:@"110" bookName:@"C++宝典"];

    NSArray *array = @[author1, author2];

    // 注意此处不能使用 [array writeToFile:path atomically:YES];
    [NSKeyedArchiver archiveRootObject:array toFile:path];
}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值