Massive View Controllers
While at Empirical Development and then MartianCraft I had been distanced from all of the inventive solutions that other development teams have been coming up with for the past few years. I was living in a bubble of our development teams.
Now that I am working independently again, I am being exposed to a large number of interesting code bases.
It came as quite a surprise to me that view controllers are considered bad by many developers and that they have been coming up with some rather intersting solutions to make them more “manageable”.
To me, this is an indication that many developers have lost the perspective on what should and what should not be in a view controller. For some reason there is a misconception going around that everything belongs in the view controller.
Madness!
Lets break it down.
(more…)
Anonymous Image File Upload in iOS With Imgur
It seems like a pretty useful feature, anonymous image file upload in iOS with imgur. If you need to upload images and don’t want to fool with some authentication mess like OAuth this technique is perfect. There are libraries that have simplified the OAuth process, however, it’s nice to be able to just initiate an upload, get a result URL back and be on your way. No fuss, no muss. That’s what I was looking for, so I wrote a little app that demonstrates how to do exactly that.
(more…)
Down with Magic Strings!
Developing iOS apps in Xcode is pretty great. With Objective-C and llvm we get type checking and autocompletion of all our classes and method names which is a nice improvement over my favorite dynamic languages. Unfortunately there are still some places where the compiler can’t help us. There are various resources we load from files like images, nibs & xibs and other resources which we need to specify by name, like a view controller we want to load from a storyboard.
(more…)
A Better Fullscreen Asset Viewer with QuickLook
Since last year I’ve spent a lot of time working on iPad apps for medical device companies. These companies want to be able to display their sales materials/digital assets to potential buyers on the iPad because of its gorgeous presentation. We can’t blame them. This is a great choice especially with the retina display on the third generation iPad. It’s incredibly compelling.
Our go-to solution for presenting these files until recently has been to just load everything into a UIWebView because it supports so many formats. Voila! Done! We like simple solutions to problems that would otherwise be very difficult.
This solution has worked great, but over time it’s become a noticeably dull spot in the app with some UX problems to boot. This is not good–especially for the part of the app that gets the most customer face time. It needs to shine. To go fullscreen, we just load a full size view controller modally. One issue with this approach though was that it only worked in landscape. For some reason it would get wonky (engineering parlance for, “um, I don’t know”) if we allowed both orientations since the rest of the app supported landscape only. It also had a nav bar that would never be hidden, so the user would always see it even when they were scrolling through the document content. Finally, there was no way to jump down deep into a document. If you needed to get to page 325, for example, you had to scroll all the way there. That’s just a bad user experience–incredibly tedious making it unlikely anyone would use it with a large document. These were some significant drawbacks and I didn’t have a good solution to bring the polish that this segment of the app deserved. (more…)
Extending NSData and (not) Overriding dealloc
A couple of weeks ago Matt Long was having a problem with an app running out of memory. He had a ginormous data file he needed to load up and process, and that memory hit was more than the app could bear. It would load just fine, into an NSData, but before he could finish with it the app would run short of memory and die.
Until recently the obvious thing would have been to tell NSData to create a memory-mapped instance. Given NSString *path
pointing to a file, you could create an NSData with almost no memory hit regardless of file size by creating it as:
NSData *data = [NSData dataWithContentsOfMappedFile:path];
Starting with iOS 5 though, this method has been deprecated. Instead, what you’re supposed to do is:
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedAlways error:&error];
So, fine, whatever, it’s a different call, so what? Well, it wasn’t working. Instruments was showing that the app was taking the full memory hit when the NSData was created. Mapping wasn’t working despite using NSDataReadingMappedAlways. So what could he do? The wheels of my mind started turning.
Handling incoming JSON redux
A few months ago I wrote here about a generic approach to safely take incoming JSON and save values to Core Data object. The goals of that code were twofold:
- Provide a safe, generic alternative to Cocoa’s
-setValuesForKeysWithDictionary:
for use with NSManagedObject and its subclasses - Handle cases where JSON data didn’t match up with what the managed objects expected. Getting a string where you expect a numeric value, or vice versa, for example, or getting a string representation of a date when you want a real NSDate object.
The first item was the most important. It’s tempting to use -setValuesForKeysWithDictionary:
to transfer JSON to a model object in one step. The method runs through the dictionary and calls -setValue:forKey:
on the target object for every entry. It has a fatal flaw though, in that it doesn’t check to see if the target object actually has a key before trying to set it. Using this method when you don’t have absolute control over the dictionary contents is an invitation to unknown key exceptions and nasty app crashes.
Fixing this for managed objects was relatively easy because Core Data provides convenient Objective-C introspection methods. The general approach was:
- Get a list of the target object’s attributes
- For each attribute, see if the incoming dictionary has an entry. If so,
- Compare the incoming type to the expected type, and convert if necessary.
- Call
-setValue:forKey:
with that key and its value.
And then just last week I had the thought, wouldn’t it be nice if this worked for any object, not just for managed objects?
Super Happy Easy Fetching in Core Data
First up, I want to thank Matt Long and Marcus Zarra for allowing me to guest post on CIMGF. This post is the first in a short series of topics describing how to I’ve made using Core Data a little simpler without giving up the power features you still need. The full project from which this series is derived is available on github.
Core Data, for both iPhone and Mac, is a very powerful framework for persisting your objects out of memory, and into a more permanent storage medium. With the enormous power of Core Data, it can be easy to slip into the trap of thinking that Core Data is very complex.
Subduing CATiledLayer
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.
(more…)
Core Data and Encryption
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.
Core Data and Enterprise iPhone Applications – Protecting Your Data
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.
Thanks Nick!
Differentiating Tap Counts on iOS [UPDATED]
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.
(more…)
Re-Ordering NSFetchedResultsController
So Marcus is the Core Data guy, but I’ve been working with it a good bit myself lately and was recently faced with having to add re-ordering for a list of entities in a UITableView. The methods I found online for accomplishing this all suggested using an NSMutableArray as the data source for the table view. That will work, but I came up with another method, though similar, that achieved what I need without having to switch from using my NSFetchedResultsController as the data source behind the UITableView. In the end, I did use an NSMutableArray, however, I end up using it just to take advantage of its indexing. Read on to see what I mean.
(more…)
Fixing the UISplitViewController Template
The default implementation of the UISplitViewController based template in Xcode does not provide a navigation controller stack in the detail view. Instead it is just a regular old view with a navigation bar at the top. I suppose there are cases when you might want such an implementation, however, i think you would more commonly want there to be a navigation stack for cases when you wan to push new view controllers for your users to see. In this post i intend to demonstrate how to convert the default template to something more useable.
(more…)
My current Prefix.pch file
I have posted and discussed this file a few times but as with all things it has been touched, tweaked, and generally improved upon.
In this article we will discuss the latest iteration of my `Prefix.pch` file. As with anything I post, it is available for you to use as you see fit.
## The File
For those who don’t want to read the entire post, here is the file:
#ifdef DEBUG
#define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#define ALog(...) [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSUTF8StringEncoding] file:[NSString stringWithCString:__FILE__ encoding:NSUTF8StringEncoding] lineNumber:__LINE__ description:__VA_ARGS__]
#else
#define DLog(...) do { } while (0)
#ifndef NS_BLOCK_ASSERTIONS
#define NS_BLOCK_ASSERTIONS
#endif
#define ALog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#endif
#define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0)
This does not *replace* the Prefix.pch that comes with your project but it does go at the top of every project that I work on. The rest of this post we will review what this does.
(more…)
Creating a NSManagedObject that is Cross Platform
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.
Accessing The Cloud From Cocoa Touch
Everything is moving toward the cloud and unless you’re building calculators, unit converters, or miniature golf score keepers your iPhone app needs to know how to get data from it. In this blog post I intend to demonstrate how to set up a simple server application and how to retrieve data from it and post data to it using Cocoa Touch. I have chosen to use PHP on the server side because of it’s simplicity and ubiquity, and because I’ve know it, somewhat. You should, however, be able to implement something similar using your server side language of choice.
In many cases when you go to access remote data, you do so through a web service API. While services based on such technologies as SOAP or XML-RPC are standards that provide reasonable methods for retrieving and updating data, REST seems to be the methodology gaining the most ground lately. For our purpose in this post I won’t get into great detail of how to implement a REST base web service as, again, REST is not a specific implementation but rather a methodology. (Read up on it elsewhere if you don’t understand what this means). However, I will talk about it briefly so that you can get on the right path for doing your own REST implementation.
(more…)