当前位置: 代码迷 >> 综合 >> iOS NSUserDefaults
  详细解决方案

iOS NSUserDefaults

热度:28   发布时间:2024-01-20 19:07:28.0

本文展示如何使用NSUserDefaults类存储和改变应用程序设置。我们将创建Contact应用程序用于存放用户指定的图片和联系人信息。

什么是NSUserDefaults?
NSUserDefaults类用于保存应用程序设置和属性以及用户数据。例如,你可以存储用户在应用程序中使用的图片或默认颜色方案。这些对象存储在iOS所谓的“defaults系统”中。iOS的defaults系统在整个app中都是可用的,因此存放到defaults系统中的数据也是整个应用程序生命周期中可用的。也就是说,无论用户关闭程序还是关机,在用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:

NSData
NSString
NSNumber
NSDate
NSArray
NSDictionary
如果你想保存其他类型,如UIImage,你应该进行编码(即archive),或者将它转换为NSData、NSNumber或者NSString。

现在,我们将通过一个简单的demo,开始学习如何使用defaults系统。

第 1 步: 创建项目
 

新建项目。选择View-based Application ,点击 Next。输入项目名称Contact。输入公司标识,Device Family选择iPhone。点击Next。选择文件保存位置,然后点击Create。

 

第 2 步: 设计界面
在ProjectNavigator的Contact文件夹下,选择ContactViewController.xib。拖入3个UITextFields到画布,如下图所示。拖入一个UIImageView和2个RoundRect Button。

选择第一个TextField,将Placeholder设置为FirstName。将第2个TextField的Placeholder设置为Last Name。将第3个TextField的Placeholder设置为Age,同时将keyboardtype设置为Number Pad。

第1个按钮的text设置为Save,第2个按钮的text设置为ChooseImage。

图片
 

 

现在,我们创建连接。点击Editor中间的按钮,显示Assistanteditor。

选择first name文本框,右键(CTRL+左键)拖到interface声明部分,将弹出一个popup窗口,在name中输入firstNameTextField,然后点击connect。

图片 


以同样的方式为Lastname、Age文本框和UIImageView创建连接,分别是:lastNameTextField、ageTextField和contactImageView。

对于按钮,我们需要创建Action而不是Outlet。从保存按钮右键拖一条线到interface声明部分,但这次我们要拖在花括号以外。将Connection改为Action(不是Outlet)并在name中输入save。同样,为ChooseImage按钮创建Action连接,name为chooseImage。现在,ContactViewController.h代码将如下所示:

 
 #import <UIKit/UIKit.h>

 

@interface ContactViewController : UIViewController {

 

    IBOutlet UIImageView *contactImageView;

    IBOutlet UITextField *firstNameTextField;

    IBOutlet UITextField *lastNameTextField;

    IBOutlet UITextField *ageTextField;

}

 

- (IBAction)save:(id)sender;

- (IBAction)chooseImage:(id)sender;

 

@end
 

接下来,点击Build andRun。输入一些文本并退出程序。如果再次打开程序,你回发现你输入的文本仍然存在。这不过iOS的“多任务”特性而已。如果你从多任务栏中删除程序图标,再次启动程序,你会发现你输入的文本不见了。在本文,我们会使用NSUserDefaults保存你输入的信息,哪怕你“真的”退出了程序。这些数据能够在多个会话中存在。

第 3 步: 挑选图片
返回standardEditor模式,以释放出更多的空间。打开ContactViewController.h,加入UIImagePickerControllerDelegate和UINavigationControllerDelegate协议。

 
 <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
 

打开ContactViewController.m,在chooseImage:方法中加入代码:

 - (IBAction)chooseImage:(id)sender

{

    UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];

    picker.delegate = self;

    picker.allowsEditing = YES;

    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    [self presentModalViewController:picker animated:YES];

}
 

首先,我们创建了一个UIImagePickerController,然后将它的delegate设置为self。然后,我们将“允许用户编辑”属性设置为YES,将UIImagePickerController的源类型设置为照片库。最后,弹出UIImagePickerController。

接下来,我们该实现imagepicker的委托方法


 #pragma mark - Image Picker Delegate

 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo

{

    contactImageView.image = image;

 

    [picker dismissModalViewControllerAnimated:YES];

}

 

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

{

 

    [picker dismissModalViewControllerAnimated:YES];

}
 

第一个方法中,我们将contactImageView的image属性设置为用户所选择的图片并解散UIImageViewController。第二个方法中,我们只是解散UIImageViewController。

第 4 步: 保存数据
保存文本使用setObject:forKey方法。key用于指定保存的文本的索引键,当你取出数据时用这个索引键去检索它。如果保存整数,使用setInteger:forKey方法。对于图片的保存我们需要创建NSData实例。

save方法修改如下:

 
 - (IBAction)save:(id)sender

{

    // Hide the keyboard

    [firstNameTextField resignFirstResponder];

    [lastNameTextField resignFirstResponder];

    [ageTextField resignFirstResponder];

 

    // Create strings and integer to store the text info

    NSString *firstName = [firstNameTextField text];

    NSString *lastName  = [lastNameTextField text];

    int age = [[ageTextField text] integerValue];

 

    // Create instances of NSData

    UIImage *contactImage = contactImageView.image;

    NSData *imageData = UIImageJPEGRepresentation(contactImage, 100);

 

    // Store the data

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

 

    [defaults setObject:firstName forKey:@"firstName"];

    [defaults setObject:lastName forKey:@"lastname"];

    [defaults setInteger:age forKey:@"age"];

    [defaults setObject:imageData forKey:@"image"];

 

    [defaults synchronize];

 

    NSLog(@"Data saved");

}
 

首先,我们将键盘释放。然后创建NSString用于临时保存用户输入的Firstname和Last name文本。对于用户Age文本,我们用一个int保存。对于contactImageView的image,由于不能直接在NSUserDefaults对象中存放UIImage,我们只能使用NSData来储存。然后我们把数据放入NSUserDefaults对象中。最后我们用synchronize方法把数据持久化到standardUserDefaults数据库。

 

第 5 步: 读取数据
最终我们要读取刚才存储的数据。由于viewDidLoad方法在程序启动时会调用,我们选择在这个方法中进行。在viewDidLoad方法,我们修改为如下所示的代码:

 - (void)viewDidLoad

{

    // Get the stored data before the view loads

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

 

    NSString *firstName = [defaults objectForKey:@"firstName"];

    NSString *lastName = [defaults objectForKey:@"lastname"];

 

    int age = [defaults integerForKey:@"age"];

    NSString *ageString = [NSString stringWithFormat:@"%i",age];

 

    NSData *imageData = [defaults dataForKey:@"image"];

    UIImage *contactImage = [UIImage imageWithData:imageData];

 

    // Update the UI elements with the saved data

    firstNameTextField.text = firstName;

    lastNameTextField.text = lastName;

    ageTextField.text = ageString;

    contactImageView.image = contactImage;

 

    [super viewDidLoad];

}
 

首先,我们调用standardUserDefaults方法获得NSUserDefaults。我们把Firstname和Last name读到了NSString中。由于Age是一个整数,我们把它转变为了字符串——因为我们无法直接把int赋值给TextField的text属性。我们把image对象读入到NSData对象,然后用NSData创建一个UIImage。最后,我们用读到的数据更新UI控件的显示内容。整个程序创建完了,再次点击Buildand Run。输入你的信息并挑选一张图片。从多任务栏中关闭程序,然后再次打开它,所有数据将再次被显示。如果一切正常,我们的demo程序就OK了。