简体   繁体   中英

Saving NSMutableArray to iPhone device

In the Simulator I can save an NSMutableArray to a file and read it back with the following code:

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:@"RiskValues"]){  // If file exists open into table
        NSLog(@"Risk Values File Exists");
        NSArray *paths = NSSearchPathForDirectoriesInDomains
        (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *fullFileName = [NSString stringWithFormat:@"RiskValues", documentsDirectory];
        gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
        gRiskValuesAlreadyInitialised   = YES;
        } else {    
        NSLog(@"Can't find RiskValues file, so initialising gRiskValues table");            
        Do something else .......
        }       

This doesn't work on the device. I have tried to locate the file using the following but it still doesn't work:

                    NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent@"RiskValues"];

What am I doing wrong?

Great answers from everyone. I have resolved the file path and existence issues at a stroke. Many, many thanks.

You have to provide absolute path here:

if ([fileManager fileExistsAtPath:@"RiskValues"])

So it must look like this:

        NSArray *paths = NSSearchPathForDirectoriesInDomains
        (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:@"RiskValues"];

NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath: fullFileName]){  // If file exists open into table
        NSLog(@"Risk Values File Exists");
        gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
        gRiskValuesAlreadyInitialised   = YES;
        } else {    
        NSLog(@"Can't find RiskValues file, so initialising gRiskValues table");            
        Do something else .......
        } 
NSString *fullFileName = [NSString stringWithFormat:@"RiskValues", documentsDirectory];

this line, you're not creating your full path string right. what you should do is

NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:@"RiskValues"];

also this check

if ([fileManager fileExistsAtPath:@"RiskValues"])

Will never pass on iOS as it is not a full path to any place you are allowed to write at in your sandbox. I suppose it works on the simulator because on the mac it's looking up relatively to the HD root (or something, not sure how the mac file system works :) ), but on the iOS you're going to have to give it a path to a file/directory in your documents (maybe by appending @"RiskValues" to it or whatever)

1) [NSString stringWithFormat:@"RiskValues", documentsDirectory] is just @"RiskValues" . So this name points to file in application's directory.

2) [fileManager fileExistsAtPath:@"RiskValues"] searches for file in application directory. It's available for read/write in simulator (it's in your computer file system after all) but it's read-only on device.

BTW ( NSFileManager Class Reference )

Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior in the case of file system race conditions. It's far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle any error gracefully than it is to try to figure out ahead of time whether the operation will succeed.

Solution:

1) Do not check file presence. Just try to make dictionary with initWithContentsOfFile:encoding:error:

2) You want it to be in documents directory so construct path like this

[documentsDirectory stringByAppendingPathComponent:@"RiskValues"]; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM