On indie iOS and Mac development.

My Thoughts on RubyMotion

May 7th, 2012

RubyMotion was announced this past week. In my world view, creation is better than talk, and there is no doubt that the developers of RubyMotion should be congratulated for shipping something. That’s more than a lot of people do and is worthy of great respect.

That said, my initial reaction was less than enthusiastic and received a fair amount of push back from my Twitter followers. To summarize my opinion, I feel that although it’s an admirable effort, and worthy of congratulations, I simply cannot recommend to new developers coming to the platform that they use a technology such as RubyMotion to build apps for iOS.

Sadly, 140 chars is simply not enough to lay out my reasons for this opinion, so instead, I thought I’d save up my thoughts and lay them out in a blog post. If you are a fan of RubyMotion, or MacRuby, then I’ll save you the effort of reading: Use them if they work for you, but in my opinion, it would be less effort to simply learn Objective-C.

What is RubyMotion

RubyMotion is a toolchain which enables you to write apps for iOS using Ruby. The toolchain interfaces directly with Cocoa Touch, so you still use the same Cocoa Touch API, but you use it through Ruby. Apps are created on the command line, and developers may, in fact are encouraged to, avoid Xcode altogether. RubyMotion is built on MacRuby, which, unlike the long-since-retired Java/Objective-C bridge uses the same runtime as Objective-C, so it has the advantage of always having access to the latest library APIs as soon as they ship. There is no need for the MacRuby distribution to track OS updates in lock-step motion.

So if you’re a Ruby developer who doesn’t know Objective-C, then this is great, because you get to program for the latest, hottest platform without having to deal with all that messy, icky Objective-C stuff.

Well, almost…

Keeping up to date

My experience in the past with technologies like RubyMotion is that they have difficulty staying up to date. When I pointed this out on Twitter, several people took issue with this assertion, rightfully claiming “But it’ll always be up to date with whatever the frameworks give you!” To which I say, “That’s not the stuff I’m worried about being up to date with!”

Ruby is a moving target

First, Ruby itself is a moving target, and Mac OS X doesn’t always ship with the latest greatest stuff. So this means you’re going to be always compiling and upgrading Ruby every time you update your OS. I have never seen a community so fond of deprecation as the Ruby community seems to be. Granted, tools like rvm and the like make this job a bit easier, but it is an additional level of complexity that can be a hassle.

Objective-C is a moving target

The bigger issue, I think, however, is that Objective-C is an actively growing language. Not just at the framework level, which is what most of the RubyMotion fans point to when they talk about compatibility, but also at the lower syntax level. Blocks, for example, are a very recent addition to the language.

RubyMotion can’t help but fall a bit behind when low level features like blocks are added to the Objective-C language. Although it’s easy to criticize Objective-C and talk about how it’s only adding features Ruby has had for years, that’s irrelevant. The point is that supporting new language features like this will always take effort and modifications to RubyMotion. Since Apple has (presumably) more engineers working on improving Objective-C than RubyMotion has on improving RubyMotion, that means that RubyMotion will always be slower to adopt new language features than Objective-C is in adding them.

Debugging and tools

I’ve written full apps using PyObjC and other technologies similar to RubyMotion. When I did, I inevitably reached a point where my frustration would get the better of me. Surprisingly, it was usually a result of having to debug the code I’d written in Python or Ruby.

Say what you will about gdb and lldb, they are still both lightyears ahead of their ruby equivilents. The same goes for the profiling tools that Apple provides. Scripting language advocates like to promote the idea that although their languages may be slower than compiled code, you can always redo slow portions of your code in C, C++, or in our case, Objective-C. The problem, however, is the tools to find out what portion of your code is slow are absolutely horrendous. Compare them to Instruments, which is a spectacular profiling tool by any measure, and you’ll see what I mean.

Xcode has its detractors, the RubyMotion developers among them, but whether you like Xcode or not, it is the designated tool that Apple has blessed for doing iOS development. Apple invests a substantial amount of R&D in this tool, and it’s ridiculous to think that it’s going to stay where it is. In fact, I would expect some of the upcoming improvements to iOS development to come in the form of more GUI oriented tools. A recent example of this is the introduction of StoryBoards. Imagine when tools like this become available!

Now, it’s fine and dandy if you’re a neckbeard and you eschew all GUI tools in favor of your l33ta55 vi/emacs skillz. I totally appreciate how amazingly productive you are with your hotkeys that let you do everything without moving your hands from the keyboard. I’m sure you’ll have a wonderful old age with your fingers curled and umoving thanks to RSI. What you don’t realize is that having a variety of movements (ie: going back and forth to the mouse occaisionally) while slower, is actually a healthier way to work. I know this because I was once you. I used to use emacs for everything, and command line for everything. And I had the wrist pain to prove it. Since I switched to Xcode and using more GUI tools, my wrist pain has totally disappeared.

Regardless of that, however, the key takeaway here is that overall, the tools provided by Apple are the best for what they do, will continue to improve, and may even, in the future, negate whatever perceived improvement you’re getting from using a higher level language. In fact, I’d go so far as to say that, Xcode aside, even Instruments, llvm, and lldb provide enough value today to make the gains you get from a higher level language irrelevant.

Not having to learn Objective-C

Finally, the big one.

I’m going to put this in bold here so it stands out and you remember it. It may be the most important part of this blog post. Here it is:

If you think that using RubyMotion is going to make it so you don’t need to learn Objective-C… you are wrong.

Remember up above where I said that RubyMotion uses the same runtime and Cocoa Touch API as Objective-C? Well guess what that means?

That means that the vast majority of the difficulty in learning to program for iOS, that is, learning the Cocoa Touch API, is still gonna be there for you… but now, thanks to the fact that you’re using a non-standard language to do it, you won’t be able to directly use any of the huge amounts of already existing sample code, courses, or reading material available across the Internet.

Instead, you’ll need to learn the ins and outs of Objective-C just to translate those examples into something you can use and then figure out how to use it from Ruby, because, it’s not gonna feel like straight up Ruby. It’s gonna feel like some weird amalgamation.

In fact, you’ll probably need to know Objective-C and the Cocoa Touch API better than a newbie Objective-C programmer, because you really will need to understand the code. Newbie Objective-C coders can probably get by just cutting and pasting, but you’ll need to translate it.

That’s harder than you might think.

Conclusion

So the point here is that the benefits of using a language and toolset other than Objective-C for iOS development simply are not there.

Please don’t get me wrong, I love Ruby, I love Python, I’ve written thousands of lines of code in them. In fact, my affair with Ruby started before I’d even heard of Objective-C! I started using Ruby in 2000. Yes, before Rails even. (Yeah, that’s right, I’m hip like that. @@ ) I think Ruby has it’s place, but iOS development isn’t it. Objective-C, Xcode, and Instruments are the right tools for that job. Similarly, Java is the right tool for Android. C# for Windows. Ruby or Python for server side scripting and automation. I think this is the only truly objective view that one can have.

My advice to new developers who want to write for iOS and who are on the fence about RubyMotion? In my opinion, don’t use it. Objective-C isn’t really that hard, and the fact that you already know a language (Ruby) will only make it easier. Saying you don’t like Objective-C based on superficial issues like brackets is simply xenophobia. You’re smart, you’ll get used to it.

My 10 Minute Review of PaintCode

March 15th, 2012

The Internets are all atwitter about PaintCode. A new app which claims to allow you to draw shapes and graphics using their painting app and have it generate Objective-C Core Graphics code to display those same graphics in your iOS or Mac App.

Although PaintCode says that they’ll have a free demo out soon, a lot of indie developers like me are hesitant to invest $80 in a tool sight unseen. We all have been burned too often by magic code generating tools that were supposed to make our jobs SO much easier, but in the end, just hurt us by generating unmaintainable code that we didn’t understand. That said, I, being the selfless fellow that I am, decided to take one for the team, bought it, and well… here we are.

It should be noted that this is not the first app of it’s kind. Opacity by Like Thought can also, reportedly, generate Core Graphics code from drawings you do in it. I downloaded Opacity when I downloaded PaintCode, just so that I could be fair and balanced. I’m not going to focus too much on Opacity. They have a free demo, you can download it for yourself. However, in cases where I think a useful comparison should be made, I will do so.

First up… does it work?

Yep, it sure does. Its pretty damn cool.

PaintCode Main Window

You draw stuff in the window, and the code to draw that in Core Graphics appears in another panel below it. I really like this model. I like it because I can just cut and paste this into my source code. I’m not generating a whole file, I just want the tiny code snippet that will draw the specific thing that I want to draw right now. It is simple, and does this one thing well, and from that perspective, I’d say the app is a success.

But the code… is it good?

Well, the code is decent. It’s generated, so it’s not hand optimized for your use case. You’ll want to edit it when you put it into your source. This is to be expected.

It does not optimize for multiple identical objects, meaning it doesn’t generate loops, or functions, or anything fancy like that whatsoever, it just generates the bare minimum basic Core Graphics drawing code you need to draw whatever it is you um… drew on the canvas.

This might actually present a problem for using this long term since the code you actually use from it will be different from the code it generates (because you will edit it). I’d argue, however, that this is simply an unreasonable expectation. The purpose of this app is to make code snippets that you will use in your app, not to generate your app.

With regard to the code itself, well, again, it’s basic. I was a bit surprised, for example, that the code didn’t seem to use CALayer attributes very much, like for example to draw shadows. This isn’t a huge deal, this is one of those things I’d do, but others might choose differently. There might be some technical reason for the style of code they generated and the API they used, but if there is, I don’t know what it is.

@schwa asked on Twitter:

If the code generated isn’t template based then there’s no fixing of bugs in it.

and the answer is, no, the code is not template based, nor does it appear that there are any preferences that would enable you to modify the code generated. This might be an issue for you if you’re expecting to be regenerating the code from the app and putting it in your app over and over.

I would say that the ability to customize the code output (via templates or preferences) is one of the biggest areas that PaintCode could improve, but it’s not a show stopper for me. I understand the limitations, and would rather have a tool like PaintCode in it’s current form without the code generation customization, than not have it at all.

A side note here is that PaintCode should not be used as a crutch. You need to understand the code it is generating. If you do not, I would actually advise not buying it. Go write some hand crafted Core Graphics code for a year or so, THEN come back and use PaintCode to help make your workflow a little faster and easier.

Can I use it to build my GUI and make it all resolution independent and stuff?

No, I wouldn’t do that. The developers (Pixel Cut) seem to imply that PaintCode will free you from the tyranny of image based GUI design and make your apps resolution independent! (My words, not theirs) This might be true if you designed all your icons and graphics using it, and then generated modules directly into your source folder and were used in your project.

The problem is, because of the lack of customization of the code generation, this kind of app will not be something you will use to regenerate your graphics repeatedly. You’ll use it once, to get a basis for hand optimized CG code, and then you may return later and use it again, but then you’ll need to hand optimize it again. That’s a bit of a pain.

If your requirements are simple, this model works… if you are generating your whole UI this way, it does not.

I would argue that PaintCode stands on it’s own without this capability. Honestly, I don’t think it’s possible to make an app that would generate perfect customizable drawing code even using templates. I think this is an impossible problem to solve, and I kinda hope that Pixel Cut doesn’t try too hard at it. Improve the code generation customization options… sure… but you’re never gonna get it perfect, and you’re never gonna satisfy everyone. When you can do that, we won’t need programmers anymore.

Are it’s graphics tools good? Is it really a painting app?

It’s tools are decent, but not great. Very much a 1.0 feature set. A solid 1.0 feature set, but a 1.0 nonetheless. It does not have layers, or grouping of objects, but it does have bezier curves, rounded rects, and interestingly, the ability to join and split objects, which is something I never would have expected in a 1.0. It has gradients, and shadows and inner shadows and things, all the basic tools… but it won’t replace Photoshop or Illustrator any time soon.

All that said, Opacity has a much wider selection of tools and is clearly a much more graphic tool intensive app, but I’ll be honest… I fired up Opacity, and there was SO MUCH STUFF that I actually didn’t even know where to start. PaintCode, on the other hand, was up and running and was able to generate some basic CG code in minutes.

The interesting dichotomy here is that PaintCode has no help file, no instructions, no preferences, nothing. It’s so simplistic, that my first impression was that it’s simplicity was an indication that it wasn’t worth it’s price. Opacity, on the other hand, has help, and tutorials, and videos, and goodness knows what else. All that and, for me, PaintCode was usable, and Opacity was not.

FWIW: I actually still haven’t figured out how to generate CG code from Opacity. I’m told it’s in there, but I can’t find it.

Can I import or export graphics files?

No, basically, you cannot. It does support exporting PDF or NeXT TIFF files, but as pointed out on Twitter, import/export of svg files would make it a much more useful app. Designers like their existing apps, and if PaintCode wants to play in this space, I think it needs to be better about interoperability. This is definitely a minus.

Interestingly, it might also be fun to be able to paste Core Graphics code into PaintCode and have it draw the result on screen, be able to modify it and have the code change according to the modifications! That would be fun. For now, however, the code panel is read-only.

So, to sum up…

It’s a good app that does one simple thing well, and for that one simple thing, IMO, it’s worth $80, yes.

As Brian Webster pointed out if it saves $80 worth of your hourly wage, then it’s worth it, and for me, I think it will.

I can easily see spending an hour crafting CG code that I could draw up in PaintCode in 5 minutes. Would I return to it later to tweak that code? No. But I’d still have gotten my money’s worth out of it.

Compared to Opacity… well, I wanted to love Opacity… I originally looked at Opacity more than a year ago, for exactly the use case I want PaintCode for. Then, as now, I just couldn’t figure it out. I couldn’t really determine if it’d let me generate the code I wanted, and even if it could… it actually seemed like it would be more effort to design the graphics in Opacity than to just write the Core Graphics code by hand. It seems as if Opacity is a so-so drawing app with the ability to generate Core Graphics code tacked on somewhere.

PaintCode is the opposite. It’s a focused programming aide and a welcome additional tool in my arsenal.

Update

I left off a sample of the code it generates. Here’s the code it generated from the screenshot above.

Update 04/04/2012

They now have a free trial. Go check it out!

Dismissing a Popover from a UISplitViewController

February 28th, 2012

This is more or less a “WTF? Is this really how hard this is?” kind of a post. It wouldn’t fit in < 140 chars, so it’s not on Twitter. I encourage you to comment if you know a better way to do this.

The Problem

The HIG states that we should avoid having multiple UIPopovers displaying at once… so when one displays, another should disappear. Sadly, when using a UISplitViewController it appears that the provided UIPopoverController for the master view controller does not do this automatically. Meaning, if you have the device in portrait mode, and you bring up another popover, the master view controller popover does not automatically dismiss.

It would be awesome if there was some global flag you could set that would just say “All UIPopOvers… if another one displays, dismiss!” But alas there isn’t. (Hmmm… a category opportunity?)

In any case, it seems, the easiest way to do this is perhaps to have all your popovers send out a notification when they are displaying, so all other popovers can close themselves. This includes the UISplitView popover… but therein lies the rub.

You see, to get to the popover that’s displayed with the UISplitView, you have to set a delegate to handle the method -splitViewController:popoverController:willPresentViewController: and save the popover controller that’s passed. For example:

-(void)splitViewController:(UISplitViewController *)svc 
  popoverController:(UIPopoverController *)pc 
  willPresentViewController:(UIViewController *)aViewController
{
    self.popover = pc;
}

The trouble is, if you do this, you lose the automatic adding and removing of the button to display this popover in your toolbar on your Detail View controller.

The Cure?

The only way to fix this, is to then ALSO implement the following delegate methods:

-(void)splitViewController:(UISplitViewController *)svc 
  willShowViewController:(UIViewController *)aViewController 
  invalidatingBarButtonItem:(UIBarButtonItem *)button
{
    NSMutableArray *toolbarItems = 
      [NSMutableArray arrayWithArray:
      self.detailViewController.toolbar.items];

    [toolbarItems removeObject:button];
    [self.detailViewController.toolbar setItems:toolbarItems];
}

-(void)splitViewController:(UISplitViewController *)svc 
  willHideViewController:(UIViewController *)aViewController 
  withBarButtonItem:(UIBarButtonItem *)barButtonItem 
  forPopoverController:(UIPopoverController *)pc
{
    NSMutableArray *toolbarItems = 
      [NSMutableArray arrayWithArray:
      self.detailViewController.toolbar.items];

    [toolbarItems insertObject:barButtonItem atIndex:0];
    [self.detailViewController.toolbar setItems:toolbarItems];    
}

Which seems like an awful lot of work just to dismiss my damn popover. Surely I must be doing something wrong or missing something obvious. Can someone enlighten me?

Displaying and Searching PDF Content on iPhone

January 20th, 2012

This is actually a repost… this was originally posted on my old blog, which is now defunct. Apparently, it got stuck in some search engine, or linked to from Stack Overflow or something… because I get regular (about 1-2 posts a month) asking that I put it back up. The code here isn’t really that good… it’s kinda a hack… and if you know a better way to do this, please speak up. Furthermore, this is the sum total of everything I know, or ever WANT to know about PDFs… so if your question isn’t answered here, don’t bother emailing me… I have no idea. I’m pretty sure that reading the PDF spec in some way causes your soul to be condemned to an eternity of spanking by the CEO of Adobe… or something.


PDF parsing is a black art that most programmers avoid. “Madness lurks here.” They mumble to themselves quietly. Choosing instead to push their PDFs through UIWebViews and commit other crimes against humanity.

It doesn’t have to be this way, however. Parsing, displaying, and searching PDFs natively and at a low level is actually surprisingly easy if you’re not afraid to get your hands a little dirty with the Core Graphics PDF functions. I’m going to show you how.

Where’s it hiding?

The first thing to know is that in order to do this, you need to use Core Graphics calls. So you need to include the Core Graphics framework in your project, and in any files you want to use the calls, you have to include the CoreGraphics.h header. It’s probably also worthwhile to review the Core Foundation memory management rules.

Once you’ve done this, it’s very straight forward to read your PDF files and display them in a custom view. Let’s take a look at how we do that.

Initializing a PDF Document

To initialize a PDF document, you first have to use the call CGPDFDocumentCreate, passing in the URL to the document you want to open. Since NSURL is toll free bridged to CFURLRef, you can create a CFURLRef just using plain old NSURL like so:

NSString *pathToPdfDoc = [[NSBundle mainBundle] 
                                    pathForResource:@"mypdf" ofType:@"pdf"];
NSURL *pdfUrl = [NSURL fileURLWithPath:pathToPdfDoc];

Then, to create the CGPDFDocumentRef, call CGPDFDocumentCreateWithURL:

CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);

Displaying Pages

So now you have a document. To display the content of the document, you have to get the content in the form of pages. PDFs are already formatted by pages, so all you need to do is get at that data. Fortunately Core Graphics has functions for that too.

To get the total count of the pages in the document, you use the call CGPDFDocumentGetNumberOfPages, which takes as a parameter, the document you created above. So, for example:

size_t pageCount = CGPDFDocumentGetNumberOfPages(document);

Then, to get an individual page to display in your view, you use the function CGPDFDocumentGetPage, passing the document and the page number you want. Like so:

CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);

Note that the currentPage parameter here is 1 based, not 0 based as is the usual case in programming. This means that the first page of the PDF document is in fact, page 1, and not page 0.

Once you have the page, you can display it in your custom view. The only complicated part here is that on iPhone, the coordinate system is flipped compared to the Mac. This causes a problem because the Core Graphics PDF system uses the desktop coordinate system even on iPhone. (It’s yucky, I know.) The solution to this is to flip the page (this can be done in your drawRect method when you go to draw the content):

CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);

CGContextRef ctx = UIGraphicsGetCurrentContext();

CGContextSaveGState(ctx);

CGContextTranslateCTM(ctx, 0.0, [self bounds].size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM(ctx, 
       CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, [self bounds], 0, true));

The key here is the call to CGContextScaleCTM. What we do, is we get the current drawing context, and then we scale it’s coordinate system on it’s y axis by -1.0. This, effectively, flips it upside down along it’s horizontal (x) axis.

Finally, we draw the page into the context using the CGContextDrawPDFPage function:

CGContextDrawPDFPage(ctx, page);    
CGContextRestoreGState(ctx);

So basically, a full on drawRect method for a custom view that draws content from a PDF page, looks something like this:

-(void)drawRect:(CGRect)inRect;
{
    if(document)
    {
        CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);

        CGContextRef ctx = UIGraphicsGetCurrentContext();

        CGContextSaveGState(ctx);

        CGContextTranslateCTM(ctx, 0.0, [self bounds].size.height);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextConcatCTM(ctx, 
                     CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, 
                      [self bounds], 0, true));

        CGContextDrawPDFPage(ctx, page);    
        CGContextRestoreGState(ctx);
    }
}

That’s all there is to it!

Searching PDFs

One of the things that seems to be particularly scary to programmers is searching PDFs. I agree that it’s certainly not pleasant stuff to code, but it’s not hard either.

Now, I want to preface this by saying that I feel this code is a bit of a hack, but it definitely works, and seems to work quite well. Perhaps there’s a better way to do this, and if you know of one, please let me know. That said, however, here’s how I’ve done it.

The first thing to know is that PDF files are made up of operators which delineate the data within them. So, for example, all text in a PDF document is stored as glyphs and prefixed by operators of type either “Tj”, in the case of a string, or “TJ” in the case of an array of strings. Knowing this, you can access the PDF data as a stream and create a scanner which will call callback methods you specify when these operators are encountered. You can then retrieve the data after the operator and use it to build your search corpus.

That probably sounds intimidating, but it’t not. You start out by creating a class that will be your “page searcher.” This will hold the state for your search engine. Here’s the listing for the interface for this class:

#import <Foundation/Foundation.h>

@interface PDFSearcher : NSObject 
{
    CGPDFOperatorTableRef table;
    NSMutableString *currentData;
}
@property (nonatomic, retain) NSMutableString * currentData;
-(id)init;
-(BOOL)page:(CGPDFPageRef)inPage containsString:(NSString *)inSearchString;
@end

Pretty straight forward stuff. We use the currentData member to store the text of the page being scanned. This is a member variable rather than a local variable because we’re going to be using C functions to fill it in. Don’t worry, that’ll make sense in a moment.

The init method for the class actually creates the callback table:

-(id)init
{
    if(self = [super init])
    {
        table = CGPDFOperatorTableCreate();
        CGPDFOperatorTableSetCallback(table, "TJ", arrayCallback);
        CGPDFOperatorTableSetCallback(table, "Tj", stringCallback);
    }
    return self;
}

The arrayCallback and the stringCallback functions are C functions that will be called by the scanner. They’re shown here:

void arrayCallback(CGPDFScannerRef inScanner, void *userInfo)
{
    PDFSearcher * searcher = (PDFSearcher *)userInfo;

    CGPDFArrayRef array;

    bool success = CGPDFScannerPopArray(inScanner, &array);

    for(size_t n = 0; n < CGPDFArrayGetCount(array); n += 2)
    {
        if(n >= CGPDFArrayGetCount(array))
            continue;

        CGPDFStringRef string;
        success = CGPDFArrayGetString(array, n, &string);
        if(success)
        {
            NSString *data = (NSString *)CGPDFStringCopyTextString(string);
            [searcher.currentData appendFormat:@"%@", data];
            [data release];
        }
    }
}

void stringCallback(CGPDFScannerRef inScanner, void *userInfo)
{
    PDFSearcher *searcher = (PDFSearcher *)userInfo;

    CGPDFStringRef string;

    bool success = CGPDFScannerPopString(inScanner, &string);

    if(success)
    {
        NSString *data = (NSString *)CGPDFStringCopyTextString(string);
        [searcher.currentData appendFormat:@" %@", data];
        [data release];
    }
}

As you can see, these will be called when the operators fire. When they do, we pop the data off the scanner, and add it to the searcher’s corpus. The userinfo pointer is actually pointing to our searcher object (based on the fact that we will pass it as the second parameter to @CGPDFScannerCreate@ in the next code). So we can typecast it to a PDFSearcher and then access that currentData member (remember I said it would make sense later?).

The actual search method looks like this:

-(BOOL)page:(CGPDFPageRef)inPage containsString:(NSString *)inSearchString;
{
    [self setCurrentData:[NSMutableString string]];
    CGPDFContentStreamRef contentStream = CGPDFContentStreamCreateWithPage(inPage);
    CGPDFScannerRef scanner = CGPDFScannerCreate(contentStream, table, self);
    bool ret = CGPDFScannerScan(scanner);
    CGPDFScannerRelease(scanner);
    CGPDFContentStreamRelease(contentStream);
    return ([[currentData uppercaseString] 
          rangeOfString:[inSearchString uppercaseString]].location != NSNotFound);
}

Basically, we create a stream from the page data, then use that and our callback table to create a scanner. We then scan the data. It’s at this point our currentData member is being filled with the data from the PDF as strings. Finally, we just search that string for our search string.

Easy peezy.

Note: much of this code is only sight compiled. I pulled it from some code I had, but it wasn’t a straight across copy, so if you find an error, please let me know.

On Preprocessor Macros, ARC and Open Source

January 19th, 2012

I get a few pull requests here and there from folks who want me to convert my blocks code to ARC. Rest assured that I will, eventually, but for now, I’m keeping it ARC agnostic so that people who have not converted to ARC can continue to use it. It’s easier to enable/disable ARC on open source code you download than it is to force people who have not converted to ARC to put the releases and retains back into that same code. Believe me, it’s as annoying for me, as it is for you that said code is not ARC. All of my projects are now ARC, and I wouldn’t code any other way. However, I too, use -fno-objc-arc on my own open source code when needed.

That said, some have suggested some alternative ways of handling open source and ARC. Most of them consist of using preprocessor macros to determine if ARC is enabled and to execute an alternative code path depending on that state. For example:

-(void)doSomething
{
    Foo *foo = [[Foo alloc] init];
    ...
#ifdef !__has_feature(objc_arc)
    [foo release];
#endif
}

I believe that this is a fundamentally wrong way to handle this situation, and I’d like to explain why.

Macros are Ugly

Macros are a very valuable tool. In fact, their purpose is to do exactly what you, young padawan are intending to do. Their purpose is to look at what type of environment your code is being compiled for, and to enable you some level of control as to what code gets compiled in that environment. However, they are also a very blunt, and error prone tool. They have no type checking and code that is cluttered with excessive macro usage is extremely hard to follow. Because of the way that macros work even compiler errors generated from macro generated code is often misleading, or downright impossible to read. Using macros all over your code like this to execute alternative code paths is fraught with peril.

In some cases, rather than sprinkling these #ifdefs all over the place in their code, some folks might simply think that they should #define their own retain/release replacements that do the switching between ARC and non-ARC for them. I just can’t bring myself to think that this is a better solution. In fact, I think it’s worse. Sprinkling MY_RELEASE(foo); all over is disconcerting to read, and will result in wasted time for other coders who not only can, but should check to see what MY_RELEASE actually does.

In addition to these, the de facto standard of naming preprocessor macros in all caps results in a codebase that more closely resembles a CHOCKLOCKed email from your crazy computer illiterate uncle than the delicate prose for which the admittedly verbose Objective-C language is known for being.

This is not to say that preprocessor macros are totally to be avoided by everyone. If you’re building an extensive framework, or if you are a systems level programmer, then you definitely have very justifiable cause for using preprocessor macros. Particularly in cases where you want to maintain compatibility across multiple platforms, or in cases where you need to help inform programmers using your code about how it needs to be used (i.e.: By having macros that show warnings for deprecations, etc.) There is probably also a small minority of programmers who might need to use macros for particularly performance critical code. If you’re one of these types of programmers, then you have my condolences.

In the case of my open source code, it does not fall into any of these categories. It’s simply one or two files, you drop into your project… and away you go. There is simply no need for using macros.

How should ARC be handled in this case?

Simple. There’s an excellent tool that the compiler provides for you. It’s the -fobjc-arc and -fno-objc-arc flags. You can set them on any file in your project just by going to the “Build Phases” part of your Xcode project and setting those as compiler flags on the files in question.

Admittedly, if your framework is very large… this could be an onerous task. In my case, however, these open source components are very small. One to two files at most.

If a user includes a non-ARC file in an ARC project, they’ll get an error when they compile it because retain and release and autorelease are deprecated. So the developer will be informed and be able to take the appropriate action. However, if you include an ARC’d file in a non-ARC project, it’ll just silently compile and leak.

To solve this, you should use a macro, but not to have conditional code paths… you should use a macro to inform the developer that they need to use ARC for that file. Here’s a simple one that I use:

#if ! __has_feature(objc_arc)
#error This file must be compiled with ARC.
#endif

This will prevent the developer from using this file unless they set the correct compiler flags. It’s simple. It’s clean. It’s out of the way, and it doesn’t clutter the code. Put this at the top of your implementation files when you convert them to ARC.

The Correct Way to Avoid Capturing Self in Blocks With ARC

October 15th, 2011

I briefly talked about the new pattern for avoiding memory leaks in blocks that capture self in my previous post about debugging ARC. However, I thought it would be worthwhile to discuss it in more detail to explain the rationale behind it.

To recap, the old pattern to avoid capturing self in blocks looked like this:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __block Foo *blockSelf = self;
    bar.block = ^
    {
        [blockSelf.baz doSomething];
    };
}
@end

The key to this code is that we want to avoid referencing self directly in the block since all variables accessed in the block will be retained by the block. If self owns the block, even indirectly, then this will lead to a retain cycle. Therefore, we use the __block keyword to create a temporary reference to self, which we then use instead of self inside the block. Unfortunately, ARC obsoletes this method by making __block references strong. So we need a new pattern to solve this problem.

The naive approach is to simply grab a weak reference to self as shown in the following code listing:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [blockSelf.baz doSomething];
    };
}

@end    

Really, this is pretty close to what we intended in the old pattern anyway right? We grab a weak reference to self, then use it in our block. No retain cycles. There’s a few problems here, however.

The problems center around the question of what happens when self gets deallocated before or during block execution. It may seem at first blush that this wouldn’t be a big deal since blockSelf is a weak reference and will be zeroed out when deallocated. Since messages to nil are harmless this should be ok right?

Well, it might be ok if ALL the messages in your block wind up doing nothing, but what if self is deallocated on another thread half way through the execution of this block? What if only half of your calls succeed? Could it leave your object in a bad state? Possibly! But there’s a worse problem lurking here… Consider the following, slightly different snippet…

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [baz doSomething];
    };
}

@end    

In this case, we’re referencing the member variable (bad) directly, not through the accessor. This still captures self so that it can access the member variable, but when it does so, the runtime does not go through the accessor. Instead it uses a direct C level pointer dereference. In other words, that code compiles to something like this:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [self->baz doSomething];
    };
}

@end    

So, if self gets deallocated in the midst of your block, then it’s possible you could get a crash since you’re directly accessing the member variable via a pointer dereference. This pattern does not obey the rule of messaging nil since you’re not messaging anything.

Because of these problems, the safest thing to do is to get a weak reference to self outside your block, then, at the top of the block, get another strong reference to self so that it doesn’t get deallocated during your block. You can then check to see if you got the strong reference, and if not, just drop out… But if you did, then you should be safe. So, basically, the preferred pattern is now:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        Foo *strongSelf = blockSelf
        [strongSelf.baz doSomething];
    };
}

@end

To be clear, this code does not guarantee thread safety, you may still need to add @synchronize blocks or thread locks, but certainly this is safer than the old pattern and it addresses all the issues shown previously. Code accordingly!

Twitter: The Broadcast Medium

October 13th, 2011

Daring Fireball links to an article this morning about the iOS 5 Twitter integration, and I had a thought:

It seems to me that a big use case of communication that we use today is about sharing “bits”. I don’t mean bits in the computer science way of thinking about bits, I mean bits as in small bits of information. Links, photos, moments, quick jokes, etc. Snippets from the web. And it seems to me that there’s really three “modes” of that communication:

  • Personal and Immediate – Where I want to share this with one particular person right now.
  • Personal and Delayed – It’s not important enough to interrupt my recipient now, but I want to drop off a note to someone for them to read at their leisure.
  • Public – I want to share this with everyone.

It seems like each of these currently has an ideal outlet in iOS 5.

  • Personal and Immediate – iMessage
  • Personal and Delayed – Email
  • Public – Twitter

Are there other “modes” of communication for these snippets that are missing? Feels like this covers everything. And that’s interesting.

Leaking ARC Memory on an NSURLConnection Wrapper?

October 12th, 2011

Wherein I document a case of my ignorance in the hopes you can avoid going down the same rat hole. This is a bit long and rambling, my apologies for that.


As you may know, gentle reader… I have decided to go full steam ahead to converting my apps to ARC.. It’s been a fun process… with it’s own share of complexities, but overall, not too bad. My first converted app, Wasabi, was fairly easy. However, there are a few design patterns I tend to use in my code which skirt the rules of prudence when writing manual retain and release Objective-C, so I was a bit concerned how ARC would handle them. To some, the solutions may be obvious, but they weren’t at all obvious to me, so I’m documenting them here, in case someone else should run into a similar issue. In this case, the issue turned out not to be anything to do with ARC at all, but my tracking it down was educational nonetheless, and useful, I suppose, to talk about.

So, without further ado, I offer you the following manual retain and release Objective-C code:

- (IBAction)buttonPushed:(id)sender 
{
    NSURLRequest *req = [NSURLRequest requestWithURL:
            [NSURL URLWithString:@"http://ax.phobos.apple.com.
                  edgesuite.net/WebObjects/MZStoreServices.woa/
                  wa/wsSearch?term=zen"]];

    JSONWebCommand *command = [[JSONWebCommand alloc] 
                  initWithRequest:req];

    command.completionBlock = ^(NSDictionary *result)
    {
        NSLog(@"Complete. Result: %@", result);
    };

    command.finallyBlock = ^
    { 
        NSLog(@"Finished"); 
        [command release];
    };

    NSLog(@"Starting load...");

    [command start];
}

So, in this code… there’s this JSONWebCommand class, whose purpose is to wrap an NSURLConnection and make it simpler to use and give it some block capabilities. Basically, no need to implement delegate callbacks and things, you just give it blocks instead of a delegate, and it automagically parses the resultant response from JSON to an NSDictionary. Everything is nice and clean. The finallyBlock is always called, regardless of whether the command completes successfully or not. So I used this in the past, as shown here, to release my command ([command release]).

This way I could make this call be very fire and forget. That is, I fire off this command, and I forget about it. I don’t need to hold onto an instance of my command or anything. It’ll call me back when it’s done. It does what I want it to do, and then is released.

ARC converted this code to:

- (IBAction)buttonPushed:(id)sender 
{
    NSURLRequest *req = [NSURLRequest requestWithURL:
            [NSURL URLWithString:@"http://ax.phobos.apple.com.
                  edgesuite.net/WebObjects/MZStoreServices.woa/
                  wa/wsSearch?term=zen"]];

    JSONWebCommand *command = [[JSONWebCommand alloc] 
                  initWithRequest:req];

    command.completionBlock = ^(NSDictionary *result)
    {
        NSLog(@"Complete. Result: %@", result);
    };

    command.finallyBlock = ^
    { 
        NSLog(@"Finished"); 
    };

    NSLog(@"Starting load...");

    [command start];
}

Not much different… but a key issue here… my release is gone!

Of course, that’s exactly what ARC is supposed to do, but WTF! I thought… urm… I’m gonna start it and it’s going to be immediately released! That won’t work!

But it did work. It worked just fine. It appeared all of the cases of this code worked without crash and without issue. How could this be?

Based on my knowledge of what ARC was doing… my command should be deallocated at the end of this method and hence none of the blocks should get called. They were, however, and this was perplexing to me!

I posted a subset of this code on the developer forums, and Greg Parker informed me that if I wanted to get my desired behavior, that is, an object that contains a block which deallocates the object, a good way to do it would be to do:

__block Foo *foo = [[Foo alloc..]];
foo.completionBlock = ^{ foo = nil; };
[foo start];

Essentially specifying an __block modifier for the variable and then setting it to nil in the completion block. Sure enough, this sounded like exactly what I wanted, and is… in other cases than this, probably a perfectly valid pattern to use for this kind of code. Still, I was perplexed that since I had this code sprinkled through my project, why was I not encountering any issues?

Finally, I decided I wanted to track down exactly what the compiler was doing here to educate myself a bit more on how ARC works.

I looked for a tool in Xcode that could give me a listing of where all the retains and releases were being inserted, but I found no joy.

To be clear… since I wasn’t sure what was going on here… I needed to rule out two different issues… First, that the JSONWebCommand wasn’t being over released. If it was, it could ultimately crash my app. Second, that perhaps the JSONWebCommand wasn’t being released. In this case, I might wind up with a leak. The tool to do this in both cases is Instruments.

I knew that the latest version of Leaks is capable now of even detecting leaks that are a result of retain cycles. Retain cycles are among the few cases where ARC might leak memory. This is because one way to get ARC to not release your object is by having it be retained by something that owns it. (i.e.: A owns B which owns A). This is a retain cycle, and ARC does not detect nor prevent it. It’s really easy to make retain cycles using blocks because of the way that blocks capture local variables. For example:

self.foo = [[Foo alloc] ...];
foo.completionBlock = ^{ [self doBar]; };

In this case, foo is owned by self, and the call [self doBar] inside the block also captures self, strongly, within the block. The block is copied by foo, and so any objects captured within it are retained by foo. Since foo is also owned by self, this is a retain cycle. It’s insidious, and not obvious at all when you just look at it. It gets worse too, when you do this:

self.foo = [[Foo alloc] ...];
foo.completionBlock = ^{ [bar doSomething]; };

In this case, bar is a member variable on self. Because it’s a member variable, it still captures self, even though self is not explicitly shown. In other words, this is still a retain cycle.

In the past, we resolved these kinds of retain cycles using techniques that declared a new variable to hold self which is modified with the modifier __block. This is because, in the past, the __block modifier basically made a weak, writable reference on the heap to the variable in question. For example:

__block id blockSelf = self;
foo.completionBlock = ^{ [blockSelf doBar]; }; 

So this would break the retain cycle. Under ARC however, the behavior of __block has been changed! __block variables are now strong, so this will NOT solve your retain cycle! Instead, you should now use the following pattern, which takes advantage of the __weak modifier.

__weak id blockSelf = self;
foo.completionBlock = ^
{
    id strongSelf = blockSelf;
    if(strongSelf)
        [strongSelf doBar];
};

This is the safest way to go, since blockSelf is a zeroing weak reference… when the block executes, if self has been deallocated, then your code won’t crash. Now, if you’re on iOS 4, or Mac OS 10.6, then you don’t have __weak… so instead, you can still get the same behavior that you had before by using __unsafe_unretained in conjunction with __block:

__block __unsafe_unretained id blockSelf = self;
foo.completionBlock = ^{ [blockSelf doBar]; }; 

Just realize that if self gets deallocated your app might blow up. Coder beware!

But anyway… I have digressed… none of this was what was happening in my code. Instruments showed no leaks… and in fact, I could see (by creating a dealloc method on my JSONWebCommand and putting a breakpoint in it) that my command was being deallocated. The only question was if it was being deallocated before I was done with it or not. I then ran the NSZombies instrument on the code… and it showed that it was not being prematurely deallocated. So that left me with the question of… How in the heck is ARC knowing the right thing to do here? So finally, I decided to do some hardcore code spelunking…

I asked around a bit on Twitter, and Stefen Lasser suggested that I use the Xcode debugger to set breakpoints on the ARC runtime methods themselves. You can do this yourself by setting symbolic breakpoints on objc_retain objc_release etc… This can be very noisy, however, so you’ll either want to disable them initially until you hit a specific point in your program, or tweak the conditions on the breakpoint to only break on certain classes. For example, you could set a conditional symbolic breakpoint on objc_retain such that it only fires when it’s parameter is of type JSONWebCommand (this may require some console gdb-fu).

In the end, this is exactly what I did… I basically ran my program up until my block of code… then set my breakpoints on the release/retain methods… and looked up the stack as each was called in turn… and here’s what I found:

This code…

connection = [[NSURLConnection alloc] 
 initWithRequest:request delegate:self startImmediately:NO];

is inside JSONWebCommand… can you spot it? Well it turns out… NSURLConnection retains it’s delegate! I’d gotten so used to delegates that are not retained, I had looked at this code a dozen times and thought “No, that can’t be retaining me… that’s a delegate!” But I traced it up to there, and saw the retain, and I said “What? How can that be retaining self?” I checked the documentation and… sure ’nuff… that’s the way that bugger works. It retains it when set, and releases it when the connection terminates.

So I guess in the end… what did I learn?

Well, I got some practice using the new tools in Instruments. Check them out… they’re excellent! In particular watch the WWDC videos on Instruments. Good stuff.

I also learned a bit about how to trace around inside ARC’s inserted code. Truth be known, I didn’t actually need the release in my block at all even before changing to ARC. So the tool was smarter than me! Less code is always better! I guess the key takeaway here, however, was that ARC wasn’t doing anything surprising. It was doing exactly what it should have done! I would have been far more bothered if it turned out it had some kind of magic it was working. But it wasn’t.

ARC, Exceptions and Objective-C

October 6th, 2011

Reading through the ARC documentation, I came across this passage:

7.6. Exceptions By default in Objective C, ARC is not exception-safe for normal releases…

 

Rationale: the standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.

Emphasis, mine… pointing this out because I think a lot of programmers who come from Java, C++, Python, etc seem to have the belief that exceptions are a tool that should be used in ordinary error conditions.  This could not be further from the truth.  Many of these other languages use exceptions excessively… to the point that they almost become like flow control mechanisms.

In Objeective-C exceptions are meant to be used ONLY in truly exceptional conditions.  Cases where you’re willing to have your app crash if they occur.

Code accordingly.

5 Rules for Writing About Products

August 16th, 2011
  1. Your product doesn’t do things. People use your product to do things.  Think about enabling people to solve problems or achieve goals, then when you write about it, write it from the perspective of showing the reader what she can accomplish.  Ex: Not “Product X does this.” or even “Product X enables you to…” Instead: “Using Product X you can…” “Using Product X you will…” “You can … with Product X.”

  2. Use the active voice. Prefer “You can…”, “You will…”, “You are…”.  Don’t use “You’ll be able to…”, “… by the user.”, or “Here, you’ll find…”. For example, rather than saying “Here you’ll find the settings screen…” say “This is the settings screen.” This technique imbues your words with energy and directness. 

  3. Avoid using the word “user”. Ex: “Users can do x with our product.” Instead, speak directly to your reader as a person.

  4. Ask yourself “What if…” questions… “What if you never had to do … again?” “What if you could… ?”

  5. Follow these rules in all of your communication about your product.  Not just your marketing material, but also in your dialog boxes, alerts, and informational text.