Where to store files - ios

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

Related

Unable to Locate Realm File on Device

I am attempting to locate the realm DB file on my device (iPhone) and I followed the steps here and here. However, I do not see any realm files in the folder AppData/Documents.
I print out the URL path as I run the app on my device and my simulator, and this is what I see:
//On device
/private/var/mobile/Containers/Shared/AppGroup/C7332EE4-1567-4C96-8392-7FBD0DC9C863/DB/default.realm
//On simulator
/Users/MYNAME/Library/Developer/CoreSimulator/Devices/D205C50D-F432-4A1F-80CB-FB3D91E0A1EA/data/Containers/Shared/AppGroup/5E67A740-A338-4583-9B9D-461F5D1A734A/DB/default.realm
The URL written on the simulator appears to be any default URL where the Realm DB is written to. I can't seem to understand why can't I find the realm file at AppData/Documents on the actual device.
Realm files are only created on disk when you call Realm() for the first time. Once you've created an instance of Realm, you can find the exact file route of that Realm by printing out realm.configuration.fileURL. You can normally use Realm.Configuration to set a different location of the Realm file on disk as opposed to the Documents directory.
Both of those file paths you displayed show that the file is located in a folder named DB and it appears to be in an app group (eg, a shared folder between apps and extensions) instead of your app's default Documents directory.
So with that being said, it would appear that somewhere in your app, a custom Realm.Configuration object is being used to create the Realm file somewhere else, which would explain why you can't find it in Documents.

How do I put content into the iOS Documents folder at compile time, using Xamarin?

I have a data file that I need to include with my app when I distribute it. When loading any files in the app, I prefix the file name with:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
This works great for anything I create within the app (and for reading back), like files I download in response to a user action. But I can't for the life of me figure out how to place files there when I build my app in Visual Studio.
I've tried making a "Documents" subdirectory in the special "Resources" folder, but that didn't work (I tried setting the "Build Action" to both BundleResource and Content). When I look at the folder for my app (from using the simulator) I can see that in the "Documents" folder there's all the files I downloaded, but I can't find my data file that I'm trying to bundle ahead of time. I even searched my entire hard drive on the Mac and still couldn't find said data file.
The data file isn't an image, if it matters. Just raw binary data. How do I set it up so that this file goes into the proper documents directory at compile time, so that I can read it using the SpecialFolder.MyDocuments prefix? Thanks.
You can't. You can include files in your app bundle, and then at startup copy them from the bundle into a user folder. But this won't happen automatically.

iCloud Drive cannot remove file created from other device

I'm trying to adopt iCloud Drive to store backups of the data of my application using a single file for each backup, if it's relevant they're simple XML files with a custom extension. File creation and upload are working fine but as I'm now trying to let the user manually delete backups I found out that I cannot delete the file programmatically but I can do it if I go to iCloud Drive from the app on iOS or the folder in Finder on macOS.
To save the files I first retrieve the root for the container with
FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
and create the Document folder if it doesn't exists as I want the user to be able to view and edit the files, after creating the file locally in the temporary directory I upload it with
let file = FileManager.default
if file.fileExists(atPath: remotePath.path) {
try? file.removeItem(at: remotePath)
}
try? file.setUbiquitous(true, itemAt: localPath, destinationURL: remotePath)
where remotePath is the path retrieved before with the file name appended. To load the files I use a NSMetadataQuery and get the path of each file with NSMetadataItemURLKey on each returned item, which is working fine but when I attempt to
try? FileManager.default.removeItem(at: retrievedPath)
it works if the same device created the file but if it is from another one it always fail and the error says that the file does not exists at the specified path.
I've removed error handling code for clarity but I've tested this behaviour inspecting the thrown error.
How can I delete any file even from other devices, am I missing some steps?
I was indeed missing something, after reading this question, in particular this answer, I found out that even if the NSMetadataQuery returns the path correctly is possible that the file has not been downloaded to the the device, hence the error.
To correctly delete a file you have to mimic the behaviour of UIDocument and use a NSFileCoordinator on a background queue, refer to the answer referenced before for implementation details.

Store iOS app audio files app in xcassets or documents directory?

If an app requires hundreds of audio files (they're small, 5-25KB), is it better to put them in an asset catalog or the documents directory? I've tried both approaches and they don't seem much different, it's a pain to manage hundreds of files in the project navigator either way and it's the same app filesize for both.
Since you wish to bundle your audio files with your app, you can't use the Documents folder. The use of the Documents folder is a runtime feature than can only be used once your app has been installed from the App Store and run by the user.
To include the files with your app so they exist immediately, they must be part of your app's resource bundle. Whether you use an asset catalog or simply store them in the bundle is up to you, but it's not possible to package them in the Documents folder since there is no Documents folder until the first time the app is run by the user.
So far, I've found one thing that influences whether to "just" put audio files in the app bundle or to put it in the asset catalog portion of the app bundle.
When you put audio files in the asset catalog, it's available as data, there's no URL. As I understand it now, if you want a URL, you'll have to extract the data and create a file, which is double work.
When you have a URL that's available automatically when you "just" put audio files in the app bundle, it gives you more options. Like using AVQueuePlayer with AVPlayerItem. AVPlayerItem only takes a URL, not data. If you wanted to play audio files one after another from the asset catalog, it's more work, you have to write code for AVAudioPlayerDelegate, whereas with AVQueuePlayer, you just provide an array of AVPlayerItems.
I suspect that there may be more advantages having a URL to reference and am not seeing the advantages the asset catalog has yet, so my opinion is subject to change.

What different between store database in different locations in iOS?

I'm working with SQLite.swift.
In the document, the path to the database is:
let path = NSSearchPathForDirectoriesInDomains(
.DocumentDirectory, .UserDomainMask, true
).first!
but i want to import and use an existing database, so i've dragged my existing database to my keyboard extension folder, and create connection to it with path is:
let path = NSBundle.mainBundle().pathForResource("db", ofType:"sqlite3")
So, i've noticed that the first way, the database will be store in /Users/*/Library/Developer/CoreSimulator/Devices/8B1DB861-AA3F-446F-A559-D4727CDB9285/data/Containers/Data/PluginKitPlugin/0BC647E4-26F3-4A1F-8271-CC73C96FD197/Documents
and the second way, the database will be store in the app.
/Users/*/Library/Developer/CoreSimulator/Devices/8B1DB861-AA3F-446F-A559-D4727CDB9285/data/Containers/Bundle/Application/E5D9514C-859A-4D4D-A771-A8CE9CDCD3E7/AppName.app/PlugIns/AppNameExt.appex
What's different between these two locations?
The second way might increase the app size because it contains the database?
And if i want to Archive/Submit my App to the AppStore with existing database, is this the only way?
The main difference is that storing the file in the documents folder means you can write (update) it, which is pretty important for a database file. You cannot write to a file in the app bundle.
The usual pattern for using a database in an app is:
Create a pre-seeded database during development and copy it to the app bundle during building.
When running, check if the database file exists and is up-to-date in the documents folder.
If not, copy it from the app bundle.
Open the database in the documents folder and read/write as desired.

Resources