本文展示如何使用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了。
摘自 kmyhy的專欄