问题
I have check the method on the internet, but thats fail to update the data.
In the pickerView:didSelectRow:inComponent method, I tested cameraCode, the key of the array has been changed after I choose different row in pickerView, but the value has not write in my plist file, which is named MultiSetting.plist, even though I write the statement:
path = [[NSBundle mainBundle] pathForResource:@"MultiSetting" ofType:@"plist"];
[settingInfo writeToFile:path atomically:YES];
Is there any can help me to improve my skill?
This is my code:
MultiSettingViewController.h
#import <UIKit/UIKit.h>
@interface MultiSettingViewController : UIViewController
@property (nonatomic) NSInteger *camNum;
@property (nonatomic, retain) IBOutlet UIPickerView *picker;
@property (strong, nonatomic) IBOutlet UITextField *textField;
@property (nonatomic,retain) IBOutlet UISegmentedControl *segmentedControl;
@property (retain, nonatomic) IBOutlet UILabel *regionLabel;
@property (retain, nonatomic) IBOutlet UILabel *placeLabel;
@property (nonatomic, retain) NSArray *placeArray;
@property (strong, nonatomic) NSMutableArray *settingArray;
@property (strong, nonatomic) UIToolbar *doneToolbar;
@property (strong, nonatomic) NSBundle *bundle;
@property (strong, nonatomic) NSString *path;
@property (strong, nonatomic) NSBundle *bundle1;
@property (strong, nonatomic) NSString *path1;
- (IBAction)segmentedControlIndexChanged;
- (void)doneBtn_OnClick:(id)sender;
- (IBAction)textfield_OnClick:(id)sender;
@end
MultiSettingViewController.m
#import "MultiSettingViewController.h"
@implementation MultiSettingViewController
@synthesize camNum, picker, placeArray, settingArray, textField, doneToolbar, segmentedControl, bundle, path, bundle1, path1, regionLabel, placeLabel;
- (void)viewDidLoad{
[super viewDidLoad];
//NSLog(@"%i", camNum);
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"HK" ofType:@"plist"]; placeArray = [[NSArray alloc] initWithContentsOfFile:path];
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"MultiSetting" ofType:@"plist"]; settingArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
if (self.segmentedControl.selectedSegmentIndex == 0){
NSInteger selectedRow = [self.picker selectedRowInComponent:0];
NSDictionary *placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
}
if(self.doneToolbar == nil){
self.doneToolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 40)];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(doneBtn_OnClick:)];
[self.doneToolbar setItems: [NSArray arrayWithObject:doneBtn]];
}
self.textField.inputView = self.picker;
self.textField.inputAccessoryView = self.doneToolbar;
self.textField.delegate = self;
self.picker.delegate = self;
self.picker.dataSource = self;
self.picker.hidden = YES;
self.doneToolbar.barStyle = UIBarStyleBlackTranslucent;
self.doneToolbar.hidden = YES; }
-(IBAction) segmentedControlIndexChanged{
switch (self.segmentedControl.selectedSegmentIndex){
case 0:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"HK" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
NSInteger selectedRow = [self.picker selectedRowInComponent:0];
NSDictionary *placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 1:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"KW" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 2:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"TW" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 3:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"TM" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 4:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"TP" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 5:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"ST" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
case 6:
bundle = [NSBundle mainBundle];
path = [bundle pathForResource:@"LT" ofType:@"plist"];
placeArray = [[NSArray alloc] initWithContentsOfFile:path];
[self.picker reloadAllComponents];
selectedRow = [self.picker selectedRowInComponent:0];
placeInfo = [placeArray objectAtIndex:selectedRow];
[regionLabel setText:[placeInfo objectForKey:@"name"]];
break;
default:
break;
} }
#pragma mark -
#pragma mark UIPickerViewDataSource methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; }
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [placeArray count]; }
#pragma mark -
#pragma mark UIPickerViewDelegate methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component { NSDictionary *placeInfo = [placeArray objectAtIndex:row]; return [placeInfo objectForKey:@"name"]; }
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component { NSDictionary *placeInfo = [placeArray objectAtIndex:row]; NSString *name = [placeInfo objectForKey:@"name"];
self.placeLabel.text = name;
NSString *code = [placeInfo objectForKey:@"cameraCode"];
NSMutableDictionary *settingInfo = [settingArray objectAtIndex:(NSInteger)camNum];
NSLog(@"%@", [settingInfo objectForKey:@"cameraCode"]);
[settingInfo setObject:code forKey:@"cameraCode"];
NSLog(@"%@", [settingInfo objectForKey:@"cameraCode"]);
path = [[NSBundle mainBundle] pathForResource:@"MultiSetting" ofType:@"plist"];
[settingInfo writeToFile:path atomically:YES];
//[self obtainPic:cameraCode];
/*aTimer = [NSTimer scheduledTimerWithTimeInterval:60.0
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:YES];
*/ }
- (void)doneBtn_OnClick:(id)sender{
[self.textField endEditing:YES];
self.picker.hidden = YES;
self.doneToolbar.hidden = YES; }
- (IBAction)textfield_OnClick:(id)sender{
self.picker.hidden = NO;
self.doneToolbar.hidden = NO; }
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
@end
Really thanks for your sincerely help!
回答1:
Everything included in the main bundle is read-only; thus, you might have a Cocoa Error 513 ("The operation couldn’t be completed. Operation not permitted") in your log.
You have three others folders for data storage which are read/write : Temp
, Cache
and Documents
You might create your file MultiSetting.plist
in the Document folder at runtime, then write into it.
You can retrieve the path to the document directory like this :
NSArray * documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDirectory = [documentPath objectAtIndex:0];
Edit
Then, you can copy your pList in there (note that as stated before, it is read-only, so you won't be able to move it nor delete it from your bundle). For this, use NSFileManagers's function -copyItemAtPath :
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error
回答2:
You're trying to write into a file that resides inside the application bundle. This is most certainly not the location for writing user settings to. And iOS won't let you either, as the sandbox blocks application write access to the app bundle.
Use the proper API to get a filesystem location where you can actually write. Documentation is here.
来源:https://stackoverflow.com/questions/17531072/failed-to-write-data-into-plist-file