Saving Data in iOS | raywenderlich.com

Find out where and how to save data in iOS! This course explores common methods for persisting user data, all from within Xcode Playgrounds.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/5429634-saving-data-in-ios

Hello and thank you very much for your course!

I have a general question regards saved data in iOS that I guess affects many Apps, however I have not seen this topic much discussed anywhere:

If I put a new version of my App to the AppStore and my data model has changed, when would I convert my permanently stored data to the new data model? Would I,

(i) directly after the user has installed the App update, in the background convert all the data to the new data model; so the next time the user opens the App, all data is already converted to the new data model,

or

(ii) convert the data ā€œon demandā€, meaning once the user actually uses the App and opens a document, I would convert the saved data of that specific document to the new data model. And documents he does not open remain in the old data model until he opens them.

Is there some Apple requirements / standard for how one should do this, or is it up to developer choice?

Maybe you have some pointers / keywords where I could start looking for an answer on this issue?

Thank you very much!

1 Like

Thank YOU for taking the time to watch it. I hope youā€™re enjoy it :slight_smile:

An excellent question you bring to us today!

And the answer can be one of the following:

  • Itā€™s up to you
  • It depends, and
  • Whatever you think is best

The reason for that is that there really isnā€™t an Apple guideline or specific pattern we are to follow, which pretty much leaves it up to us. Letā€™s, however, break it down a little bit to see when different scenarios might make more sense.

First, whatever approach we take I might go through the route of either creating a MigrationService class/object, or some sort of extension or wrapper around my model data store or model to actually handle going from one model to the other.

Second, whether you migrate all documents up front or on-demand might come down to: ā€œHow many documents does a user have, how large are they, and how long might a migration take?ā€. If we are talking about 1,000 documents each with a size of 1MB, thatā€™s quite a bit of data to churn through, almost 1GB, and, on an older device like an iPhone 6s or 7, could take a considerable amount of time.

Sticking to this same idea, what are the chances that a user will need to see all 1,000 the next time they open the app? Pretty slim Iā€™d be willing to guess, which makes this a perfect candidate to do it on-demand. I have 1,000 reminder lists (or files/documents in my app sandbox) and I decide to view 5 today. Each time I open one, we spend a few seconds doing the migration to the new model for this file, and voila!

From a user experience perspective you end up with just a few seconds of waiting once per document, no major loading on initial launch after an update, and no need to do it all upfront.

The alternative to this approach would be to do them all up-front the next time you launch the app after an update. When could this be appropriate? Maybe the user just has 10 reminder documents that are 100KB each. Even on an older device doing this migration would take a second or two at most, and you get it out of the door with relative ease.

Finally, still on the second point, there could be scenarios where you need to do this up-front, perhaps from a security perspective, perhaps because you do background processing on these documents or may modify them even without user input (thus needing them up-to-date), or something along those lines.

Third, think about data integrity, and always ensure that whatever approach you take does not put your user data at risk. Any approach with a good user experience is acceptable, even if it takes a little bit of loading time with a spinner or activity indicator on-screen. What is NOT acceptable is losing a userā€™s data, because theyā€™ll lose trust in your product, and may not come back or recommend it.

The fourth and final point is to maybe incorporate some of these questions when coming to the decision-making process:

  1. How many files and what average file size can we expect to work with?
  2. Do users, or us as developers, need everything migrated/converted up-front or can it be done on-demand?
  3. How time consuming is this going to be? What would the user experience look like in either scenario?
  4. How do we ensure the userā€™s data is never at risk?

With those, you can make an informed decision.

One final note Iā€™ll add is that you cannot count on iOS calling your app to run a background process after an app update, on a regular interval, or for sure before the user launches the app the next time. If you code it in a way where the migration will only take place when iOS calls your app for some background task, then you may end up frustrated because it did not happen when you wanted/expected it to.

These are some things I can think of to ensure the decision-making process goes well while also ultimately keeping our focus on the users, and their experience with your app :slight_smile:

I hope this helps, and feel free to ask any further questions or follow ups you may think of.

Thanks again for the time and the excellent question!

Thank you so much for your swift, clear and extensive reply, this really is gold! Following your pointers, I feel now well prepared to tackle this intelligently :slight_smile: :slight_smile: Thank you so much again!!

1 Like

Hello,
I think there is a problem with the didSet in TaskStore.swift
@Published var prioritizedTasks: [PrioritizedTasks] = [
PrioritizedTasks(priority: .high, tasks: []),
PrioritizedTasks(priority: .medium, tasks: []),
PrioritizedTasks(priority: .low, tasks: []),
PrioritizedTasks(priority: .no, tasks: [])
] {
didSet {
saveJSONPrioritizedTasks()
}

didSet does not fire when I add a new task to PrioritizedTasks. On the other hand it fires when the application start and load the datas. I tried with complete material course too (03 - (End) Challenge - Task List) and see the same thing : new tasks never be saved.
I use xCode 11 Swift 5.2.
Thank for your help

Christophe

Thank you for following along with our course and for your question.

See this post in another forum thread here: Challenge: Encoding JSON Arrays | raywenderlich.com - #3 by khuffie

The TL;DR is: Itā€™s a known bug in previous Xcode releases, there is a workaround in that blog post, but Xcode 11.5 should fix that issue. This version came out last week so, if you havenā€™t already, update and give things a try :slight_smile:

Otherwise let me know as it might still be a bug in Xcode 11.5 when it should have been fixed there.

Thanks again :hugs: :smile:

Thanks for your suggestion, weā€™ll definitely keep it in mind for any updates done to the course :slight_smile:

Iā€™m not sure I understood your comment around warnings and updates on using the tutorial. Are you seeing any in particular errors or problems using Xcode 11.6 that youā€™d like to bring to our attention? Running the first few videos in Xcode 11.6 does not yield any errors or problems, nor do the final projects with a more robust codebase.

If there isnā€™t anything specifically called out in the videos, thatā€™s an indication to our viewers and members that this course, and its code, is working as intended with all public releases of Xcode, Swift, iOS, etc. When we do find problems weā€™ll add some notes so viewers can be made aware of any changes since the videos originally came out. :slight_smile:

Checked out my previous posts and my main thought is the transitions are too abrupt. Give a bit more overview. Thatā€™s basically it.

No problem at all.

The team and I definitely appreciate your feedback, and will keep that in mind for future updates to this course, as well as new courses.

Thanks for taking the time to leave us your feedback, and for following along :slight_smile:

Hopefully youā€™re still enjoying the course and finding the contents fun and useful :slight_smile:

Great course, it was exactly what I needed for my project :grinning:

Thank you Felipe!

Youā€™re most welcome. Iā€™m very happy to hear youā€™re enjoying the course :slight_smile:

Take an espresso shot and shout ā€œDeruloā€ every time Felipe says ā€œJSONā€.
Jokes aside, thank you very much for this course. Extremely easy to understand and implement.

Thank YOU! :slight_smile: Very happy to hear weā€™ve been able to help and that youā€™re enjoying the course.

Happy coding! :smiley:

I was scratching my head a bit loading the playgrounds for this course and getting them to output the results as I went through the lessons in Xcode 12.4. It appears that when loading these playground files in this version of Xcode, the results sidebar is not displayed and thereā€™s no ā€˜runā€™ icon at the beginning of each line of code to execute it. I did notice that this course was authored on Xcode 11 version, so Iā€™m guessing this is an incompatibility with playgrounds between versions. Iā€™ve found a good enough workaround in the interim is to open a brand new playground in Xcode 12.4 and then copy the code in the Contents.swift into place. I wanted to share in case anyone else runs into this issue until an update can be made. Otherwise looking forward to learning more about iOS persistence and Data.

2 Likes

Dear Felipe, Saving Data in iOS is a very good course and I learned it twice. I wrote the app - Task List by what I learned in the course. I used the code in the tutorial to encode and decode json data, and I wrote the UI using swiftUI by myself. Just like in the tutorial, I placed the json data in the document folder. I found my codes works well in iOS simulator, but not load task list on the device.
I have to change the load json data path to the Bundle path and run on the device. Then I change the path back to the Document folder path. It will works on the device. Otherwise, task list do not load on the device.

I watch the chapter ā€œSaving on Deviceā€ for several times, but I do not find the solution.
Really hope you can help me. Thanks!

Hi Edward!

This was meant to be used for testing in the simulator in these interim steps of getting things set up.

Further on in the videos, the approach of having to drop files in the correct folder is gone, and a base JSON file is used when the application launches :slight_smile:

At that point, simply running the project on a device or the simulator will yield the expected results.

1 Like

Hi, thank you for this course.
I would like to say an update regarding SwiftUI and AppStorage (and UserDefaults) property wrapper would be a plus.

Hi Felipe,

I think you are doing an amazing job with content and explanations. That being said, I think the audio needs a lot of work.