Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ios 8: Bundle path changes

I have an iOS app that stores the absolute path of files in a database and in generated html documents. I just recently updated my iPhone to iOS 8 and now when ever I run the app it seems that the app is installed in a different directory every re-compile. For example on the first build/run [[NSBundle mainBundle] bundlePath] returns something different on the next build/run. What is going on? Is this a new feature of Apple?

Update: A bug report was created

Code example:

If I run the following line over multiple build/runs then I will get a different result each time.

#define kOLD_PATH @"oldPath"
NSString* newPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString* oldPath = [[NSUserDefaults standardUserDefaults] objectForKey:kOLD_PATH];

NSLog(@"New Path: %@", newPath);
NSLog(@"Old Path: %@", oldPath);
NSLog(@"Result: %@", [oldPath isEqualToString:newPath] ? @"Same" : @"Changed");

[[NSUserDefaults standardUserDefaults] setObject:newPath forKey:kOLD_PATH];
[[NSUserDefaults standardUserDefaults] synchronize];

The output looks like this over multiple runs

New Path: /var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library
Old Path: /var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library
Result: Changed

Full Disclosure: In my app the user imports a web page (ePub) that has resources. The resources are stored with the web page. The web page also accesses resources that are part of the app bundle. To achieve this when I load the web page the base url is set to the directory the web page is in and the bundle resources are accessed via absolute file paths. Now that file paths change on every update this is broken. I tried creating symbolic links to the bundle resources but that also fails un subsequent updates.

like image 952
datinc Avatar asked Sep 17 '14 07:09

datinc


2 Answers

Refer Technical Note 2406 by Apple

The breaking change is

Beginning in iOS 8, the Documents and Library directories are no longer siblings of your application's bundle.

Don't store full path/URL to your documents. Store the file name and always generate full path/URL with recommended approach.

Get the DocumentsDirectory URL

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

Then you get path out of url and append the file name to generate full path.

like image 104
MadNik Avatar answered Oct 26 '22 23:10

MadNik


I think the different path for each build and run is the intended way of things happening in iOS simulator. It is not an issue.

/var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library /var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library

I found even if you use the recommended way

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
}

The results are same. Different path for each build & run.

like image 43
arango_86 Avatar answered Oct 26 '22 23:10

arango_86