I'm a (kind of) newbie XCode programmer (well, I would say not so newbie nowadays...) and "my pet issue" is: "I'm having trouble saving local files onto my real iPad, compared to saving them with the simulator".
Well to be honest, I have no problem whatsoever SAVING local files, but retrieving them. Why? Because on the simulator my local files seem to persist between compilation sessions, but on the real device, every time the application gets launched (not only after being uploaded from Xcode, but normally launched), data inside the "Documents" directory seems to disappear... So the final user would not be able to store needed historical data between sessions.
Is it a perception of mine? Is it normal behaviour?
The code I use to save this "persistent" data is this one:
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDir = [paths objectAtIndex:0];
NSString *finalPath=[NSString stringWithFormat:@"%@/%@", documentsDir, path];
NSLog(@"Course.m: updatePersistentObject (to disk): final file = %@",finalPath);
[NSKeyedArchiver archiveRootObject:newObject toFile:finalPath];
'path' variable being @".HistoricalTestResults";
The code I use to retrieve data (wheather at boot time, or at runtime) is this one:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@" historical data: Documents paths = %@", paths);
NSString * docsDir = [paths objectAtIndex:0];
NSLog(@"Course.m: loadHistoricalResultsData: docsDir vale [%@]", docsDir);
NSString *tmpPath=[NSString stringWithFormat:@"%@/.HistoricalTestResults", (NSString *)docsDir];
NSLog(@"Course.m: loadHistoricalResultsData: tmpPath vale [%@]", tmpPath);
NSFileManager *localFileManager = [[NSFileManager alloc] init];
// create directory if it doesn't exist, don't do anything if it exists... (?)
[localFileManager createDirectoryAtPath:tmpPath withIntermediateDirectories:YES attributes:nil error:nil];
NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:tmpPath];
NSString *file;
while (file = [ dirEnum nextObject])
{
NSLog(@"Historical Data Folder: %@", file);
if ( [[file pathExtension] compare:@"dat"] == NSOrderedSame )
{
NSString *filePath = [NSString stringWithFormat:@"%@/%@", tmpPath, file];
NSLog(@"Course.m: loadHistoricalResultsData: filePath vale [%@]", filePath);
mHistoricalTestList=[[NSKeyedUnarchiver unarchiveObjectWithFile:filePath] retain];
}
}
[localFileManager release];
My exact problem is that while on the simulator, AT BOOT TIME, if I put a trace on the "while" code line, I can see how the enumerator gets some value, and I can iterate among the found files. On the other hand, when using my iPad, the same breakpoint yields a "nil" pointer when obtaining the enumerator.
As I said, at the beginning of a clean program session, this is normal, so then I need to generate some storable results inside my program memory to store them onto disk. I do it, and then I write them (both inside the simulator and the iPad). Then I can even re-retrieve this data (from disk) and it seems to still exist inside the Documents folder (both onto the iPad and the simulator).
But th开发者_Python百科en, if I close/kill the program, this data seems to be lost onto the real iPad, and to persist in the simulator.
With this behaviour, my only deduction is "Real iPad programs cannot store persistent data onto their Documents directory". Am I right? (Of course not, because I've seen it work on some other programs). So I have the feeling I'm doing something wrong, and after wasting TONS of time trying to find it, I'm now asking for advice on stackoverflow...
Every piece of help/insight/hint will be more than welcome.
Something I can think of is that your app is not being installed on the same app sandbox everytime. That means that while in the simulator your path is the same and the documents dir contains the same data, your ipad creates a new directory path for the installation, therefore the data you persisted in the last session won't be accessible.
Another thing that I experienced, was that the simulator was case insensitive when loading up resources, in contrast with the device that is actually case sensitive. In that time I had a strings file with extension .Strings and the iphone was looking for .strings. The simulator would work but the phone showed the keys when LocalizedString() macro was called.
So, tl;dr: verify the paths are the same in the different sessions, and your file names match.
I hope it helps. good luck!
PS: Gaudí rlz.
I'm happy! I was able to solve my own mess (!!?).
I've discovered that, when I originally copied my 2 code snippets, specially the "read part", I didn't copy it literally as it appears on my actual code, I just adapted some variable names and extra stuff that wasn't important here. (Typical situation)
I even did some more things than "removing some unrelated code pieces", (and here comes the important part), as I reordered some of them. And one of the parts I reordered was this one (which didn't work):
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSString *tmpPath=[NSString stringWithFormat:@"%@/.HistoricalTestResults", (NSString *)docsDir];
NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:tmpPath];
// create directory if it doesn't exist, don't do anything if it exists... (?)
[localFileManager createDirectoryAtPath:tmpPath withIntermediateDirectories:YES attributes:nil error:nil];
which I changed (when posting here), onto this other part (which works):
NSString *tmpPath=[NSString stringWithFormat:@"%@/.HistoricalTestResults", (NSString *)docsDir];
NSFileManager *localFileManager = [[NSFileManager alloc] init];
// create directory if it doesn't exist, don't do anything if it exists... (?)
[localFileManager createDirectoryAtPath:tmpPath withIntermediateDirectories:YES attributes:nil error:nil];
NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:tmpPath];
There's proably some logic behind this, as "why the first part does work on the emulator, but doesn't on the real device". It seems that "createDirectoryAtPath" is somewhat "resetting" some internal stuff, or maybe asking for an enumerator without having created a directory doesn't make sense...
Whatever the case is, I think my experience is worth enough to keep it here posted for someone who might be in my situation in the future!
Greetings again!
精彩评论