I think this is a common scenario.
I'm defining class models of my app, I will use Core Data for caching so I would like to take advantage of the NSManagedObject generated subclass to "reuse" it as a model to pass to different classes.
Is that advisable?
Let's say I get some data from the network I want to build an object model with same instance variables as the Core Data model generated, use it when needed and maybe cache it on the DB.
What is the common approach there?
Can I use a category on Core Data model?
Core Data subclass? Encapsulation? New class ?
Thanks for any tips on that.
Core Data is not, at its heart, a database, but rather an object graph manager.
In many scenarios, it is a very good idea to handle your objects with Core Data, and you can use a fast in-memory store.
In a way, I think that by attempting NOT to use Core Data to handle your objects, you are destined to re-implement a lot of its functionality. Just use it.
You say that you are downloading a JSON that represents a given item; and you're using this item in your views, and then persisting it in a database. Core Data excels at this; take advantage of its full set of features instead of trying to avoid it.
(And, again, using mogenerator will be very helpful, although it is certainly not required).
Matt Gallagher has a nice blog article about the differences between Core Data and a database - I suggest that you read it, it's valuable information.
Cocoa With Love: The differences between Core Data and a Database
Related
I'm trying to figure out how to use Core Data in my App. I already have in mind what the object graph would be like at runtime:
An Account object owns a TransactionList object.
A TransactionList object contains all the transactions of the account. Rather than being a flat list, it organizes transactions per day. So it contains a list of DailyTransactions objects sorted by date.
A DailyTransactions contains a list of Transaction objects which occur in a single day.
At first I thought Core Data was an ORM so I thought I might just need two tables: Account table and Transaction table which contained all transactions and set up the above object graph (i.e., organizing transactions per date and generating DailyTransactions objects, etc.) using application code at run time.
When I started to learn Core Data, however, I realized Core Data was more of an object graph manager than an ORM. So I'm thinking about using Core Data to implement above runtime object relationship directly (it's not clear to me what's the benefit but I believe Core Data must have some features that will be helpful).
So I'm thinking about a data model in Core Data like the following:
Acount <--> TransactionList -->> DailyTransactions -->> Transaction
Since I'm still learning Core Data, I'm not able to verify the design yet. I suppose this is the right way to use Core Data. But doesn't this put too many implementation details, instead of raw data, in persistent store? The issue with saving implementation details, I think, is that they are far more complex than raw data and they may contain duplicate data. To put it in another way, what exactly does the "data" in data model means, raw data or any useful runtime objects?
An alternative approach is to use Core Data as ORM by defining a data model like:
Account <-->> Transactions
and setting up the runtime object graph using application code. This leads to more complex application code but simpler database design (I understand user doesn't need to deal with database directly when using Core Data, but still it's good to have a simpler system). That said, I doubt this is not the right way to use Cord Data.
A more general question. I did little database programming before, but I had the impression that there was usually a business object layer above plain old data object layer in server side programming framework like J2EE. In those architectures, objects that encapsulate application business are not same as the objects loaded from database. It seems that's not the case with Core Data?
Thanks for any explanations or suggestions in advance.
(Note: the example above is an simplification. A transaction like transfer involves two accounts. I ignore that detail for simplification.)
Now that I read more about the Core Data, I'll try to answer my own question since no one did it. I hope this may help other people who have the same confusion as I did. Note the answer is based on my current (limited) understanding.
1. Core Data is an object graph manager for data to be persistently stored
There are a lot articles on the net emphasizing that Core Data manages object graph and it's not an ORM or database. While they might be technically correct, they unfortunately cause confusion to beginner like me. In my opinion, it's equally important to point out that objects managed by Core Data are not arbitrary runtime objects but those that are suitable for being saved in database. By suitable it means all these objects conform to principles of database schema design.
So, what' a proper data model is very much a database design question (it's important to point out this because most articles try to ask their readers to forget about database).
For example, in the account and transactions example I gave above, while I'd like to organize transactions per day (e,g., putting them in a two-level list, first by date, then by transaction timestamp) at runtime. But the best practice in database design is to save all transactions in a single table and generating the two-level list at runtime using application code (I believe so).
So the data model in Core Data should be like:
Account <->> Transaction
The question left is where I can add the code to generate the runtime structure (e.g., two-level list) I'd like to have. I think it's to extend Account class.
2. Constraints of Core Data
The fact that Core Data is designed to work with database (see 1) explains why it has some constraints on the data model design (i.e., attribute can't be of an arbitrary type, etc.).
While I don't see anyone mentioned this on the net, personally I think relationship in Core Data is quite limited. It can't be of a custom type (e.g, class) but has to be a variable (to-one) or an array (to-many) at run time. That makes it far less expressive. Note: I guess it's so due to some technical reason. I just hope it could be a class and hence more flexible.
For example, in my App I actually have complex logic between Account and its Transaction and want to encapsulate it into a single class. So I'm thinking to introduce an entity to represent the relationship explicitly:
Account <->> AccountTranstionMap <-> Transaction
I know it's odd to do this in Core Data. I'll see how it works and update the answer when I finish my app. If someone knows a better way to not do this, please let me know!
3. Benefits of Core Data
If one is writing a simple App, (for example, an App that data modal change are driven by user and hence occurs in sequence and don't have asynchronous data change from iCloud), I think it's OK to ignore all the discussions about object graph vs ORM, etc. and just use the basic features of Core Data.
From the documents I have read so far (there are still a lot I haven't finished), the benefits of Core Data includes automatic mutual reference establishment and clean up, live and automatically updated relationship property value, undo, etc. But if your App is not complex, it might be easier to implement these features using application code.
That said, it's interesting to learn a new technology which has limitation but at the same time can be very powerful in more complex situations. BTW, just curious, is there similar framework like Core Data on other platforms (either open source or commercial)? I don't think I read about similar things before.
I'll leave the question open for other answers and comments :) I'll update my answer when I have more practical experience with Core Data.
i am new to this Core data. When i search for tutorials, I'm seeing this sentence Core Data is not a database everywhere on the internet.
If it is not a database, why are we using it as a database?
For what purpose Core Data is initially created?
Is there any other way Core Data was used before/will be used in
future (Other than as a DB)?
Sorry for my English.
Thanks for the time.. (:
Actually Core Data is a bridge between the code and the underlying database (like SQLite or XML...). Core Data is not a database, but uses SQLite (or XML...) for persistence. The main purpose of Core Data is to manage memory objects and object graphs easily without having to do it manually through a SQLite library for instance. It is possible to use Core Data without persistence is you want (using In-Memory stores).
Here is the documentation : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/index.html#//apple_ref/doc/uid/TP40001075-CH2-SW1
Bye!
If it is not a database, why are we using it as a database?
"We" are not necessarily doing so, depending on who you mean by "we". Core Data can be used in a database-like manner, keeping in mind the Core Data vs. SQL differences others have noted. But that's not the only possible use.
Statements that Core Data isn't a database are mostly intended to prevent people from thinking of Core Data in the same sense as SQL. That sort of thinking leads to badly designed data models, since the approach is different. It can be used as a database in the generic sense of the storing structured data but it's important to not assume that it works like other databases you may have used.
For what purpose Core Data is initially created?
Is there any other way Core Data was used before/will be used in future (Other than as a DB)?
Core Data was created to fill what might have been perceived as a missing piece in Apple's frameworks. They generally take the MVC approach. There were classes to help in designing and implementing views (in these pre-iOS days that meant AppKit) and with controller classes (for example NSArrayController, also an OS X class). But model support was limited to NSCoding, which required a lot of repetitive code. Custom solutions also had trouble scaling to large amounts of data-- for example NSCoding doesn't help you load only part of a large document graph, because it recursively works its way through the entire object hierarchy.
Core Data was added with the purpose of making it easier to design and implement the model layer of an app. It's no accident that the document you edit to design the data is called a data model and not a schema.
The idea was (and is) that you could
Design your data model visually in Xcode
Create and use instances of your model objects
Read and save those objects in a file
...all without ever needing to write your own code to figure out how to convert your model objects to and from something that could be written into a file, or with the mechanics of opening a file, reading/writing it, and saving it. You'd just create objects as needed and then call save on NSManagedObjectContext. The small bit of code that was concerned with locating and opening the file was all pretty much the same in any app, so while it was still required it was mostly no longer the app developer's concern (and in iOS 10, NSPersistentContainer eliminates even this). You'd also get the benefit of only needing to load the parts of your object graph that you currently needed instead of loading everything every time.
As you've noticed, in practice Core Data is commonly used more or less like a database, and it works for that. But it's not designed to be limited to such uses.
Yes it is true , Core data is not a Database, though internally it saves data using sqlite. We use Coredata for persistent data which means we should be able to save the data and use it even after closing and reopening the app. There are various ways to store data like Sqlite,Plist,UserDefaults and CoreData. Coredata does not maintain any relations like SQlite. It means there are no keys like primary and foreign etc. Coredata allows you to deal with data in Object Oriented Approach. You can easily work with data operations even you don't have knowledge about DB queries.
Typically I use Core Data in my applications, but for my current project I don't need data to persist launch to launch.
Because of that, I'm wondering how I should store my data. It's not going to be tens of thousands of items or anything, hundreds at the high end most likely.
I'm still going to create an NSObject subclass to represent each "entry" in the database, but what should I store that in? A simple NSMutableArray that's a property? Should I have a distinct model class? Should I still be using Core Data somehow?
What's the accepted/best practice for a situation like this?
The persistence aspect is only one part of core data. The fetch requests, object graph maintenance and entity modeller are arguably just as important.
If you don't want to persist your data, use the in-memory store type when creating your core data stack.
I would say that if you are familiar with Core Data why dont use it?
But alternatively of course you can stick with NSUserDefault. Atm i'm using the NSCache class.
Good explanation of NSCache and how to use it
Apple's Doc
I would give it a shot if you dont like to use CD for your current Project..
Since you're not worried about persistence, it seems simplest to just use a wrapper around an NSMutableArray (or NSMutableDictionary if indexing is more important that ordering) Since you can apply NSPredicates to arrays you've still got the ability to do very dynamic database style sorting and searching without some of the drawbacks of core data.
Use a wrapper instead of just using an array because that gives you a convenient place to put sorting and searching options, as well as possibly giving you better access to KVO operations.
I would like to know how to manage a big Core Data ManagedObjectModel like this, but with more attributes in every entity. Proyectos(means Projects) and Desarrolladores(means Developers) will be a Table View. The other entities will be only items. I want to manage with singleTon for the fetchedResultController and to control the managedObjectContext
Does anyone knows about some examples like this? Big Models or something? All that I find is with only one entity or two.
Another question is that I am going to get all the data from JSON requests, so I want to know if I had to use NSPersistentStoreCordinator or I should use UIManagedDocument?
This is other example
Thank you.
I recommend using a sigle shared (Singleton) UIManagedDocument to ensure that you have the same UIManagedObjectContext for all the classes in your App.
Example on how to set this up can be found in thos blog:
http://www.adevelopingstory.com/blog/2012/03/core-data-with-a-single-shared-uimanageddocument.html
You can have several NSFetchedResultsController that will use this shared UIManagedObjectContext (from the shared UIManagedDocument).
This is a sample project I did for the Stanford course CS193p on iPhone programming. It uses Core Data with the sigleton I am proposing.
https://bitbucket.org/jcatalan007/cdspot
If you are using CoreData to cache data from JSON, you might want to look at https://github.com/RestKit/RestKit. It will take care of mapping between JSON objects and CodeData objects - potentially saving you a lot of code.
The model you show is not very large; examples in books and courses are deliberately small because they are only intended to teach. Real-world databases are always larger.
i'm struggling a bit with this subject since I come from the world of PHP where you don't have anything like "Core Data" (as far as i know).
Until today, when i needed a data model for saving data from the server , lets say i got some users from an API, i would create an NSObject class called "MyAppUser" , and on the .h file would have the properties for that data and synthesize it in the .m , and then just use that class for arranging my server-data in nice neat objects.
I read a bit about Core Data , and it seems its mainly for actually storing the data in some sort of database, which isn't what i want. What i want is actually just have organized objects with data from my server returned to me. Could i do this with Core Data? just have objects but without actually managing them and storing them ?
Thank you and sorry if my question is a bit "scattered" :)
Shai.
Your interpretation is correct - core data is a persistence framework. It is designed to help you store and retrieve data between sessions. It's not worth the overhead (IMO) for transient data. Use a custom object for storage, or even just an NSDictionary.