Core Data and NSFetchedResultsController do clever things under-the-hood to improve performance, such as loading data in batches as it’s needed. But there’s a gotcha with grouping data with sectionNameKeyPath than can cause a big hit in performance. Check this out.
Hi, I’m new here. You may know me as @atomicbird on Twitter. Just a few days ago my book Core Data for iOS: Developing Data-Driven Applications for the iPad, iPhone, and iPod touch (co-written with the excellent Tim Isted) was published, and Matt invited me to contribute some Core Data tips to CIMGF. I’m going to start off discussing taking JSON data from a web service and converting it to Core Data storage. Along the way I’ll cover how to inspect managed objects to find out what attributes they have and what the attribute types are.
Publishing lead times being what they are, this post covers information not included in the book.
Many technologies we use as Cocoa/Cocoa Touch developers stand untouched by the faint of heart because often we simply don’t understand them and employing them can seem a daunting task. One of those technologies is found in Core Animation and is referred to as the CATiledLayer. It seems like a magical sort of technology because so much of its implementation is a bit of a black box and this fact contributes to it being misunderstood. CATiledLayer simply provides a way to draw very large images without incurring a severe memory hit. This is important no matter where you’re deploying, but it especially matters on iOS devices as memory is precious and when the OS tells you to free up memory, you better be able to do so or your app will be brought down. This blog post is intended to demonstrate that CATiledLayer works as advertised and implementing it is not as hard as it may have once seemed.
**This article is reprinted from the MDN**
The documentation on Core Data for the iPhone has lead to some confusion about how best to use Core Data on a Cocoa Touch device. One particular section seems to be the most confusing, specifically:
> A view controller typically shouldn’t retrieve the context from a global object such as the application delegate. This tends to make the application architecture rigid. Neither should a view controller typically create a context for its own use. This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.
> When you create a view controller, you pass it a context. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.
The idea behind this section is the issue of rigidity. Ideally, each view controller should be an island on its own. It should not rely on its parent, nor should it rely on the Application Delegate. Once a view controller is pushed onto the screen it should ideally be its own master.
## Why Rigidity is bad
It is fairly common when designing a Cocoa Touch application to “hard code” everything. Take the following navigation controller design:
![Navigation Controller Design](http://www.cimgf.com/wp-content/uploads/2011/01/Image1.png “Standard Navigation Controller Design”)
When this design, it is common to code each view controller and make it “aware” of its parent. In that design, it would be common to see view controller B call methods or call back (to its delegate) view controller A. While there is nothing technically wrong with this design, it is very rigid. It is nearly impossible to either move view controller B to another location in the stack or to reuse view controller B somewhere else. This is the trap that the documentation is trying to help new developers avoid.
## Solution One
Again using a standard/normal navigation controller design, it is expected that the detail flows from left to right. The left most (or root) view controller contains the most vague information and the right most (or deepest) view controller contains the greatest detail.
In this case then the best solution is to use a
UIFetchedResultsController. This controller can be considered a thin layer between the view controllers and the Core Data bits. The advantage is that the
UIFetchedResultsController is designed to work with tables. The other advantage is that your least detailed view (the root most likely) can listen as the delegate of the
UIFetchedResultsController for changes and update itself.
In this design, however, instead of passing around a context, you would hand off just the entity that the child view controller needs to know about. The Core Data Recipes example provided by Apple illustrates this design quite well.
How does this break rigidity? Each view controller, from the root on down, only knows what is passed into it. The root gets the
UIFetchedResultsController passed into it. The child views only get the items it cares about passed into it. None of them care what their parent view controller is. There is no call back to a parent.
## Solution two
What happens when we don’t have a typical navigation controller design? Perhaps a child view can pop up a modal view that displays different information. Perhaps a child view, for whatever reason needs to access information that cannot be directly passed into it every time.
In these cases there are a few different options.
### View already has a
Following our example above, lets say that view controller C needs to create a new object. Perhaps it is a detail view of a recipe and the user wants to add a new recipe type (perhaps she is a vegan and just discovered there is no vegan type in the list). In this case we have passed in an entity (the recipe) but not a reference to the
NSManagedObjectContext. Fortunately this solution is easy to fix. The
NSManagedObject retains a reference to its
NSManagedObjectContext internally and we can access it. Therefore we can easily retrieve the
NSManagedObjectContext from the
NSManagedObject and create the new Type entity and pass it to the modal child or whatever our design calls for.
This again avoids rigidity because the view controller that represents the entity does not need to call up to a parent object or the
UIApplication delegate. It is self contained and only manages view controllers that are down stream from it.
### View does not have a
In this situation things are *slightly* more complicated. In this case we want to create a
@property for the
NSManagedObjectContext and require that our creator set the property.
@interface MyViewController : ViewController
@property (nonatomic, retain) NSManagedObjectContext *moc;
Again, the view controller is an island of its own because it does not care where that
NSManagedObjectContext came from. All it knows is that it is required for the view to function. It does not care of it is a new
NSManagedObjectContext specifically created for its use (perhaps for a cancelable edit tree) or if it is the same
NSManagedObjectContext that has been passed around since the launch of the application. All it knows is that it has the elements it needs to perform its function.
By making the
NSManagedObjectContext a settable property we can also transplant the view easily. If, at some point in the project lifecycle, we decide that it makes more sense to have the following design:
![Modal View Controller](http://www.cimgf.com/wp-content/uploads/2011/01/Image3.png “Modal View Controller”)
Taking from Apple’s Recipes Application, perhaps we decide that moving from the table view directly to the image of the recipe is more pleasing to the users and that when they want to see how to make it they can “flip” the image over and see the detail.
Making this change with each view controller being an island is quite simple. We just rearrange the views without having to worry too much about breaking the application.
## Solution three
Up until now we have been looking at just a navigation controller design. But what about tab bars? In the situation of a tab bar we again want to avoid rigidity because it is even more common that tabs will get moved around.
The solution to this is to again use a
@property for the
NSManagedObjectContext and require that the creator set this property before the view is displayed on screen. If you are creating the tabs in code this is trivial because you are already calling init on the view controller and you can add one more line of code after the init to set the property.
If the user interface is being developed mostly in Interface Builder it is slightly more tricky. Personally I am not a fan of creating navigation controllers or tab bar controllers in Interface Builder. However if that is the design then I would recommend referencing the view controllers as properties and passing along the context upon initialization of the application. It may be possible to do this entirely in Interface Builder but I am not comfortable enough to recommend that as a solution.
The overall idea behind this article is to keep each view controller separate from anything up stream or in a different silo. This will make the design far more flexible in the long run. Any time that you feel the “need” to pass in a parent view controller to a child view controller, reconsider the design. Consider using a
@protocol delegate design or NSNotification calls instead. Keep each view controller as its own private island.
Just a quick post to point out a great article written by Nick Harris of NewsGator fame. He has looked into the issues with Core Data and encryption.
It has always been a difficult question and fortunately Apple has addressed it for us. Even better, Nick has shared the code so we don’t even need to try and discover the solution ourselves.
In your iPhone/iPad apps you often need to know how many times your user tapped in a view. This can be challenging because, though the user may have tapped twice, you will receive the event and it will look like they tapped once as well as twice. If the user triple-tapped, you will get the event for one tap, two taps, and three taps. It can get a little frustrating, but the trick is timing. You simply have to wait a period of time to see if another tap comes. If it does, you cancel the action spawned by the first tap. If it doesn’t you allow the action to run. There’s a few little nuances to getting it to work, but it can be done. Here is how.
An interesting question came up on Stackoverflow today so I decided to expound upon it in a short blog post.
A situation that I believe we are going to be seeing more and more often is one where application developers are writing multiple “versions” of their applications to be used on the desktop, their iPhone and now the iPad.
Because of that situation, it is becoming even more important that we write as much portable code as possible. Fortunately, our model can be completely portable between the two platforms.
Upon first glance, the UIButton class doesn’t seem to provide what you might expect in terms of customization. This often causes developers to resort to creating buttons in an image editor and then specifying that in the Background field in Interface Builder. This is a fine solution and will likely give you what you need, but with Core Animation layers there is a simpler way to achieve the look you want without having to create an image. This post will demonstrate how.
Last month I was given the opportunity to write an article for The Pragmatic Programmers great magazine called “PragPub”. I am happy to say that the article I wrote for them was published in this month’s edition. The article, titled “Touching the Core”, is a walk through Apple’s great addition to the Core Data API for the iPhone.
Specifically this article walks through using the NSFetchedResultsController and some best practices in its use. The magazine is available for free on their website, [The Pragmatic Bookshelf](http://pragprog.com/magazines).
For those not aware, when you compile an Objective-C application, whether it be for the desktop or for Cocoa Touch devices, the debugging symbols are stripped out of the binaries. Therefore, unlike other languages such as Java, when a crash occurs, there is virtually no way to determine where the crash occurred. However, when the applications are compiled, a dSYM bundle is generated. This bundle allows us to match up the debugging symbols with the application’s crash log to help determine the cause of the crash.
At first glance setting a height dynamically for table view cells seems a little daunting and the first most obvious answers that come to mind are not necessarily correct. In this post I will show you how to set your table view cell heights dynamically based upon the text content without subclassing UITableViewCell. You can subclass it, however, doing so does not make the code much cleaner as setting the height is done in your delegate for the table view itself rather than the cell anyhow. Read on to see what you need to know to make dynamic cell height sizing a breeze.
I’ve seen a good bit of sample code that shows how to implement using a UINavigationController in a view controller that is managed by a UITabBarController, but I haven’t seen much on how to do it with Interface Builder. Turns out that it’s pretty simple and I’m going to show you how.
Update: This is documented behavior.
Every now and again while doing development you stumble upon something that makes you go, hmmmm. Those are normally the moments at which you have to ask yourself, “is this a bug or a feature”. If it’s a bug, then you should file a radar with Apple, however, what if it’s a feature? You blog about it, of course!
I have done a bit less iPhone development than Marcus, so he was a little stumped while looking through some of my code where I created a view controller using a simple alloc/init. Most interestingly is that fact that the app works. It loads the correct nib and displays the view just fine without any trouble. Notice I said alloc/init and not alloc/initWithNibName. How can this possibly work? How did my controller “know” which view to use?
As you develop applications for the iPhone, you will likely use the project templates provided in Xcode. One such template, called “Tab Bar Application” helps you get a tab bar application set up quickly, but by default the application it generates only supports portrait mode for display. So how can you make the application also support landscape or even only support landscape? In this post we will address that question.
Similar to one of my first blog posts on building a basic application for Mac OS X using xcode 3.0, I am going to explain for beginning iPhone/iPod Touch developers how to build the most basic Cocoa Touch application using Interface Builder and an application delegate in xcode 3.1. This tutorial post is really to provide a quick how-to. I won’t go into any depth explaining why things are done the way they are done, but this should help you get up and running with your first application pretty quickly so that you too can clog the App Store with useless superfluous apps (kidding… just kidding).
If you are a visual learner, it may be helpful to you to instead watch a video presentation of this tutorial. I’ve posted it on the site, but you’ll have to click the link to see my Cocoa Touch Video Tutorial.