I enabled UIFilesharingEnabled option in my app set to true but this was exposes my documents file and my sqlite.db file also.
Then how can restrict on to display/access my database files to user or other apps?
You should take a look at the Library Directory section Apple File System Basics. There you can find all information regarding where to write your app files:
Library
This is the top-level directory for any files that are not user data
files. You typically put files in one of several standard
subdirectories. iOS apps commonly use the Application Support and
Caches subdirectories; however, you can create custom subdirectories.
Use the Library subdirectories for any files you don’t want exposed to
the user. Your app should not use these directories for user data
files. The contents of the Library directory (with the exception of
the Caches subdirectory) are backed up by iTunes and iCloud. For
additional information about the Library directory and its commonly
used subdirectories, see The Library Directory Stores App-Specific
Files.
You can check this post how to access the Library directory in your App Bundle
It could be achieved by using libraryDirectory.
private static var __once: NSString = {
let documentFolderPath = NSSearchPathForDirectoriesInDomains(
.libraryDirectory,
.userDomainMask,
true)[0] as String
let databaseFile = "DATABASE_FILE_NAME"
return "\(documentFolderPath)\(databaseFile)" as NSString
}()
Related
We plan to store the following user files
SQLite file
Image files
Audio files
We also provide an option for users, to upload and download the above files, to a 3rd party cloud storage.
I was wondering, should we use
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
or
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
for the above file storage purpose?
Historically we used the “Documents” folder, but nowadays the “Application Support” directory is the best place for files like this.
The File System Programming Guide says
Put user data in Documents/. User data generally includes any files you might want to expose to the user—anything you might want the user to create, import, delete or edit. For a drawing app, user data includes any graphic files the user might create. For a text editor, it includes the text files. Video and audio apps may even include files that the user has downloaded to watch or listen to later.
Put app-created support files in the Library/Application support/ directory. In general, this directory includes files that the app uses to run but that should remain hidden from the user. This directory can also include data files, configuration files, templates and modified versions of resources loaded from the app bundle.
Remember that files in Documents/ and Application Support/ are backed up by default. You can exclude files from the backup by calling -[NSURL setResourceValue:forKey:error:] using the NSURLIsExcludedFromBackupKey key. Any file that can be re-created or downloaded must be excluded from the backup. This is particularly important for large media files. If your application downloads video or audio files, make sure they are not included in the backup.
Put temporary data in the tmp/ directory. Temporary data comprises any data that you do not need to persist for an extended period of time. Remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device. The system will periodically purge these files when your app is not running; therefore, you cannot rely on these files persisting after your app terminates.
Put data cache files in the Library/Caches/ directory. Cache data can be used for any data that needs to persist longer than temporary data, but not as long as a support file. Generally speaking, the application does not require cache data to operate properly, but it can use cache data to improve performance. Examples of cache data include (but are not limited to) database cache files and transient, downloadable content. Note that the system may delete the Caches/ directory to free up disk space, so your app must be able to re-create or download these files as needed.
Also see the iOS Storage Best Practices video.
If using the .applicationSupportDirectory, I’d suggest you use url(for:in:appropriateFor:create:) with create set to true:
let folderURL = try! FileManager.default
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
It doesn't make much difference which you choose. The chief difference is in case you want to use a file browser or the Files app; they can look in your documents directory but not in your application support directory.
Also if you pick one and release the app and later change your mind, it's easy to migrate and change where the app stores its information.
I'm basically doing variations on this:
let dir = fileManager.url(forUbiquityContainerIdentifier: nil)?
let files = try fileManager.contentsOfDirectory(at: dir)
trying to get to the root (i.e., the "/") of iCloud Drive, where I have some files that aren't in any folder.
However, dir is (expectedly, I guess) my app's folder.
Is it even possible to access the root of iCloud Drive? I mean, users can obviously drop files here, but can I get to that directory? (Note that for the moment I'm trying to avoid using a DocumentPickerViewController.)
It is not possible to access directly files outside of your app's iCloud container. I you want to allow users to give your app access to files that are potentially stored somewhere else, you need to UIDocumentPickerViewController.
More information on iCloud documents can be found here:
https://developer.apple.com/library/content/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForDocumentsIniCloud.html#//apple_ref/doc/uid/TP40012094-CH2-SW1
Basically, I have 2 projects running, one is in obj-c and another is in Swift 4 and I want them to access their directory folder in order to exchange their resources in the run-time. Right now my approach is accessing document directory of Swift 4 project via:
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
so it will generate the path like:
/Users/public1/Library/Developer/CoreSimulator/Devices/22D423BD-C28D-45B7-A976-D9FB02409988/data/Containers/Data/Application/3B15E00A-910B-420E-8047-99F2E6E5013D/Documents
And if I want get the same Documents directory of obj-c project, I will use above path, delete 2 last components path:
/Users/public1/Library/Developer/CoreSimulator/Devices/22D423BD-C28D-45B7-A976-D9FB02409988/data/Containers/Data/Application
then using enumerator.nextObject() to find the flag of obj-c project. It works perfectly fine in simulator but in the device, those code counters a problem is that when running on a device, those folders won't be on the macOS folders but in device folders, so the URLs executes by above code is something like:
/var/mobile/Containers
and I neither can find nor access to that folder so that my enumerator won't work. So is there a way to accessing that folder (using code) or some mechanism to get 2 project folder shared with each other?
=========================================================
EDIT: for using AppGroup I added those code in my Obj-C project:
NSUserDefaults *pathShared = [[NSUserDefaults alloc] nitWithSuiteName:#"com.example.myDomain"];
[pathShared setObject:directoryPath forKey:#"path"];
and in Swift 4 code:
let userDefault = UserDefaults(suiteName: "com.example.myDomain");
let path = userDefault?.object(forKey: "path");
but it didn't seem to work...
A language that you are using to implement application is not a reason. It is just a different applications with different sandboxes. In iOS one application can't get access to files from a sandbox of other application. You can share data between applications by using same AppGroup for the applications, after that you can use shared UserDefaults and write and read files from a shared directory:
<...>
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: #"com.example.domain.MyShareExtension"];
[mySharedDefaults setObject:theAccountName forKey:#"lastAccountName"];
<...>
NSFileManager* fileManager = [[NSFileManager defaultManger];
NSURL* url = [fileManager containerURLForSecurityApplicationGroupIdentifier:[self appContainerName];
<...>
On iOS, the sandbox will prevent your app from accessing any other app's data, even if you developed the other app yourself, too. However, you can set up an App Group and entitle both of your apps to access it, and that will allow you to share what you want. The Sharing Data with Your Containing App heading on this page has a good overview on how to do that
I'm newbee at IOS Developing and just started learning Swift.
In my app I need to store files somewhere...
For example in Android I use assets folder. In IOS I didn't find any way to retrieve folders and files from assets.
Where should I store files to use them when app is running, and how should I get access to them. Also need to get file/folder names
I am not sure you what you mean by "store files", but if you just want to store resource files, like a CSS stylesheet, sound effects etc, you can just drag it into the navigator in Xcode (the left panel). In my project here, I've added a bunch of mp3 files:
To access these files, you can use the Bundle class. It will give you the path to a specific file in string or URL.
For example, if you want to store the text in a text file named text.txt in a string variable:
let contentsOfFile = String(contentsOfFile:
Bundle.main.path(forResource: "text", ofType: "txt")!, encoding: .utf8)
use Bundle. In this way, the file will be packaged into the App
use Sandbox. This way the file is stored on the local disk
I am developing an application which can list the phone files, such as a .pdf. But so far I could only read the files within the application directory.
The following code:
let pathURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let path = pathURL.URLByAppendingPathComponent("file.pdf")
let pathStr = path.path
return pathStr
The above code works, but only for directories within the application directory and I need to read all directories and grab all the .pdf files.
How to get access to all phone directories? For example, read and catch all the .pdf files you have on your phone. If not, please indicate the link where the restriction list.
Due to Apple's sandboxing, you can only read documents in your own app's directory.
From the documentation:
An iOS app’s interactions with the file system are limited mostly to the directories inside the app’s sandbox.