Q:

What is correct way to store/retrieve user data (read/write files) in iPhone (iOS) dev via Swift?

Background
I've written one particular app via Windows Forms (C#), Android (Java and Kotlin), HTML5 Web App, ElectronJS (runs on Linux, Mac, and Win10) and even as a UWP (Universal Windows Platform) app.
All Use JSON File For Data
All of those apps use the exact same JSON formatted data for user settings. 
That means I can share data on all platforms via the same file and file format. 
On Android there is the additional benefit of having the file saved in the UserPrefs (which provides security and backup for user).
The Problem
I've also written the app as an iPhone/iPad app (Swift), however I cannot find the proper way to handle the JSON file storage.
The problem is not related to de-serializing the JSON into my business object.  That all works fine.  However, I am not sure about:

where should files be stored in the iPhone/iPad system?
can you save a file in some sort of user preference or appdata
location?
How do you open a file for read/write and read/write data? (Swift)
How can I better understand the paths available to read and write
files?

I've searched all over looking for this answer.  Can you point me to official documentation, a book, a StackOverflow item or something that explains this clearly?  (Hopefully with Swift examples.)

A:

See iOS Storage Best Practices video and the File System Basics document. That should get you going.
In short, app data is generally stored in “application support directory”, documents exposed to the user (e.g. the Files app) are stored in “documents” folder, downloads that can be easily re-retrieved are stored in “caches” folder. Technically you could use UserDefaults for storing of this sort of application data, but it really is not intended for this purpose.
Re opening a file for “read/write”, when dealing with JSON, you don’t generally do that. You read the file into a Data and deserialize the JSON into your model objects. 
do {
    let fileURL = try FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("appdata.json")

    let data = try Data(contentsOf: fileURL)
    let appData = try JSONDecoder().decode(AppData.self, from: data)
    // do something with appData
} catch { 
    print(error)
}

When you want to update, you serialize the model objects into a Data containing your JSON and then write it to the file, replacing the file.
do {
    let fileURL = try FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("appdata.json")

    let data = try JSONEncoder().encode(appData)
    try data.write(to: fileURL)
} catch { 
    print(error)
}

Obviously, this assumes that the AppData type (or whatever you call it) conforms to Codable, but you said you were familiar with serialization of JSON. See Encoding and Decoding Custom Types for more information.

