I'm new to Core Data, and currently using it to save API server response in an IOS App, using AFNetworking : I have a couple models like Conversations and Messages, I want to allow users to view theirs even if there is no Network.
I was previously using NSObjects and parsing JSON, which was working well.
Does it sound strange to have 2 Objects For the same class : the current NSObject and the equivalent CoreData Managed Object?
With both NSObjects and NSManagedObjects for the same class
With only NSManagedObjects
In the case 2), when using only NSManagedObjects, I have to wait to create and fetch the NSManagedObjects whereas in the case of using both I can do the core data save in the background and don't wait for that save to display it to user.
Any recommendations on which way to go, or any better alternative I did not consider?
NSManagedObject is a subclass of NSObject, so solution 2 is the only way to go.
As for saving, this does not necessarily take much time. Also, if you use a NSFetchedResultsController to display the items, even in-memory changes (before saving the context) will be caught by its delegate methods
Related
I just started working with core data in iOS app dev using swift. The first two things that I encountered are: 1. AppDelegate 2. NSManagedObjectContext.
I understand that 'AppDelegate.swift' file is a source file just like the 'ViewController.swift'. But in all the tutorials it was referred as 'something which will be used later'. Perhaps, now is the time to get familiar with it. Could you kindly tell me what exactly it does?
What does an object of type 'NSManagedObjectContext' do? What is its function? Could you please put its function in simpler words?
Thanks in advance.
Have a look at the following figure for visual understanding of Key objects in an iOS app:
Role of AppDelegate:
The app delegate is the heart of your app code. It handles app initialization, state transitions, and many high-level app events. This object is also the only one guaranteed to be present in every app, so it is often used to set up the app’s initial data structures.
AppDelegate is used for the whole app, you can use it to manage the app life cycle, on the other hand, ViewController is used for a single view. you can use it to manage life cycle of a view. One app can have multiple views. but only one AppDelegate.
Role of NSManagedObjectContext:
The NSManagedObjectContext is a fundamental concept of Core Data.It is like transaction in a relational data. You can fetch objects, you can create objects , update and delete them, save them back to the persistent store, etc. Basically for all the core data operations, you will need to interact with NSManagedObjectContext.
UIApplicationDelegate is an interface between device (the iOS system) and your application. You will i.e. handle push notifications in this class
Context is more complicated. Generally all object that comes from CoreData has some context which is responsible for sync all object in this context. So if you fetch object A and in some other point of code you will fetch again this object (lets call it A2) and both are fetched in the same context then A == A2 is always true. But that's just the tip of the iceberg.
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.
I am writing an app that has a form spread across multiple ViewControllers and a main menu with the submit button on it that opens an e-Mail with the text fields data displayed in it, the only problem i have is that the text boxes don't 'remember' what's been written in them when switching between sections of the form. I have had a look through threads regarding persistent data but have found nothing. I want my application to remember what's been entered in the text fields when switching between views so it can populate the e-Mail with the data but then 'forget' the data again when the user minimises the app. Any advice or pieces of code would be much appreciated.
So create a data model singleton and have your view controllers read/write their values from properties of that singleton.
(In viewWillAppear, fetch a pointer to the model singleton and install values from properties of the singleton into your VC's fields. When the user changes a value in a field, have your VC modify the corresponding property of the singleton.
You can write your singleton to listen for the "will enter background" notification and archive it's settings to disk, and make it's init method try to read saved values from disk (or set the values to a defined starting state if they have never been set). You can use NSUserDefaults, NSCoding, or a variety of other approaches for archiving your data.
There are lots of options to persist data. I currently favoring Realm, but previously I've used Core Data, YapDatabase, and even simply serializing objects to disk. Note that if this is your first foray into saving data on iOS, I strongly advise AVOIDING Core Data, as it is very complex and Feature Rich (also, difficult to use correctly until you know it fluently). I recommend you start with serializing objects yourself, then either Realm or YapDatabase.
You should create a singleton NSObject class and keep data in that class ... As singleton objects hold data until the application is terminated.
I am currently using singleton instances to access and maintain various NSObject in the app.
For instance, I have :
VariableStores, that maintain several objects such as currentUser (custom NSObject), lastLocation (CLLocation), etc.
TaskManager, containing a NSMutableArray of NSOperations that have failed in order to be re-executed later (such as Instagram with failed upload).
If I kill the app, singleton instances are destroyed and :
- some data must be retrieved from the server side (for instance, the currentUser) which increase the length duration
- some data cant be retrieved from the server-side, such as the NSOperation in the TaskManager (as they are only managed locally)
Thus, I would like to go further and maintain that kind of objects even if the app is totally killed.
What should I consider as a good practice? Serializing object into NSUserDefaults and deserialize ? Is there other best practices?
In case of serializion, serializing objects in -applicationWillTerminate delegate and deserializing them in appropriate -init methods of singleton (that are instantiated in the appDidFinishLaunching) can be considered as acceptable ?
the idea of singleton pattern is just to transfer data between controllers without worrying about details ..
what you need to do is a persisting data of your App ..
you can use core data if you see that the data that you need to store is a little big for plists.. or you can use sqlite but that will give you a little pain for writing a lot of sql statements..
or you can use regular plist or nsUserDefaults (i don't like that option) but it's a little slow if the data is too much ..
you can save this data when app go to background or terminated..
I have an NSManagedObject subclass to represent a person on Flickr. I have to grab all the properties to be stored in Core Data of the internet with a URL request. I want to put the functions to grab the data off the web in the Person class. However, the request will be done asynchronously, and the properties will be set on the object in a completion block. Will this cause an error because Core Data is not thread safe?Would it be best to have a seperate class for loading, or would the NSManagedObject Subclass work?
I would put it in a separate class. Not so much for the different threads issue (which is relatively simple to solve by using NSManagedObjectContext's performBlock: method), but for your separation of concerns. The data model should just store the data. It shouldn't have to worry about downloading it. Create a class that downloads the data, and then pass raw data to the NSManagedObject subclass (a method named +objectFromDownloadedData:(NSData *) comes to mind) to create an actual data object that your app can work with.
You could put networking code in an NSManagedObject subclass.
It would be spectacularly poor design to do so, however. Putting networking code in a model class is just terrible app architecture. It could work, but it will be some of the ugliest, most awful code ever seen on iOS.