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
Related
I am developing iPhone app for a web application currently running online. Current web application is big and complex and uses SQL to store vital information like member details, login credentials etx. Other stuffs like info about several sections, groups, sub groups and other information related to each are saved in txt. Current system uses its own standard to keep data in files and also made custom algorithm to read and write data in it. Each txt file is below 1 mb size. There are lot of data manipulations going on.
Custom algorithm created just read those files and put all data in cache as records (same as in core data managedobjectcontext) and whenever there is a change in data the whole file is overwritten.
So while implementing the same what I want to choose for iPhone app? In apple website they said that 'SQLite is perfect for low-level relational database work' https://developer.apple.com/technologies/ios/data-management.html But in my case it is high level.
So please help me to make a decision. Do I want to manage data in files or sqlite database using core data?
I would also like to know whether it is possible to import those classes and algorithms currently in webserver to iOS, so I don't want to rewrite the same algorithm for iOS? Current server codes are in C#
In the rare case that you need to do low-level relational database work use SQLite. In the 99% other cases use Core Data. Don't ever store relational stuff into txt files. It'll just be a pain.
Your use case sounds like a good match for Core Data.
Often misunderstood, Core Data is an object store that happens to use sqlite for persistence. You don't manipulate the sqlite underneath it, Core Data manage the sqlite for you. You do not write SQL. The closest match to it in .NET is EDM and the Entity Framework in ADO.NET.
Assuming the classes and algorithm you want to import in the webserver is in C#, sadly those needed to be ported to Obj-C.
I am creating a Questions and answers app for iphone which allows user to answer the questions displayed.
Currently I am invoking a web service to store the users answers. But I am slightly worried what if the web service goes down. I need to store the users answers locally and then invoke the web service when it is up and running.
How can I store the users answers when the web service is down. Is Sqllite a good option for this?
Please suggest.
Thanks,
Is Sqllite a good option for this?
Yes, SQLite is decidedly a good option. The other choice would be Core Data.
Use CoreData or SQLite on iPhone?
It depends on the complexity of your data model. I've looked into something like this recently and here is what I learnt. The most popular data storage methods in the iPhone are:
plist
Good for small quantities (hundreds of Ks) of hierarchical data.
Bad if relationships or queries are complex (since you have to write the code).
Very easy to learn.
Supports array, dict, string, data, date, integer, real, boolean elements.
You can store it as XML, which is editable and portable, or as binary files, which is faster.
Core Data
It's a object graph manager with searching and persistent functionality.
You need a good few hours of learning.
Easy to use once you set it up.
Better than a plist because it lets you manage object graphs, grow your object model, write queries, undo/redo, migrations to modified data models, memory management, and handle concurrent access.
Better than SQLite because:
The performance is similar and the speed of development is faster.
Creating objects is faster.
When the objects are in memory, executing queries doesn't require a search in the backend (which usually is either memory or SQLite).
SQLite
A database.
Better than Core Data when the operation doesn't require you to bring objects to memory. Example: update, delete, and select 1 (see if something exists).
It has full text search if you compile the extension.
Hardest to learn. Easier if you use a wrapper: FMDB, egodatabase.
If you can get away with a plist do that. If you see the amount of code you will have to write is too much work, then switch to Core Data. Only if you are an expert and absolutely need the performance use SQLite (unless, of course, you already know SQLite and not Core Data).
It should be, yes. I'd set up a Core Data based app with entities for Questions and Answers and set up relationships between them. Then just use NSFetchedResultsController or whatever you would like to gather and display the data
You have several options:
Sqlite
Core Data
Client-Side storage
If you wish to go the web based route, I'd take a quick look at Safari Client-Side Storage and Offline Applications Programming Guide.
Basically, you store a local copy of the database in memory so incase the web service is down, users can still use the app.
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've been looking into creating a new application for iOS and after my last few apps I've been tempted to use CoreData (for benefits including saving and automatic undo/redo).
I've been a little confused when trying to implement the data-model I've been given fr the project though, since it seems that CoreData seems very much much closer to a database than a data model.
Should I be using CoreData for an application that doesn't generally fit the 'large amount of data/records' description I would generally use an SQL style database for?
If it helps, the app I'm designing will be a sort of document editor, so there will be a number of objects I will need to represent (there might be embedded images, graphs/charts, hyperlinks etc within the document) and I need to create this model from an xml description.
Most of these 'items' need to implement a set of interfaces (the model was created for a Java product; I'm having difficulties seeing how inheritance and abstract interfaces can apply to CoreData), and every example I've found so far seems to add base elements (like an NSDate or String) to a simple model.
Does this sound like a candidate for CoreData, or is CoreData more of a tool for implementing a database in an application? (i.e a library system/staff database).
consider CoreData as an option once you are able to properly write the majority of the code it will replace. so once you know how to properly serialize/deserialize, write undo/redo, KVO, copying, etc.
Should I be using CoreData for an
application that doesn't generally fit
the 'large amount of data/records'
description I would generally use an
SQL style database for?
CoreData isn't restricted to large databases (at all) - it will work well with small sets, and beyond databases (binary files and documents, direct in memory use of models).
your example could benefit from CoreData. it depends on the amount of custom code you need - sometimes it is just easier to write the code if you're just using CD objects as an interface generator, and your app uses a lot of custom code/objects. to be honest, i've never used CoreData in a shipping app - i always found reasons to migrate models to existing code before then (assuming CoreData was also used during development/modeling stages).
it's a nice framework, but it shouldn't be viewed as a 'magic object generator' that will solve most problems. first, you need to understand he technologies/patterns you intend to replace with it. there is a limited number of ideal uses for it. if you can't write the code the objects depend on, don't bother using CoreData. iow - don't consider it as a replacement for initial effort because there are certainly times when it is a good choice and a bad choice - but you can't make an objective answer for your context if you don't (truly) understand what it is capable of.
One of the purposes of Core Data is managing an object graph in memory. This certainly fits your application. It can then be persisted to disk easily. Using a tool such as mogenerator allows you to use Core Data to manage the object life cycle, graph and persistence, but add your custom protocols on top.
In short, yes, you can use Core Data for non-database uses, with a bit of work to conform to the model.
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...