Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
So I have a process for a user to take a photo add info and upload to my database. My question is how should I store that data so it is accessible through all my controllers and when they click the upload button it sends the final object to the server to be added to the database. Would I use core data? Or like a struct? I just want to make sure I am doing this correctly.
This is an opinion oriented answer and it is influenced by developer's familiarity/comfort with the various underlying concepts as well. Hence though I dont consider it as an answer here is my opinion.
Should I use core data, so it is accessible through all my controllers?
Absolutely no! U don't need core data, just to create a shared data source which is being used by multiple ViewController's simultaneously. You can obviously create a Singleton data source object and can be accessed by all the VC's.
But then, core data is not just a shared data source isn't it ?
Core data is a Persistent Data Store where as your structs are not.
Assume user takes a pic, and before it gets uploaded quits the app, or you want to provide offline capability to user, where user can take a pic without internet and queue it for upload and whenever internet comes back your app loads it to server, if u use structs and keep data source in memory, if user quits the app all the efforts done by user to will go waste and obviously user will not appreciate it. On the other hand if u use core data you can obviously have it in sqlite file, and then access it whenever u need it even if user quits the app in between :)
Managed Object Context provides performBlock and performBlockAndWait to synchronize the access to core data in multi threaded environment but with a plain array of struct u have to write it on ur own.
Now there is no point in reinventing the wheel isn't it? We all know data types like array are not thread safe :) So is managedObject Context but managedObject context on iOS 5 onwards provides the amazing handy methods like performBlock and performBlockAndWait which eases the life of developer when dealing with shared data source (managedObject) in multi threaded environment.
Managed Object Context provides notifications about the changes happening in real time and works like a charm with NSFetchedResultsController providing a mechanism to constatly monitor and update the data source
I dont think its a big thing, but in order to achieve the same thing with array u'll have to use KVO. But because KVO wont work with swift objects u'll have to override didSet method and manually throw notification to all VC's when data source changes. Not so elegant solution isn't it :)
Scalability and robustness :
Finally, how many records are u dealing with also matters. I have been a part of a company which uploads and restores thousands of images on/from users device. In a scenario where you are dealing with 1000s of images maintaining a array is always a pain and memory print costly as well because the entire array will be loaded all the time. On the other hand NSFetchedResultsController works on page fault mechanism. It loads data efficiently only when needed.
Scalability is just a matter of adding new fields to managed object entity and robustness is directly proportional to you skill set dealing with core data I believe.
Pinch of Advice :
No matter whether u use array of structs or Core Data, always store images in local file system and keep the local path relative reference in your data source. Holding an entire an image in memory is a real bad idea :D
Hope it helps.
Related
This question is not about the technical problem, but rather the approach.
I know two more or less common approaches to store the data received from the server in your app:
1) Using managers, data holders etc to store the data. They are most often some kind of singleton and are used to store the models received from the server. (E.g. - the array of the posts/places/users) Singletons are needed to be able to access the data from any screen. I think the majority of apps uses this approach.
2) Using Core Data (or maybe Realm) as in-memory storage. This approach avoids having singletons, but, I guess, it is a bit more complex (and crash risky) to maintain and support.
How do you store data and why?
P.S. Any answers would help. But big "thank you" for detailed ones, with reasons.
The reason people opt to use Core Data/Relam/Shark or any other iOS ORM is mainly for the purpose of persisting data between runs of the app.
Currently there are two ways of doing this, for single values and very small (not that I encourage it) objects you can use the UserDefaults to persist between app launches. For a approach closer to a database, infact in the case of Core Data and SharkORM, they are built on top of SQLite, you need to use an ORM.
Using a manager to store an array of a data models will only persist said models for the lifetime of the app. For example when the user force quits the app, restarts their device or in some circumstances when iOS terminates your app, all that data will be lost permanently. This is because it is stored in RAM which is volatile memory, rather than in a database on the disk itself.
Using a database layer even if you don't specifically require persistence between launches can have its advantages though; for instance SharkORM allows you to execute raw SQL queries on your objects if you don't want to use the built in powerful query builder. This can be useful to quickly pull the model you are interested in rather than iterating through a local array.
In reply to your question, how do I store data?
Well, I use a combination of all three. Say for instance I called to an API for some data which I wanted to display there and then to the user, I would use a manager instance with an array to hold the data model.
But on the flipside if I wanted to store that data for later or if I needed to execute a complex query on it, I would store it on disk using Shark.
If however I just wanted to store whether or not the user had seen my on boarding flow I would just persist a boolean value into UserDefaults.
I hope this is detailed enough for you.
CoreData isn't strictly "in-memory". You can load objects into your data model and save them into their context, then they might actually be on disk and out of main memory, and they can easily be brought back via fetch requests.
Singletons, on the other hand, do typically stay in main memory all the time until the user terminates the app. If you have larger objects that you are storing in some data structure (e.g. full resolution images when all you really needed was a thumbnail), this can be quite a resource hog.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am working on an application that is dependent on data that should be loaded from our remote servers on the application first launch. Currently I simply fetch data using few different functions and then loading the data into different object arrays. I did some research about preloading data but everything I found has specifically to do with preloading data using CoreData objects. Here are my questions:
Should I load data using CoreData objects? Is it OK to load data into arrays of custom objects?
What are the pros and cons of loading that data into arrays of custom objects?
What are the pros and cons of loading the data into CoreData objects?
How should I get the application to load the data, make sure each function has completed and the data has been loaded before the application moves on with loading the primary view?
Thank you!
Both variants of loading data to CoreData objects and into array of custom objects are ok, but mainly serves different purposes. Storing data using CoreData objects is the most common way of storing persistent data. Thus if you might have to support offline mode work of your application in future, that's the right choice. If you know for sure that your application should work only in case Internet access is available, there is no need to support data persistence and storing data into array of custom objects is absolutely enough.
Talking about data server requests chaining. You can perform synchronous calls in application:didFinishLaunchingWithOptions: method. In such case application will display launch screen while data is loading. But that's probably not the best solution because user might be confused what is happening so long period of time before application actually starts. If I were you I would rather create loading screen with some kind of progress bar that shows user that data is loading and how much data is already loaded. For chaining requests in such controller I would use ReactiveCocoa. You can find an example of how to do so by this link.
Hello I'm using CoreData + MagicalRecord 3 to manage the data in my app. Until then everything was working fine, but then I realize in production than my app is freezing like hell !
So I started to investigate knowing about the fact that to not stuck the UI, it's better to have a main context and a background context and save stuff in background etc...
Nevertheless I have to question due to my setup. I use CoreData in-memory store system (for the best performance) and I don't care about storing the data on disk of my app, I'm fine with a volatile model that will be destroyed when the app is killed or in background for too long. I just want to be able to find my data from any view controller and without coupling.
So I have few questions :
1) If I would use 1 unique context, what would happen if I NEVER save it to the memory store ? For instance if I MR_createEntity then I retrieve this entity from the context and update it, is it updated everywhere or do I have to save it so it can be updated ? In other term was is the interest of saving for in-memory where you don't want to persist the data forever ?
2) If I use 1 unique context that I declare being background, if I display my screen before my data is finished to saved, the screen won't be able to find and display my data right ? Unless I use NSFetchResultController right ?
1) you want to save your data even with an in memory store for a couple of reasons. First, so that you can use core data properly in the case where you might change your mind and persist your data. Second, you'll likely want to access and process some data on different threads/queues. In that case, you'll have to use Core Data's data safety mechanisms for threads/queues. The store is the lowest level at which Core Data will sync data across threads (the old way). This may be less important if you use nested contexts to sync your data (the new way). But even with nested contexts, you'll need call save in order for your changes to merge across contexts. Core Data doesn't really like it when you save to a nil store.
2) You can make and use your own context for displaying data. NSFetchedResultsController does a lot of the leg work in listening for the correct notifications and making sure you're getting very specific updates for the data you asked for in the first place. NSFRC is not always necessary, but will certainly be the easiest way to start.
Within my Swift application, there are two classes that I interact with in almost 75% of the app. One is a set of settings called UserSettings, and the other is called Job. These both are stored in sqllite.
Most of the time it's just reading values already set, and on one areas it also writes. It seems strange to have to keep reinstantiating my settings and job services to communicate with my database to get back to me the same object i'm accessing across the board.
In a case like this, the options to me see to be either
constantly reading/writing to the database, or
do some sort of singleton accessed throughout the entire app.
I'm not sure how much Swift changes anything in terms of arriving at an answer to this question, but I wanted to seek the help of Stack Overflow. How do I set an object that I can access throughout the entire app? Or is it not ideal and instead I need to get it from my db every time?
Thanks so much.
I recommend you to read how core data works, I know you are managing your own store, but the architecture works fine. As a summary you can create a "context object"(this could be your singleton) who interacts with your store (sqlite) creating managed objects, you will work with this objects who are associated with the "context object", and when ever you need to save the changes, you ask the "context object" to write all the managed objects in the store.
Your managed objects need to be only a copy of the "context object" objects, so when you ask to "save" data to the "context object" you only copy back this managed objects. This will help with save multithread coding. (Your context object should work on a serialized queue).
Again this is just a summary, you should read how core data works to get a better picture.
Edit:
Read this blog: http://www.objc.io/issue-4/core-data-overview.html
The difference is that you only need one store and one context object.
I am currently creating an iOS app, which connects to a database and asynchronously downloads a JSON object of data to display in a table view.
As it currently stands, this is an ok way to do it. However, when the database starts getting much larger, this will cause a massive inconvenience. I'm reasonably proficient in Objective-C but not so much in the database side of things. What would be the best way to get this data from the server, and keep it in the app? At the moment, I have a custom class object storing the data for each of the 'objects' in the JSON object. There will however be many other aspects of the app that the database will handle, such as invites, logins and user details.
Would core data be the way to go? I.e duplicating the database (to a certain extent) and storing it locally, then accessing from there. As I said, i'm not really sure which route to take here, so any advice would be real appreciated.
Core location is for handling location (satellite (and wifi) positionning).
I guess you mean Core Data. Core Data is a graph object model which allows you to manipulate data as objects. You don't dig directly into the database, you ask for objects instanciation through predicates (kind of where clause in SQL) and the manipulate the objects.
This stated, it all depends on what is a "big" database. If it's really big you could consider copying locally a part of it and ask for what's remaining from the server through your webservice.
Another question that you could ask yourself is the quantity of data that never change and if your website database and your app database needs to get synchronized (if your website database is always changing then it would be dumb to copy it in your app totally and always synced your app..).
Links :
Introduction to Core Data
Difference between Core Data and a Database (Cocoa With Love)
edit :
A question you can ask yourself is where your data needs to be saved ?
if your app is just for printing 20 cells out of a total of 200 cells then i would go for a total download of your 200 cells. The load of the other cells will be with no delay after first download, especially appreciated if you're using table view cells with reusable cells
is a delay of some seconds acceptable between the 20 first cells and the 20 following ? I think there is no real "good" answer to your question, it depends on many factors (purpose of your app, acceptable time between loads, does the info needs to be modified and saved back to server or locally, what kind of customers, what your app will do with the cells, if you have a database locally will it be totally independant from "mother" database (if no, what kind of synchronization), etc.)
Trying to sum up things according to what I've understood of your needs, I would say that webservices is good if you just need to retrieve info and exploiting it after without saving it back (even if you can do it actually having services allowing you to do it), having a database locally is good if you need your app to be independant from your server in some ways.
Only you has the key to answer all this and take a decision according to your needs and your knowledge of your application and your customers.
Something like JSON or SOAP is the way to go with getting structured data from a web service into objects in your iPhone app.
Storing relational data on the iPhone itself is easy with SQLite. Here's a decent looking tutorial.
Make things easy for yourself by writing a data layer, abstracting away calls to the database, to avoid dotting SQL queries all over your code in places it shouldn't be, like the UI.