I'm building a data visualization application that will help me realize data using Apple's Core Graphics and Core Animation frameworks. I have a Python server performing the data science and communicating the data I want to visualize in JSON.
When I started making the data visuals in my NSView subclasses, I noticed there is a lot of data that each Core Animation layer maintains. For instance, if this were a candlestick graph, each "candle" would have a trade Open, High, Low, Close, Date/Time, etc. data associated.
I know that in strict MVC design Views are not supposed to handle any data management -- only the rendering of that data.
Is this were Apple's Core Data framework would come in?
All my research...
iOS Core Data: Confused about Core Data and database
Core Data vs. Database fundamental difference?
https://nshipster.com/nscoding/
...and many more.
...says that Core Data is not a database. It's an object graph manager that could persist object data if you wanted it to. It also says that "Core Data's true function is to provide the complete model layer for the Model-View-Controller app design that the Apple API uses."
So, does that mean Core Data can be used without its persistence feature?
Since much of my data is live, I don't have much use for persistence. All of that data comes from my Python server. But, I will have a LOT of graphs with Core Animation shapes to represent them. And, the graphs will be constantly changing based on different options, server changes, and user-selected overlays.
I started to develop a separate class to handle individual CAShapeLayers, the data that defined each of them, and their rendering methods. But, this isn't true MVC design -- it's an object-oriented approach, right?
I'm confused...
What data should an NSView subclass manage, and when should Core Data take over?
My research also showed NSCoder with NSKeyArchiver is an alternative, but that seems to be used primarily to serialize/deserialize or encode/decode data to a file-store or for network transfer. I'm not sure I'm looking for that.
Related
Im developing an iOS application and I'm stuck on how to design the structure of it. Here is what I have so far:
The app is called "Time Clock" and it allows users to clock in and out. The app will generate time stamps when a user clocks in or out respectively. As far as data goes, I already have a large MySQL database that is already being used for a similar Windows desktop application. (I'm trying to cater to my company's iPhone users)
My question is, what should I do about the data structures in this app? Can Core Data retrieve the MySQL data (through a web service) and manage it? Should I use data controller classes to manage the data? I don't know the best way to handle the data.
Here are the data fields that need to be managed:
Store
Name
PIN
Timestamp In
Timestamp Out
All in all, what is the most efficient way to manage the data in an app such as this? If you could point me in the right direction i would be very thankful! :-)
Core data wont be able to retrieve anything from a webservice, you need to make a data access layer that will return that data to you via NSURLConnection and the like, there is a lot of information out there on how to do this... I would recommend modeling some classes that basically your data layer will fill for the rest of your application to work with. Also if your data is shared across many views i would suggest making some singleton class that will keep the data already retrieved, this way you can access it across different UIViewControllers in your application. Way I would structure this is
DataAccessLayer (layer that consumes your webservices, and fills the info into classes (your model)) -> Some Singleton class that keeps your objects from your webservices -> UIViewControllers (these will talk to your data access layer/ Singleton class for the data it needs which in turn uses it to fill your views ->VIEWS - > if changes occur to your model relay that to your webservices via the data access layer
... As far as core data, you can use that if you want to persist the data in your application, but its not necesary otherwise, i should point out that core data is not the only way to persist data in your application... This answer is a bit general but hope it can point you to the right direction..
Daniel
I am really confused on what the Core Data actually is. Or I guess my question is, when dealing with a database, would you use Core Data? Like if I wanted access values from a database would I be using Core Data to access those values? How would I approach this problem?
Thank you so much for the help.
Core Data is an framework that does the work of "object persistence". In other words, it's code you can use that takes care of saving a collection of objects to disk and loading them again later. It does a lot of work to allow you to store lots of data and load only the objects you need at a time, and unload ones when memory is tight.
Core Data can use a database to accomplish this, but that's it's business, not yours. When you use Core Data, it is a black box. You tell it to save the data and then step out of the way.
If you want to interact with an existing database, such as a MySQL database on a web server, that's a completely different matter. You might use Core Data to store local copies of objects on your device, but in that case Core Data won't care that the objects are copies from some other database. It doesn't care.
It is a convenient, native means of storing data in your iOS applications. Don't think of it as sqlite although you can view the files it creates with various sqlite tools. Instead think of it as a tool for manipulating an object graph of information important to your app.
I've used it in two main ways. First to store a bunch of static data that is important to an app, in one case that was a large amount of location data for an indoor mapping application. What arrived as a massive CSV file of waypoints was converted to core data. Core Data was incredibly useful for this because it allowed preparing a sqlite file which was shipped with the application containing all the infomation. Updates from a web service arrive as more CSV that is added to the Core Data to keep information current. At runtime the location information object (the waypoint a user is at) is retrieved with a predicate (i.e. the point they tapped on) and that object, through its Core Data relationships, indicates where it is possible to go from that point. Core Data provided the information necessary to perform A* routing through the indoor map.
Second it is great when you have a bunch of objects arriving as JSON and you want to be able to store and access those objects later. Let's say you have a typical app where you have a User and some information about the User, let's call it Thing. Users have Things. When you want to know something about a User you retrieve the Core Data record using a predicate - typically "name" or similar - and you get all the information you stored about the User back. Again you can make use of relationships to explore the user's connections and make displaying information easy. Perhaps the User has many Things, then you can say "user.things" and you get a NSSet of NSManagedObjects representing those Things.
You use it like a database. Its utility is that it is easy to access from anywhere in your iOS code, it is easy to store and easy to retrieve information also. Faulting lets you retrieve one object and navigate to any object connected through relationships by following the relationships. Because you define the attributes and relationships yourself in the data model editor it is easily customized for what you need to store. To me it is one of the most used and most useful parts of iOS.
When you want to automate display of information from Core Data you can use a NSFetchedResultsController to initiate a fetch and to respond through delegate methods to changes to the underlying data. If you set up a UITableView to use a NSFetchedResultsController as data source, you can have the table automatically update whenever the objects displayed in the cells changed. Very useful for apps where you periodically update information and want what is displayed to be kept current.
When your object model changes it is possible to maintain all of your existing information and migrate it to the new model. Core Data manages automatic (lightweight migration) when it can, or if you have made more radical changes you can supply rules to handle the migration.
The limitation of Core Data is that it is not great for storing binaries. If you have images that you need to store, far better to store a path to the location of the image than trying to store the actual data.
Yes, if you want a local database on your device, Core Data is the appropriate technology. It probably makes sense to start your research with the Core Data Programming Guide.
You can alternatively use SQLite (which Core Data uses in the backend), but Core Data offers some material advantages and is the preferred database interface for iOS. If you decide to pursue SQLite for any reason, though, I'd suggest you contemplate using the FMDB Objective-C SQLite wrapper.
But Core Data is generally the way to go.
So I have been doing lots of reading and found out NSCache is not persistent which is a slight problem for what I need to do. I have heard that I will need to use Core data instead... but I don't have any experience with core data so am wondering if its the only solution for persistent data.
The app will allow the user to search through a catalog, by typing in a search parameter in the code and select a distributor for their search parameter. What I want to do when the app loads is download the list of distributors and save them to a "cache" the will be persistent (till when the header I will make at some point changes and demands the app to update the cache), so that if the user turns the app of or the phone next time then open it the manufacture.
Now that I'm getting abit deeper into my app I'm getting abit lost in things for instance how would setting up a cache work with regards to NSURLConnection.
Any suggestions or code examples would be greatly appreciated..
This previous answer of mine might help you decide.
To sum it up:
If your data is small, static and low-complexity, use a collection class and write it to disk using the built-in class methods
If the data is static, low-complexity but large, SQL may be a good solution especially if you already know it.
If the data is dynamic and complex regardless of size, then Core Data is your best choice.
Viewed purely from the technical perspective, Core Data is always the best choice for iOS/MacOS API apps. Core Data is not just a persistence API, it is an API for creating the model layer of the Model-View-Controller design paradigm that the Apple API uses. It not only persist the data, but models it, validates its and provides an easy interface to the rest of the API.
If your going to be writing iOS apps, you need to eventually learn Core Data. However, it does have a learning curve and you should pick the method right now that will let you ship a usable app.
You can also check out sqlite. Here's another question that discusses getting started with sqlite on the phone: Where's the best SQLite 3 tutorial for iPhone-SDK?
The advantage to sqlite is that it is fairly easy to pick up. The downside is that you have to write queries for everything, and that can be a pain. It doesn't save objects, just data, numbers or text.
I have an app developed for iPhone OS 2.x. For the obvious reasons, the model classes in that app were written without Core Data.
Now that 3.x is available, I'd like to know what are some of my options for taking my existing model classes and rebuilding them with Core Data. I do many things with my models besides the obvious, such as serializing them and storing them into an sqlite3 database so that my application can work when there isn't any network connectivity. I would expect Core Data to be able to help me with that as well.
Also, with the incorporation of Core Data in your application, is there any reason at all to still use sqlite3? Would you still use it for things such as providing for offline content, keeping around statistics that might not necessarily make sense to create a model out of? Or is there ways of incorporating all of that into Core Data as well?
The primary benefits I've found from using Core Data in my iPhone applications are:
Keeping referential integrity
Managed model migration on schema changes
providing an object relational mapping
Vastly simplified insertion and join and query process - joins for instance are typically just done through "dotted" syntax
Multiple store overlaying (although look for my stackoverflow question about this to see if it actually works on sqllite, still awaiting response...)
Structured predicate construction - you can create your predicates as objects instead of inline embedded sql statements
Reflective data store - you can introspect the data store at run time in a structured and statically analyzable way
That said, if your app already has been designed to work against a sqllite database, you really need to ask yourself if you're ready to convert your application over.
You will need to do at least these things:
Remodel your entire database schema in Core Data managed object models
Rewrite all of your database queries and management to use Core Data
Rewrite all of your models to either be backed by Core Data generated managed objects, or extending them
Import all of your existing data by hand into your Core Data database
Be prepared for potentially writing a lot more code! Although Core Data provides a good object framework for dealing with data store querying and management, it also does so at the expense of verbosity.
To continue the previous point, when you do even relatively minor changes to your schema, you're going to be prepared to spend a relatively significant amount of time providing a schema mapping and applying it correctly to your existing schemas.
Give you already have solved almost all of these issues already, the benefit you would get form porting an existing application to Core Data is elegance and keeping up with latest technology. You will have to provide a not insignificant amount of effort to get that, and given the benefits probably aren't stupendous, you might find it not really worth your while.
To answer your second question, I can't really think of any reason for using sqllite directly if you are using Core Data to be honest. I'm not certain that outer joins are terribly simple in Core Data for instance. However, you don't typically use Core Data in that manner - you would use it procedurally to craft the same effect as the outer join in SQL.
For statistics and stuff I would still use Core Data because it provides some fantastic aggregation functionality.
Note there is nothing preventing you from taking the opposite approach: adopt Core Data for extended functionality until you become comfortable enough with it, then begin porting your main applications existing code to use Core Data.
The other answer is very good, but I disagree on the benefits being mainly elegance and keeping up with technology... the real reason to move to Core Data is actually performance and memory related, in the Core Data manages caching very intelligently and you'd have to do a lot of work to replicate that. That to me is the sole reason to even consider it, as it is very verbose as noted and you also have to work around all data objects needing to use NSNumber to hold primitive values (which I find particularly annoying).
For something like your setup, the approach I'd probably take for migration is to have each model class hold on to managed objects that are actually the storage classes - then your whole code would not have to change, just some things in the model objects and possibly management classes you might have built to handle creation or population of the model objects. That even hides the NSNumber wrapped primitive issue.
If you are strongly considering working with Core Data, you may want to take a look at this book that covers the iPhone specific Core Data as well (including NSFetchedResultsController):
http://www.pragprog.com/titles/mzcd/core-data
You can buy an e-book only unlocked PDF version which is not too expensive...
We're beginning development of an in-house app in the iPhone Enterprise developer program. Since it's close to OS 3.0, we're reconsidering our original design of using SQLite and using Core Data instead. Here's some more info:
There is a legacy desktop application that this is replacing. We will reuse the existing back end.
We currently have a SQLite database generated as a proof of concept. This is basically a cut down version of the existing back end database.
We will be loading data from a remote site and storing it locally, where it will persist and need to be . We only update it if it has changed, which will be every month or two. We will most likely use XML or JSON to transfer the data.
There are two developers on this project and we both have strong SQL skills but neither one has used Core Data.
My questions are: what is the benefit of Core Data over SQLite, what would the benefit be in this specific instance and do the benefits justify learning a new framework instead of using existing strong SQL skills?
EDIT:
I just noticed this question: Core Data vs SQLite 3. I guess my questions therefore are:
If I have to check if a specific item either exists or has an update, which is easy using SQL, does Core Data still make sense? Can I load the first object in a graph and check the version number without loading the whole graph?
If we already know SQL, does the advantages of Core Data for this one project justify us learning it?
As you've read Core Data vs SQLite 3, you know that Core Data and the persistence mechanism (SQLite in this case) are largely orthogonal. Core Data is really about managing an object graph and it's main use case is for the model component of an MVC architecture. If your application fits nicely into this architecture, it's probably worth using Core Data as it will save you a lot of code in the model component. If you already have a working model component (e.g. from the existing desktop app), then Core Data won't buy you much. A hybrid approach is possible-- you can do your own persistence/querying and build a Core Data in memory store which you populate with the result of a query and use this in-memory store via Core Data as the model component for your app. This isn't common, but I've done it and there are no major roadblocks.
To answer your specific questions:
You can assign a version number to the entire persistent store and retrieve that information via +[NSPersistentStore metadataForPersistentStoreWithURL:error:], without even opening the store. An equivalent +setMetadata:forPersistentStoreWithURL:error also exists, of course. If you want to store the version info in an entity instance instead of in the persistent store metadata, you can load only a single object. With an SQLite persistent store, Core Data does a very good job of fetching only what you need.
The NSPredicate API, is very easy to learn and it seems to do a decent job of compilation to SQL. At least for databases of the size you could fit on an iPhone it's certainly been adequate (performance wise) in my experience. I think the SQL vs. Core Data question is slightly misguided, however. Once you get the result of a query what are you going to do with it? If you roll your own, you'll have to instantiate objects, handle faulting/uniqueing (if you don't want to load the entire result of a query into memory immediately) and all of the other object graph management facilities already provided by Core Data.
It sounds like you already have the project designed using SQLite, and you have experience in that area.
So the bottom line is, does it make sense to port this project, will Core Data give me anything that I didn't already have in my original design?
Assuming that the original design was done properly, based on the requirements ON THIS PROJECT, it's probably not worth it.
But that's not the end of the discussion. There are other things to think about: Will my next project have such light database requirements? Do I need to ship soon, due to timeline or budget constraints? Assuming I'm going to have to learn Core Data sooner or later, doesn't it make sense to do it now? Am I possibly interested in porting my code over to the Mac?
The answers to these questions may lead you to the decision that yes, it is indeed worth it to go back to the drawing board so to speak, and learn what Core Data is all about.
To get to your final question: What are the advantages? Well, Core Data is a higher level abstraction of your database, it is also data store agnostic (so if a future version of the iPhone were to ditch SQLite for an embedded version of MySQL... unlikely, but it's an example) then Core Data would require VERY few changes to the code to make it work with the new data store. Core Data will provide a great deal of quick portability to the Mac platform. Core Data will handle versioning of your data model, whereas unless you have a framework or a workflow to manage it, direct access to SQLite won't.
I'm sure other answerers can come up with other advantages, and maybe some good reasons why NOT to mess with Core Data. Incidentally, in a similar situation, my decision was to port to the higher level, newer framework. But in my case, it was for a side project, and ship date and budget were non-factors.
Not to detract from this forum, but you might find more respondents with contextually relevant experience at the Apple iPhone DevForum.
Speaking from a purely project management perspective, it sounds like you know how to build what you want to build using SQLite, and so it would make more sense to me for you to start along that route.
That being said, CoreData builds on top of SQLite and if you are trying to leverage other parts of the system in conjunction with your data, e.g. using KVC/KVO or bindings, then you may quickly find that this functionality is worth the learning curve.
= Mike