Tag Archive for Objc

Programming Pitfalls: Circular Imports in Objective-C

PitfallI spend a lot of time in XCode working in Objective-C for iOS and Mac OS X projects. In many ways, Objective-C has become my “native language” in terms of programming languages. Still, that doesn’t mean that I can’t make really silly mistakes when working in that language. In fact, through the magic of GitHub you can see the mistake in real-time in my open-source Cocoa / Cocoa Touch networking library, MDNetworking.

The mistake is, like the best dumb mistakes, small and simple but can take more time than I’d like to admit to notice and resolve. Take a look at this pseudo-code sample for what went wrong:

#import "Foo.h"
#import "Bar.h"

@implementation Foo
 // CODE
@end

 

#import "Bar.h"
#import "Foo.h"

@implementation Bar
// CODE
@end

That’s it. That’s all you need to do to reproduce this programming pitfall. As always, I hope this has been illuminating and entertaining for you and please do follow me on Twitter.

Programming Pitfalls: iOS Simulator and Audio Codecs

PitfallThere are some bugs that you fix and brag about to your friends afterward, then there are the ones that are just plain embarrassing. Unfortunately, I’m writing about one of the latter today rather than the former.  You see this pitfall, though no more or less annoying than the others I cover in this series, is made all the more worse by the fact that I should have known better. If you’ve ever listened to an episode of Coder Radio in which I mention the iOS Simulator, then you know that I always warn developers to never trust it; the reason for this is that your code isn’t really running on iOS but rather a pseudo-OS X platform. Never ever trust the simulator. Ever.

Taking a step back, let’s look at the issue. I have a number of audio files and they all play just fine on the iOS Simulator, but my beta testers are reporting that they can’t hear any audio files at all on their devices. This is odd to say the least. I scoured my AVAudio implementation looking for the most obscure of bugs but still found nothing. The good news, using “good” very loosely, is that I was able to delete the app and reproduce the bug myself.

After a few hours of pouring over LLDB and various Test Flight logs, I found that everything looked fine: the audio URLs (the audio is coming from a server) all looked fine, there didn’t appear to be any NSZombie related issues, and the audio files themselves seemed fine.  I was totally lost.

Then I remembered something based on an offhand comment I found on a StackOverflow post — the simulator uses OS X’s audio subsystems which differ from iOS’s. In particular, OS X has access to a few more audio codecs than iOS. As it turns out, the API I  was interacting with has different calls that request the audio in different formats. I changed the call to request the MP3 formatted files and was good to go. Facepalm.

I hope you’ve enjoyed taking a look at another programming pitfall and please do leave any comments on Google+ or Twitter. Also, please keep in mind that I am always available for consulting projects.

Bad Synchronous Call! Bad!

Back in the dark old days of Commodore 64 and its brethren computers were pretty much all synchronous; instructions executed one after the other, one at a time. It was a simpler time. Users did expect a responsive UI during slow operations or so I have been told. Wondering what a slow operation is? Well, how about any sort of IO? or large data transfer? or how about just pretty much any data transfer over 3G? Of course, there are other cases of long operations but no need to open old wounds….

Now I can hear you already, arguing ‘the platforms today are so much more multi-threaded / multi-core by default I don’t have to worry about writing asynchronous code.’ Well sir (or madam), you are dead wrong. It is true that or more modern platforms have done a lot to run their internal operations in a thread safe / optimized way, but there are a lot of cases where YOU MUST make your code asynchronous. The platform is not going to waive a magic wand and make your operation run asynchronously. Need an example? Here you go:

UIImage* image = [UIImage imageWithData:[NSData dataWithContentsOfURL:someURL]];

Looks reasonable, no? Wrong! That code though deceptively simple is actually very bad. Let’s take a look at what is actually happening in this little one liner:

NSData* imageData = [NSData dataWithContentsOfURL:someURL];
image = [UIImage imageWithData:imageData];

Still pretty simple, right? That’s the exact same functionality as the one linear above and the same problem. Take a closer look at that first line. Pretty simple, right? All it is doing is reading the contents of a URL (in this case an image) downloading the data, and creating an NSData object from it. See the problem yet? That is all happening in order synchronously. If the network is slow or the server is slow to return, the UI on your lovely app will lock for a second or so. Bad UX. Very bad. It is important to note that this code is using one of the most direct ways to create an image from an external service provided wholly by Cocoa. Not to hit this too hard, but the platform vendor’s framework (Cocoa in this case) is not doing anything magical to prevent this from happening. Your code is causing the problem and you have to fix it — yourself.

Oh? You actually want to see a correct version of this code? Well, ok. What needs to happen here is that the image needs to be dealt with asynchronously. I like to use the popular (albeit somewhat dated) iOS / Mac library ASIHTTP to accomplish this. For one request it is really easy:

ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:someURL];
__weak ASIHTTPRequest* _request = request;
[request setCompletionBlock: ^{
UIImage* image = [UIImage imageWithData:[_request responseData]];
}];
[request setFailedBlock: ^{
// handle failure
}];
[request startAsynchronous];

Not too bad, right? Just a quick walkthrough. If you are new to Cocoa you might not be familiar with the concept of blocks. It’s a pretty big topic and worthy of its own post (or series of posts) but they are similar to closures in other languages. Also, the “__weak” is to prevent a retain cycle for developers using ARC; if you are not using ARC in your new iOS or Mac OS X projects, consider it. Ok so what if you have to deal with a large number of images for something like a UITableView full images? Well check this out:

ASINetworkQueue* q = [[ASINetworkQueue alloc] init];
[q setDelegate:self];
[q setQueueDidFinishSelector:@selector(networkQueueDidFinish:)];
[q setRequestDidFailSelector:@selector(requestDidFail:)];
[q setRequestDidFinishSelector:@selector(requestDidFinish:)];
for (int i = 0; [someArrayOfImagesURLS count]; i++) {
ASIHTTPRequest* imageRequest = [ASIHTTPRequest requestWithURL:[someArrayOfImagesURLS count]];
[q addOperation:imageRequest];
}
[q go];

// delegate methods
- (void) requestDidFail:(ASIHTTPRequest *)request {
// something bad happened -- handle it!
}

- (void) requestDidFinish:(ASIHTTPRequest *)request {
UIImage* image = [UIImage imageWithData:[request responseData]];
// do something with the image
}

- (void) networkQueueDidFinish:(ASINetworkQueue *)q {
// do something magical when the queue is done
}

Ok so all that has changed is that we iterate through an array or URLS for the images, create ASIHTTPRequests based on them, add them to our operation queue, and deal with the delegate methods. One thing of note is that there are separate callbacks for when each individual request finishes and for the queue itself and if you fail to implement one of those required delegate methods your app will crash.

Hope this helps someone. I am going to be posting more about writing asynchronous code to best take advantage of the multi-threaded / multi-core nature of our favorite platforms. Stay tuned for a look at this type of thing on Android! Find me on Google+ or Twitter if you have feedback.


Programming Pitfalls: Bit in the ARC

Apple’s ARC (automatic reference counting) for Mac and iOS devices is intended to make Cocoa development easier. For the most part it does. However, in using it I have encountered a bit of a pitfall: by default the compiler does not optimize your code in debugging but uses its most optimized setting for release.  What does this mean? Well, the more you tell it to optimize your code, the sooner it will release objects for you, which can lead to some issues. To be clear the default settings for each mode are zero optimization and the most possible optimization respectively.

Basically,  a lib I was using was working fine in testing but was throwing BAD_ACCESS errors when running in release mode. After over an hour and half of investigating I found:

The screenshot is showing XCode’s “Build Settings” screen, where you can clearly see that a different level of optimization is being used for the two different modes.

From here the fix is pretty easy: tune down that optimization level. Alternatively, you could dig into the code that is having the issues, but that might turn out to be something of a premature optimization for most needs.

Hope this helps someone. You can find me on Twitter or Google Plus.

Programming Pitfalls: NSAutorelease Pools on iOS 4.X

iOS 5 has brought a lot of quality of life improvements in terms of memory management and the general iOS development workflow, assuming you are on the latest tooling. However, nothing is free and there seems to be a little bit of a pitfall that you might hit if you are testing predominantly on iOS 5.x: iOS 5 seems to deal with autorelease pools a bit differently than 4.

Here’s the situation:

- (void) viewDidLoad {
  [super viewDidLoad];
  [self performSelectorOnMainThread:@selector(yourMagicalMethod) withObject:nil     waitUntilDone:NO];
}

- (void) yourMagicalMethod {
  // do some magical stuff and set some objects to autorelease
}

This will run fine and without complaint on iOS 5. However, on iOS 4 it throws some errors in the log at runtime regarding no autorelease pool being set and leaks every object you set to autorelease in yourMagicalMethod. If that isn’t enough to crash your app, then your app will be in a highly unstable state and will be prone to crashing the next time you do something even somewhat intensive, such as call the camera.

I did some sleuthing with Instruments and found that yes on 4.x those objects are all leaked and yes they are not on 5. Luckily there is an easy solution that doesn’t involve any crazy version checks or (God forbid) compiler macros:

- (void) yourMagicalMethod {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// do some magical stuff and set some objects to autorelease

  [pool release];
}

That’s it. All you need to do is create an autorelease pool in scope and release it. Both iOS 4 and 5 will be happy. I don’t know why this issues exists and I’d love to find out if you do. If you have questions or comments, I am on Twitter and Google+.

Simply Loading TableViewCells from a Nib

UITableViews drive a significant portion of iOS apps. Apple has provided some pretty great tools for developing decent looking apps based on them, but there are times when you might want to do something a little more stylish than what iOS provides. That’s when you probably consider writing your own UITableViewCell subclass or at least adding a category to UITableViewCell, though I find that is probably the less appropriate option in most cases. Getting your cells to look just right can be more than a little time consuming. Luckily, there is a bit of a shortcut you can take: loading the cells from a nib.

Before I show you how to do this, you should know going in that there are some drawbacks to doing this and that this is not an appropriate solution a some cases. Loading cells from a nib is less performant than just drawing the entire thing in code. Generally, you would not want to do something like this in a resource intensive app, such  as a game for example.  Ok, now that we have gotten that disclaimer out of the way, let’s get back to the point:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
   self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) {
       NSArray* nibContents = [[NSBundle mainBundle] loadNibNamed:@"SpecialCell" owner:self options:NULL];
       NSEnumerator* nibEnumerator = [nibContents objectEnumerator];
       NSObject* nibObject = nil;
       while ((nibObject = [nibEnumerator nextObject]) != nil) {
           if ([nibObject isKindOfClass:[SpecialCell class]]) {
               self = (SpecialCell *)nibObject;
               break;
           }
       }
   }
   return self;
}

The above code presupposes that SpecialCell is a subclass of UITableViewCell; I omitted the header for the sake of brevity. So, let’s get the obvious stuff out of the way. This method is overwriting initWithStyle and yes you could write a second method rather than overwriting that one. We have the normal if (self) check that we see in inits. All pretty much standard.

Ok, so what is actually loading the nib? Well, if you look nib is being loaded and its contents are being placed in the nibContents array. Once the the contents of the nib are all in the array, an enumerator is created based on it. After that we simply loop through all of the objects, assign self the the one whose class is SpecialCell and return it.
Pretty easy, right? Just keep in mind that this can be a source of slow down on your table and may not be an appropriate solution for your app, but this can be a good time saver for prototypes or non resource intensive apps. If you have any feedback I can found Twitter or Google+.

Objective-C Singletons

A singleton is a way for developers to keep one and only one object of a class in existence for the entire lifecycle of an application; the nitpicky among you will note that there are portions of an app that might not have any instances of a singleton object, since it is common practice not create the singleton until you need it. Some example cases that you would use a singleton include: a player object for a game, a user object for a social app, and a shopping cart.

Creating a singleton is pretty simple:

@interface User : NSObject
static User* userSingleton;
+ (User *) userSingleton {
  if (!userSingleton) {
    userSingleton = [User alloc] init];
 }
return userSingleton;
}

Let’s walk through this. You declare a static user object called userSingleton, then whenver [User userSingleton] is called you check to see if that object is not null and either returns the existing object or alloc/inits the object, then returns it.

Ok, so that’s all well and good, but how do you actually use it. Well it’s simple. Let’s say our User class has a name property. We could access that with our singleton via:

[[User userSingleton] name];

Need to set the name?

[[User userSingleton] setName:@”Luke”];

Not bad, right? Also, note that all other messages can be sent via the same syntax, so:

[[User userSingleton] someMessage];

For those of you coming from a Java background sending a message in Objective-C would be called calling a method in Java.


Now you may have noticed that the above user object will have null values for all of its properties when it is first created and might want to be able to set some default values. For this example let’s assume that User has a few properties (name, fathersName, and saberColor):

static User* userSingleton;
+ (User *) userSingleton {
  if (!userSingleton) {
    userSingleton = [User alloc] init];
    [userSingleton setName:@”Luke”];
    [userSingleton setFathersName:@”Anakin”];
    [userSingleton setSaberColor:[UIColor blueColor]];
  }
return userSingleton;
}

As you can see, if the object is null, then we create it like before, but now we set some default values to its properties. Naturally, these values will be overwritten when you call their respective setters:

[[User userSingleton] setSaberColor:[UIColor greenColor]];


That’s pretty much all you need to know to get started with singletons in Objective-C. One thing of note about my code samples is that they assume you are using ARC, but you are not they still work; you will just have to include the proper retain/release calls. Hope this helps, please get in touch on Twitter or Google+.

***Update: An eagle-eyed reader pointed out to me that my sample here does not prevent you from creating a new instance of the object. So, if you created the object as I recommend but did User* badUser = [User alloc] init] you would have a new user object.  To get a true singleton (ie only one instance allowed) you would have to override alloc and a few other methods; The eagle-eyed reader recommends you see: http://cocoadev.com/index.pl?SingletonDesignPattern. Also, a few of you have gotten in touch with me asking why I did not show the GCD / block pattern. The reason for that is that I feel that it is too advanced for beginners but will write it up shortly. Thanks for all the feedback.

NSTask 100

I’ll get right to the point here. Reinventing the wheel is bad. Period. End of sentence. If you have a requirement that can be met by an acceptably licensed open-source software project and you are not using that project, then you are likely adding unneeded complexity to you project; you are certainly adding development time and therefore cost to the project.

Recently, I have been spending a lot of time developing an internal Mac OS X application for a client. This is a large scale application that has a lot of very specific requirements; these requirements range for media conversions to data sorting. After spending a little time trying to create my own internal Objective-C classes for many of these functions, I started wishing that I could just call down to OS X’s underlying UNIX utilities.

Then I remember something that I had read in a Cocoa book almost a year ago: NSTask. I popped open Dash and got to reading the documentation on this awesome class. Basically, you can use NSTask to call down to a UNIX utility, pass it parameters as you would from the terminal, and deal with its output.

Let me show you an example of how this would work with one of my favorite GPL’d tools: LAME.

NSTask* lameTask = [[NSTask alloc] init];
[lameTask setLaunchPath@”PATH_TO_LAME”];
[lameTask setArguments:[NSArray arrayWithObjects:@”CRAPPY_AUDIO_FILE.wav”, @”NEW_AWESOMENESS.mp3”, nil]];
[lameTask launch];
<

That’s it. It really is that simple. Keep in mind that for this to work the user needs to have LAME installed on his box already for this to work and distributing GPL’d software with proprietary software can be legally jeopardizing, so read those licenses. Also, MP3 is an IP encumbered format and I am not suggesting that you should violate IP by using the above code; I am only using it as a fun and easy to understand example of using NSTask to call a UNIX tool/

I hope this helps somebody out, if you have any questions or comments, please let me know or comment below.

All About ARC

ARC (short for automatic reference counting) is one of the most talked about and interesting additions to the iOS developer toolchain. However, in recent conversations with other developers I’ve found that there are a lot of misconceptions surrounding the technology. Hopefully, this clears up some of the confusion.

The first mistake that people often make when talking about ARC is that they equate it to garbage collection in languages such as C# and Java. This is simply incorrect. Boiling it down to its most basic explanation, a garbage collector runs in your application and checks to see what objects are no longer needed and removes them. This means that garbage collectors are very convenient for developers, but they take a small (depending on the implementation) amount of resources themselves. ARC is a special setting that can be set from within XCode that tells the compiler to insert release statements for you. So, this means that when you have ARC enabled the compiler is following the same retain / release rules you would normally follow for your own memory management, but this only happens at compile time, so there is no performance hit and you never see that statements themselves. This is useful because the compiler is far less likely to make a mistake than the average developer, especially in tricky situations, such as those that arise with multiple autorelease pools.

The second common belief developers hold surrounding ARC is that all their projects should use it. For new projects, this makes sense as long as you don’t mind targeting iOS 4.3+. However, converting legacy projects to use ARC can be a little hairy and like all magic that is made for developer convenience, when ARC causes a problem, it tends to be a tough one. Of course, that is not always the case and you mileage will certainly vary, but this is something to consider before hitting that shiny convert button.

Lastly, a number of developers that I have spoken to are under the mistaken impressions that all libs or external projects that you project is taking advantage of must be compatible with ARC for your codebase to use ARC. This is not the case. You can toggle ARC on and off for individual projects within your project (I know that sounds weird to me too) and safely use your legacy C libs or non-ARC Objective-C frameworks.

Overall, ARC is a great addition to the iOS developer’s toolbox, but it is like any other new technology and should be understood for what it is and adopted when appropriate.

Tutorial: Recording Media with QTKit for Mac OS X

Mac’s are very popular among creative professionals ranging from the user interface designer who designed your favorite iPhone app to the starving videographer who is just starting to break into the field via Youtube and Vimeo.

Recently, I have taken the plunge into Mac OS X application development and had a need to implement a number of multimedia functionality into the application: recording video via a built in or external camera and recording audio via the built in or external microphone and a number of other things. One way to this with a minimum level of effort is to use Apple’s QTKit; for those not familiar with Apple technologies QT stands for Quick Time which is Apple’s entrant into the multimedia player space.

There are number of things that you can do with QTKit but I am only going to focus on recording video and audio for this post. Additionally, I am making some assumptions about you, my reader: I assume that you know how to add a framework to an XCode project, I also assume that you know at least a introductory level of Objective-C and will not providing samples of what I consider boilerplate code.

Ok, so let’s get to it. Once you have imported QTKit, open the header file the class that you want to deal with the recording and declare some variables like so:

QTCaptureSession* session;
QTCaptureMovieFileOutput* fileOutput;
QTCaptureDeviceInput* videoInput;
QTCaptureDeviceInput* audioInput;

You are also going to want to create an NSButton to receive a click from the user. Jump into your implementation file and it’s time to start using those objects and making some more to actually determine how capable the system is of recording media. The following code is probably best put in an awakeFromNib or some similar function:

QTCaptureDevice* videoDevice = [QTCaptureDevice defaultInputDeviceWtihMediaType:QTMediaTypeVideo];
if (videoDevice) {
videoInput = [[QTCaptureDeviceInput alloc] initWithDevice:videoDevice];
...
}

Ok, so what we’ve done here is create videoDevice and set it to refer to whatever the default video recording device is for the user’s systems; I would be willing to gamble that you will be dealing with the built in camera pretty much all the time, but even if some silly user out there is doing something well… silly QTKit does a good job of abstracting specific hardware concerns away. I’ve omitted a good deal of code from my implementation above that basically does some safety checks and checks to see if the once device that you have found can also do audio recording and if it can assigns it that duty as well. These checks are mostly BOOL checks and simple checks from the hasMediaType method.

Once you have your input device / devices configured it is time to actual configure how the media will be recorded:

QTCaptureConnection* connection;
NSEnumerator* enumerator = [[fileOutput connections] objectEnumerator];
while ((connection = [enumerator nextObject])) {
QTCompressionOptions* options = nil;
if (mediaType isEqualToString:QTMediaTypeVideo]) {
options = [QTCompressionOptions compressionOptionsWithIdentifier:@”QTCompressionOptions240SizeH264”];
} else If ...
}

Basically, all this code does is create a few objects and loop over some data (I know that’s a pretty hardcore oversimplification but from an implementation standpoint, that is all you really need to know) and then determine how to encode the data to be output. Again, I have shown the code for the video, but the code to encode the audio is very similar.

In the last code chunk I neglected to explain what fileOutput was. Simply put it is an object that, as its name suggests, represents the resulting data after it has been properly encoded. So using that object we can do:

[fileOutput setCompressionOptions:options forConnection:connection];
[session startRunning];

And there you go. Your output will know be encoded to whatever you set in the above loop, so if you kept my code, your video would be in H264. The last line of code should be self explanatory, so I am just going to move on.

Your fileOutput object has one more important job to do: determine where to write the resulting file or if to write it at all. Remember when I recommended that you create a button and an IBAction? Well, you are going to use it now. Put the following code in your IBAction:

[fileOutput recordToOutputFileURL:[NSURL fileURLWithPath:@”/Users/share/movie.mov”]];

Basically, all this does is tell you fileOutput object where to write its data. Fair warning, that last code sample breaks Apple’s new sandboxing rules for the Mac AppStore, so if you want to be in the Mac AppStore, you are going to have to write the data within your application’s own sandbox; see Apple’s developer docs for more details on the new sandboxing rules. Also, the keen eyed coder will notice that my samples require manual memory management, but I did not include and release statements. Be sure to manage your memory properly.

If you have any questions or comments, sound off in the comments. Additionally, I can be reached on Twitter @dominucco.