App Updates, NSURL, and Documents Directory
You should use relative URLs to store references to files. The absolute URL is likely to change after an app update
Files Saved During App Updates
When a user downloads an app update,
iTunes installs the update in a new app directory. It then moves the
user’s data files from the old installation over to the new app
directory before deleting the old installation. Files in the following
directories are guaranteed to be preserved during the update process:
- Application_Home/Documents
- Application_Home/Library
Although files
in other user directories may also be moved over, you should not rely
on them being present after an update.
https://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTuning/PerformanceTuning.html
Thx to the sandbox, the application home is also the user home. So it is possible to use the unix tilde which is a short hand to the user home, i.e. ~/Documents
, ~/Library
and so on.
Use -[NSString stringByAbbreviatingWithTildeInPath]
to turn a full path into a relative ~ path. And reverse it with -[NSString stringByExpandingTildeInPath]
.
What happens to files stored in the documents directory when an app is updated?
No, the files will remain.
You can then go ahead and change them as part of the update or just use them like before.
But you should be careful how you reference the saved files, since they will be in a new directory after the update: App Updates, NSURL, and Documents Directory Basically you should only save the relative path from the documents directory, that will remain unchanged as well.
What is the documents directory (NSDocumentDirectory)?
Your app only (on a non-jailbroken device) runs in a "sandboxed" environment. This means that it can only access files and directories within its own contents. For example Documents and Library.
See the iOS Application Programming Guide.
To access the Documents directory of your applications sandbox, you can use the following:
iOS 8 and newer, this is the recommended method
+ (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
if you need to support iOS 7 or earlier
+ (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = paths.firstObject;
return basePath;
}
This Documents directory allows you to store files and subdirectories your app creates or may need.
To access files in the Library directory of your apps sandbox use (in place of paths
above):
[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]
Document directory path change when rebuild application
iOS 8 onwards, Absolute url to app's sandbox changes every time you relaunch the app. Hence you should never save the absolute url of the video. Save the name of the video and recreate the url every time you relaunch the app.
let pathComponent = "pack\(self.packID)-\(selectRow + 1).mp4"
let directoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let folderPath: URL = directoryURL.appendingPathComponent("Downloads", isDirectory: true)
let fileURL: URL = folderPath.appendingPathComponent(pathComponent)
Once you have fileURL
look for the file and you will find the file downloaded in previous launch.
iOS creates a new Sandbox for app every time user launches the app. Hence absolute URL will very. But iOS will take care of setting up all the folders and contents inside the Sandbox as it was earlier. So though base url of SandBox change, relative url's of all the content will be remained intact.
Hence its advised never to save absolute url to any folder :) Hope it helps
Does updating iOS apps delete library directory files?
You should save them in the Documents folder, it is persistent across updates.
Monotouch: documentsDirectory = environment.specialfolder.personal;
Objective-C: NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
Replace File in Documents Directory
You can check if your application is a fresh install or an update from AppDelegate. However, it seems you are not saving your App Version in NSUserDefaults, it will be a bit tricky for you. You save your new version of File.sqlite in Resource and copy it to document directory.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString* curVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
NSString* lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:@"LastVersion"];
if ( lastVersion == nil )
{
//App Installed for the first time. In your case it might be an update because you do not store lastVersion value.
//Reference the path to the documents directory.
NSString *documentDir =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//Get the path of old file.
NSString *filePath = [documentDir stringByAppendingPathComponent:@"File.sqlite"];
if([[NSFileManager defaultManager] fileExistsAtPath: filePath])
{
[fileManager removeItemAtPath:filePath error:&error] //Delete old file
}
//Copy New File.sqlite from Resource Bundle.
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"File" ofType:@"sqlite"];
[fileManager copyItemAtPath:resourcePath toPath:filePath error:&error];
}
else if (![lastVersion isEqual: curVersion])
{
// App is updated. For future Versions you can Update files from here!
}
[[NSUserDefaults standardUserDefaults] setObject:curVersion forKey:@"LastVersion"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Hope this helps!
Related Topics
How to Get a Swift Type Name as a String with Its Namespace (Or Framework Name)
Enable and Debug Zombie Objects in iOS Using Xcode 5.1.1
Xmlparser.Sharedparser.Decode() in Swift3
How to Use Dark Mode in Simulator iOS 13
iOS Multiline Label in Interface Builder
Asset Catalog: Access Images with Same Name in Different Folders
How to Integrate Cocoapods with a Swift Project
iOS Change Navigation Bar Title Font and Color
Uisearchcontroller Persisting After Segue
Block_Release Deallocating UI Objects on a Background Thread
Swift 3 JSON Nsfastenumerationiterator Has No Subscript Members
How to Get a Crash Log Due to Expiration of Provisioning Profile
Add Modal Popup to Map Annotation - Swift 3.0
What Values Should I Use for Cfbundleversion and Cfbundleshortversionstring
Xcode - How to Drag a Component from One View to Another Without Losing Its Frame
Having App Restart Itself When It Detects Change to Privacy Settings