Category Archives: idevblogaday

Mastering Copy and Paste in iOS – Part 2

In part 1 of this series I focused on a very simple locking down of copy and paste in iOS.  Replying NO to canPerformSelector: simply removes the ability to copy and paste from the menu that appears.  Needless to say that can be a little inelegant.  Preventing data leakage can be a good thing but making your app difficult to use is not.  In this post we’ll dig deeper into how you can interact with the copy and paste system to not only prevent leakage but also to work with more than just text.

First let’s get acquainted with some of the components of the copy and paste system.

UIPasteboard

Any time you copy or cut anything in iOS that content gets posted to an instance of UIPasteboard.  The pasteboard is a powerful and type agnostic way to move content from one application to another or between parts of a single application.  The pasteboard is capable of storing nearly any type of data, not just text.

UIMenuController

Screen Shot 2013-05-25 at 3.10.07 PM

UIMenuController is the controller that’s displayed when you highlight text.  Like many other visual controls in iOS this one is pretty locked down.  There are several system items that are added to the menu by default, but you can certainly add your own items via UIMenuItem to do whatever you like.

UIResponderStandardEditActions

This informal protocol is conformed to by descendants of UIResponder to handle the common actions provided by UIMenuController.  UIMenuController will start looking for objects in the responder chain with the first responder moving up the hierarchy until it finds a valid target for the various messages offered by the specified action, such as copy: or cut:.  As we saw in part 1, objects responding to canPerformAction: alter the options provided by the UIMenuController.

The way these three interact isn’t entirely obvious, so we’ll build a sample application that shows placing data in an application specific pasteboard, uses a custom image view that conforms to the UIResponderStandardEditActions protocol supporting cutting and pasting, and adding some custom functionality to the UIMenuController that will appear over our control.  You can download the sample project here.

Setting up the project

We’ll start with a master-detail template.  The master view controller will contain a list of table cells with an image and some text.  The detail view will show the image displayed.  This isn’t a post about table views and interface builder, so I recommend just checking out the sample code if you’re not comfortable with the basic setup.

The custom control

Our custom control will simply be a UIImageView that implements the basic methods for cut, copy, and paste.  To get the implementation correct it’s important to think about what a user’s expectation would be for these three actions:

  • copy – the image is made available to paste into other controls that can accept an image as content.
  • cut – the image is made available to paste into other controls that can accept the image and the image is removed from the current control.
  • paste – the displayed image is replaced with whatever image is in the clipboard.

Implementing these three methods from UIResponderStandardEditActions is actually quite simple:

- (void)copy:(id)sender
{
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setImage:self.image];
}

- (void)paste:(id)sender
{
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    if (pasteboard.image) self.image = pasteboard.image;
}

- (void)thumb:(id)sender
{
    UIImage *thumb = [self thumbnailFromImage:self.image];
    [[UIPasteboard generalPasteboard] setImage:thumb];
}

Easy, right? The copy method will add the UIImageView’s image to the pasteboard via setImage. Conversely, paste will place the image from the pasteboard if it exists. Cut will first call copy to place the image to the pasteboard then clear out the image property.

Adding the UIMenuController

You can run this code now, however there’s no way to actually access the cut, copy, and paste methods.  We’ll have to do a couple of things to get the UIMenuController to appear and allow us to copy and paste the image content.

  1. Add a long press gesture recognizer to our control.
  2. On the action for gesture recognizer we’ll make our control the first responder.
  3. Lastly show the menu controller.

Adding the gesture recognizer is easy.  See the code below for creating the UIMenuController:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
    NSLog(@"long press");

    UIMenuController *menu = [UIMenuController sharedMenuController];
    if (![menu isMenuVisible])
    {
        [self becomeFirstResponder];
        [menu setTargetRect:self.frame inView:self.superview];
        [menu setMenuVisible:YES animated:YES];
    }
}

You’ll notice that the menu controller is a singleton, and this is the only way to instantiate one. If the menu isn’t shown already we’ll make our image view the first responder and display the menu. The critically important step is to register ourselves as the first responder. Remember that the UIMenuController looks for the protocol methods using the responder chain. No other class in our view will respond to these methods. Without setting ourselves as the first responder the UIMenuViewController won’t display at all.

Since we implement cut, copy, and paste, those are the three buttons presented in the menu controller.  At this point you can run the app and successfully copy and paste between the image views.  You can also try jumping out to Mobile Safari, long pressing an image, selecting copy and pasting it into one of your image views if you’re still skeptical.

Adding custom actions to the menu

UIMenuController exposes the menuItems property allowing you to add custom menu items.  The menu items are added after any system items and must be instances of UIMenuItem.  We’ll add a custom menu item to copy a thumbnail of the image to the pasteboard.

Creating the thumbnail is somewhat out of scope for a detailed explanation, but here’s the code below.  It takes an image and returns one-third the size of the original (source material taken from here):

- (UIImage *)thumbnailFromImage:(UIImage *)source
{
    CGSize originalSize = source.size;
    CGSize destSize = CGSizeMake(originalSize.width / 3, originalSize.height / 3);

    UIGraphicsBeginImageContext(destSize);
    [ source drawInRect:(CGRect){CGPointZero, destSize}];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Next we need to create a method on our image view to place the thumbnail on the pasteboard:

- (void)thumb:(id)sender
{
    UIImage *thumb = [self thumbnailFromImage:self.image];
    [[UIPasteboard generalPasteboard] setImage:thumb];
}

Lastly we need to create the UIMenuItem to add to the UIMenuController. The UIMenuItem class is very simple and only takes a title and selector. Since we added the method thumb: to our image view that’s the selector we’ll reference in the menu item.

UIMenuItem *item = [[UIMenuItem alloc] initWithTitle:@"Copy Thumbnail" action:@selector(thumb:)];
menu.menuItems = @[item];

We’ll place this code right before showing the menu controller in the long press handler. You can now run the app, select “Copy Thumbnail” and you’ll see the image pasted is a thumbnail relative to the original.

Note: If you created the nib for the detail view yourself, it’s important the view mode to “center” to avoid the image view stretching the thumbnail when you paste it.

Creating an application specific pasteboard

Up until this point we’ve been using the standard general pasteboard but the SDK provides us other options as well. The only requirement for creating a new one is that the name must be unique. You might also mark a pasteboard as persistent so it will live on after your app terminates. This isn’t particularly useful for a single application but can be extremely powerful for preventing data leakage while still maintaining copy and paste functionality between a suite of apps.

We’ll define the custom pasteboard name in the application delegate’s header file. We can import that into any other file where I need the pasteboard name.

// App delegate header
extern NSString *const pasteboardIdentifier;

I’ll also initialize the pasteboard in applicationDidLoad method on the app delegate:

// app delegate implementation file
// make sure to define the extern
NSString *const pasteboardIdentifier = @"com.pzearfoss.customCopyPaste";

// ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...
    [UIPasteboard pasteboardWithName:pasteboardIdentifier create:YES];
    // ...
}

Lastly, in my image view I’ll replace the generalPasteboard call with pasteboardWithName:create:

- (void)copy:(id)sender
{
    UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:pasteboardIdentifier create:NO];
    [pasteboard setImage:self.image];
}

- (void)paste:(id)sender
{
    UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:pasteboardIdentifier create:NO];
    if (pasteboard.image) self.image = pasteboard.image;
}

- (void)thumb:(id)sender
{
    UIImage *thumb = [self thumbnailFromImage:self.image];
    [[UIPasteboard pasteboardWithName:pasteboardIdentifier create:NO] setImage:thumb];
}

Running the application you’ll now see that you can copy and paste between image views as you could before, but if you try to copy from another app like Mobile Safari it will not paste in our app.

That concludes part 2 for implementing copy and paste, UIMenuController, and using an app specific UIPasteboard. Check out part 3 where we’ll store more complex data types in the pasteboard.

A Quick Gotcha About Blocks

Blocks are a great addition to the iOS SDK and C standard, especially for predominantly event driven applications as we commonly see on the iPhone and iPad.  There’s a quick gotcha that a junior developer here at Mindgrub reminded me of the other day.

While blocks are a powerful tool, if you’re not careful they can start to degrade the quality of your app by introducing retain cycles.  Retain cycles occur when two objects in your application keep strong references to one another.  Take the common table view for example.  Ordinarily, the view controller containing (owning) the table view acts as the datasource and delegate for table, providing the necessary information for displaying the number of rows and supplying cell objects.  If you look closely at the properties on UITableView for datasource and delegate, you’ll see that both properties are declared as “assign” or “weak” in ARC.  This is critical particularly in the case where the view controller is also the datasource/delegate.  If the properties were “strong” or “retain” you could easily wind up in a retain cycle where neither your UITableView nor your view controller would ever be destroyed, thereby leaking memory.

This can happen with blocks as well and it’s not always so obvious.  Let’s say we have a view for which we define a block to handle the user tapping it.  The code might look something like this:


#import <UIKit/UIKit.h>

typedef void(^TapBlock)(void);

@interface TapBlockView : UIView
{
   TapBlock tapBlock;
}

@property (nonatomic, copy) TapBlock tapBlock;
@end

@implementation TapBlockView
@synthesize tapBlock;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
   tapBlock();
}

- (void)dealloc
{
   [tapBlock release];
   [super dealloc];
}

@end

This is a very convenient way of setting up delegate style behavior without having to litter your code with lots of protocol definitions. Now an example of using the view in a view controller:

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapBlockView = [[TapBlockView alloc] initWithFrame:CGRectZero];
    [tapBlockView setTapBlock:^(void) {
        self.someLabel.text = @"You tapped it!";
    }];
}

Everything seems fine right? Nice and convenient.

Not so fast.

Blocks automatically scope capture and retain any object types you use in the block. In this case that variable is “self”. Now we have a retain cycle since self owns the tap view which owns the block which now owns self.

According to Mike Ash, the correct way to handle this is to use a weak pointer (assign) in the block like this:

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapBlockView = [[TapBlockView alloc] initWithFrame:CGRectZero];
    __block typeof (self) weakself = self;
    [tapBlockView setTapBlock:^(void) {
        weakself.someLabel.text = @"You tapped it!";
    }];
}

By using a weak, nonretained pointer along with the __block modifier we’ve broken the retain cycle. For ARC code you should use __weak instead of __block.

There’s two important lessons to be pulled from this. The first is that you always have to be aware of the code you’re writing and look for subtle retain cycles like this one. No amount of automatic reference counting magic can help you in some of these scenarios. The second is that it’s always good to look at code written by others on your team because there’s nearly always something new to learn to refresh on, even if you’re one of the more seasoned developers and the code you’re reading is from a junior dev.

For more information check out these two articles on Mike Ash’s Friday Q&A Site:
9/30/2011 – Automatic Reference Counting
4/30/2010 – Dealing With Retain Cycles

A Lesson In Knowing Your Product

Long ago, in my first year at Mindgrub we were contracted to work on a community site that circled around creating a sense of nostalgia.  You could go in and become fans (or something) of things from your 80s childhood.  The site details really aren’t important, and I’m not even sure if the site is even still around anymore.  Regardless, we were working with other far flung contractors to bring this whole nugget together, and it wasn’t happening.  At all.

I remember sitting in weekly conference calls discussing the merit of the PHP site architecture, templating systems, database backends.  Tons of nitty gritty details that really had absolutely nothing to do with creating a community site.  Phrases like “so when when we’re done the templating system will work just like smarty” were uttered often (clarification: not by us, we were only making some javascript widgets).  Usually someone would follow with “then why the fuck aren’t we using smarty?”.   I recall this verbatim.

The situation continued to spiral into more and more delays as we trudged along. There eventually was a call between our CEO and theirs where our CEO asked why they’re so focused on software development when what they were trying to build was a community site, not a software system.  I imagine the silence was deafening.

It was a bad case of “not invented here” syndrome.  Symptoms include burning tons of time and energy on something that quite simply has A) already been done, B) probably better and better tested than you could do it, and C) completely ancillary to your core business.

That conversation came ringing back all to true to me on a recent project.  We were looking to add a rich PDF viewer to an app with paging, zooming, and all the other bells and whistles.  For a few days I looked on the internet, found some sample code, and toyed with some of the Apple examples for displaying PDFs.  I got something that worked, sort of.  One stray rotation of the device could throw the whole thing out of whack.  I was trying to avoid having to pay for a library that does all these.  Then it hit me.  The goal of the app was not to display PDFs, it was merely one facet of it.  I has already been done, better than I could have done it in the time we had to do it.  Displaying PDFs was not the business goal of this application.  I was doing nobody any good by continuing to churn on it.

The lesson here is to know what your product is, whether it belongs to you or you’re ultimately helping someone else create theirs.  It’s always important to recognize that using a well tested pay-for component might just the thing you need to add the value you were looking for and get everyone back to focusing on what’s really important.

Do Just About Anything With Blocks

I love using blocks in objective-C (and C for that matter).  I think they’re the most useful additions to language since . . . well I don’t know.  I allows your code to be more compact and more logically grouped (remember UIView animation delegates? yeesh).  In some cases, even faster by backgrounding certain operations with GCD.   Sadly, blocks have only made it into a small portion on the SDKs and frameworks, most notably collection enumeration and the vastly improved UIView animations.  Fortunately there’s some enterprising individuals and groups who’ve created some very good libraries for extending blocks to other parts of the framework.

BlocksKit

BlocksKit is an open source library that allows you to do just about anything with blocks.  You can easily apply blocks as selectors to UIControls, UIGestureRecognizers, and NSTimers.  There are facilities to apply blocks in different ways to collections, and through the use of dynamic delegates you can use blocks in place of delegates on alerts and action sheets.  As a bonus there’s some handy utilities for dealing with associated objects too.

Block based drawing

I’ve shared this before,but David Hamrick posted a great demo on using blocks to handle drawing on UIViews without the need to subclass.  Find it here.

UIAlertView+Blocks:

If you don’t need everything in BlocksKit, you can check out UIAlertView+Blocks which works very nicely for working with alerts and actions sheets without the need for a delegate at all.

Note: BlocksKit and the above categories don’t play nice together.  You’ll need to pick on or the other to avoid some very odd runtime bugs.

Some block tips of my own:

Static comparators

Apple added block based comparisons for sorting NSArrays.  The block takes 2 objects and returns an NSComparisonResult.  If you find yourself sorting the same thing in multiple places it’s often faster to statically declare your comparator that you can reuse.  Let’s say we have an array of a custom class person, with strings for first and last name:


@interface Person : NSObject
@property (nonatomic, copy) NSString *firstName, *lastName;
@end

Sorting using a block is simple enough, given an array of Person objects:


[people sortUsingComparator:^NSComparisonResult(id p1, id p2) {
if ([[p1 lastName] isEqualToString:[p2 lastName]])
{
return [[p1 firstName] caseInsensitiveCompare:[p2 firstName]];
}
return [[p1 lastName] caseInsensitiveCompare:[p2 lastName]];
}];

If we want to reuse the comparator multiple places, we store it into a static variable:


static NSComparator personCompare = ^NSComparisonResult(id p1, id p2) {
if ([[p1 lastName] isEqualToString:[p2 lastName]])
{
return [[p1 firstName] caseInsensitiveCompare:[p2 firstName]];
}
return [[p1 lastName] caseInsensitiveCompare:[p2 lastName]];
};

// ...

[people sortUsingComparator:personCompare];

You can do the same thing with literally any block you want to reuse, but you don’t get the benefit capturing scoped variables.

Blocks in forms:

It’s common to have forms made of table cells with text fields for entering user data.  Normally to properly apply the captured data you either have to do some creative work with UIView tags or extend the UITableViewDelegate to hand your new cell type.  You can also use blocks to handle the callback by either adding a block variable to a custom table cell.


typedef void(^TextViewEndCallback)(NSString *enteredText);

@interface MultiLineTextFieldCell : UITableViewCell <UITextViewDelegate>
{
UITextView *textView;
SBTextViewEndCallback textViewEndCallback;
}
@property (nonatomic, retain) IBOutlet UITextView *textView;
- (void)setTextViewEndCallback:(TextViewEndCallback)callback;
@end

The above example uses a text view in a table cell.  The table cell should be delegate for the text view.  In the text view delegate method you need only call the block passed into the cell:


- (void)textViewDidEndEditing:(UITextView *)textView_
{
textViewEndCallback(textView.text);
}

This is very easy to use in your cellForRowAtIndexPath method:


__block SomeClass *object = [objects objectAtIndex:indexPath.row];

[cell setTextViewEndCallback:^(NSString *enteredText) {
object.somestring = enteredText;
}];

We used very similar ideas to the above in SalesBag to speed development along.

That’s it!

I enjoy how blocks can speed development along and allows you to write more flexible and sometimes even more reusable code.  Have any cool block tricks?  I’d love to hear them.  Happy Coding!

2012 – A look back and a look forward

Another day, another dollar.  Another year, another . . . something.

Dunno.  I’ve never had much use for resolutions related to an arbitrary day of the year.  I tend to see goal setting as an ongoing thing and goals as more of a continual series of milestones rather than a single achievable event.  Why new years resolutions anyway?  Why not 6-month resolutions?  Or monthly resolutions?  Monthly resolutions in agile sprints?  Maybe I’m onto something . . .

Most of the stuff I put up here is highly technical in nature.  Tutorials on how to do this or that in iOS or XCode.  I was tempted to go technical on this one too.  A rambling list of technologies I’ve worked with.  Another xxxKit.framework I intend to plod around with.

Boring.  Who cares.

That in itself isn’t really interesting to anyone (not even me really).  So in a different direction I’m taking stock of what I’m good at, what I’m not good at, and what I want to be better at on a very general level.  I think these could apply to anyone working as developer whether working on an indie project (as many people reading iDevBlogADay probably are) or working on client work (as I do).

Things I’m Good At:

Watching the details – It came to me in an epiphany this year.  Strangely.  I am a detail oriented person.  I was never the kid with a clean room.  I never meticulously organized my closet by color.  I never had the border-line OCD, must-organize-everything kind of personality.  I still don’t.  On some level I separate ordinary details from Details That Matter.

At any rate, I have a penchant for the details when it comes to my work.  I like this.  I love this.  I used to be envious of the detail oriented folk.  I’m pleased to count myself among them in some regard.  I think this is necessary for people who work as developers.  Your job is detail oriented.  “The computer will only do exactly what you tell it”, my dad used to say.  To a fault.  I take pride in the craftsmanship of my work.  I always have.  2012 will be no different.

Making a plan – 2012 was one of my first forays in developing a real, honest-to-god software engineering plan.  I thought I’d nailed it.  Turns out I was about 75% of the way there (the gaps really showed up during development).  Regardless the parts that were planned well went off without much of a hitch and came in under-time against the project plan.  This is something I want to expand upon in 2012.  You’d be amazed what you can figure out ahead of time before you write one line of code.  Every 15 minute interval spent mulling over a problem before you start will save probably hours in development when the same problem inevitably comes up.  As mine and Mindgrub’s projects grow ever larger this will become increasingly more important.

Things I Suck At (and want to improve upon):

Automating the mundane – Shame on me as a developer, but there’s a lot of things for which I don’t have automation in place.  Simple stuff.  Dumb stuff.  Stupid stuff I still do manually like pushing a build to test flight or setting up a UITableView.  I think there’s a couple reasons I haven’t delved into this more.

  1. Time is not always on my side, in that the pressure to just get the client work out the door is high to where I don’t think I’ll have time to find/write a script or an automator action or make an XCode template.  Usually by the time I notice that I should have automated it I’m already 75% done with the task.
  2. Fear of the tools – What if automator jacks the upload to testflight?  What if the deployment script fails?  Dumb fear.  Paranoia.  I need to get over this one.
  3. Lack of knowledge – In no way can I count myself as a bash guru.  I couldn’t write a Perl script to save my life.  Granted automator is a huge help here.  In some ways you can put this under “fear of the tools”

Not sure if there’s an easy solution here.  First would be to learn the tools: automator, a little bash.  I think I’ll leave Perl until 2013.  I also have a mind to make a slew of Xcode templates to use with my development team as it always seems there’s a bunch of things we have to add to any UIViewController.  Third for me is to try out tools and scripts that get posted to various places like HackerNews and Twitter, see what other folks are doing and try to adopt them into my and my team’s workflow.

Branch Out – I’ve been working with iOS almost exclusively in 2011.  It’s great and I love it but I’ve been feeling the need to branch out lately.  I believe it’s important especially in the current job market to be versatile as a developer.  Learning new programming languages will make you better at whichever language you use everyday.  Learning new frameworks will make you think differently about the frameworks you already use.  And if you don’t learn anything new, technology will pass you by.  For 2012 I want to get a release of a cocoa app.  While it’s still objective-c, there’s a lot of nuanced differences between the two.  I’ve got a couple of ideas rattling around, just gotta get up and get going on one.

Making every moment count – I feel like I need a little more get up and go in my life.  Not that I’m lazy.  Far from it.  But I want to make more of my free time that I have.  That doesn’t necessarily mean more work or side projects but more about getting the feeling that I’m getting most out of every minute.  This year I want to work on paring down distractions and focus more on important things.

So, maybe this process was a little more cathartic than I thought looking at the tone of the post from the top to the bottom.  At any rate I want to wish those few regular readers and folks from iDevBlogADay a great new year.  Happy Coding!

Multiple Build Targets For Fun and Profit

This month Mindgrub and Wheelhouse Analytics released Salesbag 1.0, a sales presentation tool geared at the financial services industry. The project represents somewhat of departure for Mindgrub as a consultancy. Most previous projects have been a once-and-done kind of project. For Salesbag we’ll be working long-term with Wheelhouse to release frequent updates to the app.

This presented numerous challenges as 1.0 got out the door and we started work on the first set of updates. Aside from our internal testing team, Wheelhouse has a team of their own. They want to be able to show the app store version off while still testing our updated builds to them. To keep the development and live builds totally separate we decided the best course was to create separate target for the dev version that they would use for their testing. To iPad, these would look like entirely different apps, so we’d never run the chance of damaging the live data during testing. In the rest of this post I’ll detail how to create a separate development target for testing purposes some of the added benefits you’ll get out of doing this.

Step 1 – Create a new app id and provisioning profile.

In the provisioning portal, create a new app id and ad hoc provisioning portal. I assume that everyone reading knows how to do this. For Salesbag we created a com.wheelhouse.salesbagDev app id.

Step 2 – Create a duplicate target

Duplicating the target is simple. Simply right click the build target in the project details and select “duplicate”.

Step 3 – Create a duplicate info plist

In order to use the new app id, we’ll need to duplicate and modify the info.plist to include the new app id.

You can also change other build settings like the bundle display name to make your dev version distinguishable from the production app.

Step 4 – Modify the target build settings to include the new plist

The new target must know to use the new the info.plist. Open the build settings for the target, search for info, and change the name of the info.plist.

Step 5 – Create a new scheme to build the new target

The last thing to do is to create a new scheme to build the new target. Under the schemes drop down at the top of the Xcode window and select manage schemes to bring up the scheme manager. You select duplicate from the actions (gear) menu at the bottom of the window.

Once your new scheme is created, click edit to open the new scheme. All you need to do next is replace the old target with your dev target and hit ok (this is in the “build” section).

You should now see the new scheme in the schemes drop down.

BONUS – Setup target specific code

In the dev version of salesbag we added some features for testers to be able to wipe out old data from previous iterations of Salesbag (in our case local eventkit calendars from development on the earlier versions). With your new target you can easily create custom preprocessor directives to dynamically include code in dev versions that you give to your testers.

Step 1 – Create a new preprocessor macro

In the build settings for the dev target search for preprocessor and double click the section called Preprocessor Macros under the target. Add a new parameter in here. We chose “DEV_VERSION=1”.

Step 2 – Use your new macro in code

To include code specifically for your dev version, simply use the macro you created in step 1:

#if DEV_VERSION
NSLog(@"cool testing feature");
#endif

That’s it!

Hopefully the process above will help some other developers in their longer term projects.  Also be sure to drop a comment if you have any feedback.  Happy coding!

Cappuccino : First Thoughts

Hello to all the readers coming from iDevBlogADay!  I’ve started working on a project that is being built using Cappuccino, a web development framework modeled off Objective-c and Cocoa.  After working with it for about 5 days I wanted to scribble down my first impression of the framework and tools.

Language:

The language for working with Cappuccino is objective-j.  Objective-j is to javascript what objective-c is to c in that you get object orientedness without it mucking up the foundations of the base language.  According to its creators, this is exactly why they chose the smalltalk style syntax of objective-c over other constructs when deciding how to craft their language.

Coming from iOS development, picking up the syntax was a breeze.  Having had a background with javascript didn’t hurt either, but I haven’t yet run across any particular problem where I’ve had to lean on that knowledge to move forward.  Some things are different though and might trip up would be adopters:

  1. No .h files – Javascript has no notion of separate compilation (or compilation at all for that matter).  As a result there is no .h file, only your .j which contains your @implementation block.  The @implementation block serves as both the @interface and @implementation from objective-c containing instance variables and full method implementations.
  2. No properties – I know there’s some haters of the @property directive in the community.  To those folks, I don’t know how you ever lived without dot syntax, as it’s the one thing I miss from objective-c.  Typing things like [[[self view] subviews] objectAtIndex:0] and the like gets a bit tedious after a while.  That said, you can still have objective-j generate accessors for you with the @accessors directive.    Why the lack of dot syntax?  For the same reason objective-j was chosen: not breaking javascript.  Javascript is object oriented in its own way, so supplanting its existing dot syntax would break the language.
  3. Variable naming – iVars in the interface are still named with their type, but without the ‘*’ or pointer to it.  Local variables cannot be typed (probably what still trips me up the most).  The keyword for a local variable is “var” from javascript syntax.  All this really means is that you need to be extra careful naming variables so you know what they are later in code.

Frameworks:

I can’t help but be impressed with how thorough the Cappuccino folks have been in duplicating the Cocoa frameworks.  Virtually all the foundation classes you might need are there as well as much of the Cocoa UI components.  This is probably the greatest benefit to using Cappuccino is the sheer number of controls available out of the box without having to get into the nitty gritty of HTML and CSS manipulation required to get things like scrolling table view and outline views.  Cappuccino keeps the API to very close to their Cocoa counterparts so using them is easy if you’re already familiar.

Installing:

To get started learning Cappuccino provides a starter package that let’s you play around with the frameworks.  For a full fledged installation, the simplest thing is to build the frameworks from source.  There’s an installation script that will download the sources and compile them.  The included jake tool (think make, but for javascript) makes it very simple to build all the frameworks you need and deploy your application later.  All this work is done on the command line, so you’ll want to be comfortable in terminal before you dive in.

Development Tools:

This is probably where Cappuccino is lacking the most at the moment.  There is an Xcode plugin but I’ve found it’s crashy and unreliable in Xcode 4.  So far the best set of tools I can find are TextMate and Xcode’s Interface Builder with XCodeCapp which converts the xib files to cib (Cappuccino interface files) on the fly.  Coda has support for objective-j though I haven’t tried it out yet.

Debugging has its own set of challenges as well.  It’s supposedly possible to set breakpoints in either firebug or safari’s web developer window, but I haven’t seen how to do that yet.  So far console.log has been my best friend for debugging my application.  Additionally, since there is no compiler you don’t get the benefit of compiler errors and warnings to help you along.

I’m hoping the state of the tools improves as Cappuccino chugs closer to 1.0.  I’d love to see a full blown Xcode plugin with code completion, debugging, and building and deployment.  That is a tall order of course, especially when Xcode itself sometimes feels more like a beta than a fully tested application.  280North, the team behind Cappuccino seemed to have something strong going with Atlas, a web based interface builder and IDE, but there hasn’t been any movement on that since they were bought out by Motorola a couple of years ago.

Results:

Tools aside, the amount you’re able to produce with very little code (especially if using interface builder) is pretty profound.  Having worked on web applications in the past it’s refreshing to be able to focus on the logic of the app rather than being worried about the ins and outs of HTML, CSS, and raw javascript.  Cappuccino seems to make intelligent decisions about how rendering a given view should be handled, whether with a div or HTML 5 canvas.  Having a proper abstraction for the DOM is invaluable in this regard and most of the default controls look great right out of the box.

Conclusion:

If nothing else it’s fantastic to be able to use my objective-c skill set and jump into developing a modern web application quickly using cappuccino.  It requires you to develop your own workflow; it’s not as integrated as iOS / Xcode is.  The tools, however, seem to be improving as the Cappuccino approaches 1.0.  In all, I left web development because I didn’t like having to deal with both the application logic and HTML/css drudgery simultaneously to get anything done.  Cappuccino solves that problem for me and has allowed to me to produce some promising stuff very quickly.

A Better Table View Data Structure

Lately, I’ve found myself creating a lot of table views that look like this:

Grouped Table View

Grouped Table View

A plain-jane table view filled with homogenous items grouped by some common element.  I couldn’t help but notice how ill-suited the standard NS data structures are for handling this.  It always involves some sorted array containing the keys of a dictionary which is filled with sorted arrays.  The setup for these is pretty standard and easily repeatable, so I submit to the community my IndexArray class which takes care of much of the boiler plate for you.  This is definitely rough around the edges as I only started putting this all together yesterday.

First some high level requirements:

  • Everything should be sortable: keys and items.
  • I want to be able to add and remove items without having to always resort.
  • I want to be able to specify how the sort should occur.  I want this to be as convenient as sorting an array.
  • I don’t want have to worry about the logic of whether a key has an array associated with it when I push items into it.
  • Items should be easily accessible by index so it works rather seamlessly with UITableViews.
  • Keys should have the same freedom as they do in NSDictionary.

Here’s my public interface as it stands now:


@property (nonatomic, assign) SEL keySortSelector;
@property (nonatomic, assign) SEL objectSortSelector;
@property (nonatomic, copy) NSComparator keySortComparator;
@property (nonatomic, copy) NSComparator objectSortComparator;

// accessing keys
- (id)keyAtIndex:(NSUInteger)index;
- (NSOrderedSet *)allKeys;
- (NSUInteger)keyCount;

// accessing objects
- (id)objectForKeyAtIndex:(NSUInteger)keyIndex objectIndex:(NSUInteger)objIndex;
- (id)objectForKey:(id)key index:(NSUInteger)index;
- (NSArray *)allObjectsForKey:(id)key;
- (NSUInteger)count;

// adding objects
- (void)addObject:(id)object forKey:(id<NSCopying>)key;

// removing objects
- (void)removeObject:(id)object forKey:(id)key;

You can see that I’ve specified 2 ways to sort keys and items.  Since keys are usually strings, it’s uber convenient to simply hand the compare: selector to the data structure.  For what I’ve been working on the items are NSManagedObject subclasses, so I need something a little more powerful to maintain their order, so I can also send in a comparator block in the form:


typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

Adding and removing objects is as simple as possible with:


// adding objects
- (void)addObject:(id)object forKey:(id<NSCopying>)key;

// removing objects
- (void)removeObject:(id)object forKey:(id)key;

Under the hood:

Here’s the rest of the interface:

@interface PZIndexedArray : NSObject
{
    @private
    NSMutableDictionary *dictionary_;
    NSMutableOrderedSet *orderedKeys_;
    
    SEL keySortSelector_;
    SEL objectSortSelector_;
    NSComparator keySortComparator_;
    NSComparator objectSortComparator_;
    
    BOOL sortsKeys_;
    BOOL sortsObjects_;
    BOOL usesComparatorForKeys_;
    BOOL usesComparatorForObjects_;
}

I’m using two data structures inside the class. First an NSDictionary that will contain mutable arrays for each key. Secondly an NSOrderedSet that will also contain every key. The ordered set will guarantee uniqueness of the keys and provide the ordering I need.

You can also see the selectors and comparators being stored. There’s also some flags to know whether the class should try to sort at all (we won’t if there’s neither a comparator nor a selector). In the implementation as I have it, the selector will take precedence over the comparator if both are provided for either keys or items.

The implementation is pretty straightforward. Setting a comparator or a selector automatically triggers the flags for sorting. There’s a setter for each one, but they all look basically like this:

- (void)setKeySortComparator:(NSComparator)keySortComparator
{
    if (keySortComparator != keySortComparator_)
    {
        [keySortComparator_ release];
        keySortComparator_ = Block_copy(keySortComparator);
    }
    
    sortsKeys_ = keySortComparator != nil;
}

Adding an object for a key is pretty simple. The mutable array is automatically created if no entry exists for a key.

// adding objects
- (void)addObject:(id)object forKey:(id<NSCopying>)key
{
    NSMutableArray *array = [dictionary_ objectForKey:key];
    if (!array)
    {
        array = [NSMutableArray array];
        [dictionary_ setObject:array forKey:key];
        
        if (sortsKeys_)
        {
            [self insertKeySorted:key];
        }
        else
        {
            [orderedKeys_ addObject:key];
        }
    }
    
    if (sortsObjects_)
    {
        [self insertObject:object array:array];
    }
    else
    {
        [array addObject:object];
    }
}

If there’s no sorting the on the keys, the key simply added to the set, otherwise it gets inserted in sorted order. Same goes for items. The sorted insert methods are pretty much the same both. The basic method is to iterate through the array until the object in the enumerator is greater than the object being inserted.

- (void)insertKeySorted:(id)key
{
    if ([orderedKeys_ count] == 0)
    {
        [orderedKeys_ addObject:key];
        return;
    }
    
    __block NSUInteger insertIndex = -1;
    __block NSInvocation *selectorInvocation = nil;
    if (!usesComparatorForKeys_)
    {
        selectorInvocation = [NSInvocation invocationWithMethodSignature:[key methodSignatureForSelector:keySortSelector_]];
        [selectorInvocation setTarget:key];
        [selectorInvocation setSelector:keySortSelector_];
    }
    
    [orderedKeys_ enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx  < [orderedKeys_ count])
        {     
            NSComparisonResult result = NSOrderedAscending;
            if (usesComparatorForKeys_)
            {
                result = self.keySortComparator(key, obj);
            }
            else
            {
                [selectorInvocation setArgument:&obj atIndex:2];
                [selectorInvocation invoke];
                [selectorInvocation getReturnValue:&result];
            }
            
            if (result == NSOrderedAscending)
            {
                insertIndex = idx;
                *stop = YES;
            }
                                
        }
    }];
    
    if (insertIndex == -1)
    {
        [orderedKeys_ addObject:key];
    }
    else
    {
        [orderedKeys_ insertObject:key atIndex:insertIndex];
    }
}

The result is adding items from an array into this data structure is much more compact and cleaner than maintaining the data structures yourself:

IndexedArray *byName = [[IndexedArray alloc] init];
byName.keySortSelector = @selector(compare:);
byName.objectSortComparator = ^NSComparisonResult(Document *doc1, Document *doc2) {
    return [[doc1.filename firstCharacterAsString] compare:[doc2.filename firstCharacterAsString]];
};
// firstCharacterAsString is a category I created.  

And it integrates nicely with the table view datasource methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [categoryIndex keyCount];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [categoryIndex allObjectsForKey:[categoryIndex keyAtIndex:section]];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [categoryIndex keyAtIndex:section];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
    }
    
    id item = [categoryIndex objectForKeyAtIndex:indexPath.section objectIndex:indexPath.row];
    cell.textLabel.text = [item filename];
    return cell;
}

The code for this is posted up GitHub. Please have a look and feel free to contribute back!

6 Things in iOS 5 That Will Make Your Next Project Easier

There’s no shortage of hype around the arrival of iOS5 this week.  Much of it has been about iCloud, ARC, notifications, and Siri of course.  These are big deals to be sure, but for a coder there’s some great improvements that simply make your development process easier.  Here’s my list of favorites, some of which I’ve already started using:

CoreImage and CIFilters – The addition of the CoreImage framework will give you more ways to create compelling UIs.  CIFiltlers aren’t limited just to images.  You can apply them to any CALayer.

UIAppearance – It used to be that if you wanted a custom looking UISwitch or or UIProgressView you’d have to implement it from scratch or try and rip the control apart view by view and modify it yourself.  Writing a custom control is of course time consuming and modifying the view hierarchy leaves your UI at the mercy of the next iOS update.  UIAppearance and the appearance proxies let you configure the look of the default controls in ways you couldn’t before either on a per instance or hierarchy level, or application wide.

Container View Controllers – Absolutely huge, probably my the most useful improvement for me.  It used to be that if you wanted a custom container, like a tab bar or split view, you had to implement it yourself from scratch.  It was always problematic and you often had to hack properties like myParentViewController because the property was locked down.  Now you can make container view controllers and the existing controllers (and containers like UINavigationController) will play nice with them.

Real locations in the simulator – You’re probably not really at Apple headquarters anyway.  Glad the simulator has finally caught on 😉

Ordered relationships in CoreData – If you’ve ever tried to do this on your own, you know how valuable this can be.  Not only does your “group” have “users”, they now have an ordered collection of “users”.

EventKit upgrades – What strikes me a severe limitation of EventKit is that up until now you can’t create calendars in your iOS app.  EventKit upgrades now allow it.

Some Love for Data Structures

NSArray.  NSDictionary.  NSSet.  So common.  So ordinary.  Or are they really?

You probably use tons of these every day.  You probably write them without even thinking about them.  They are the foundation of any (interesting) iOS application.  Rarely do we ever think about what they are.  Who are these creatures?  What do they do? In short they’re data structures.  The foundation of an application and the bane of every computer science undergrad.

It’s often difficult to find good topics to blog about, especially when you’re in the middle of bug-fix mode with my day job and haven’t necessarily been doing anything interesting or innovative.  For my second iDevBlogADay post, I’m going to give some love to our built-in data structures and also discuss some alternatives to them.

But first a side-bar:

Big-O

Big-O is used to describe the complexity of an operation (algorithm).  It defines the worst case performance of an operation.  It’s usually useless describe the best or even the average case of an operation, but always useful to be able to say that an operation will perform no worse than particular value.  For data structures we define the performance in terms of ‘n’ which the number of items in the data structure.

For instance:

O(n) – “big O of n” means that for an operation we have to touch every object in the data structure at worst case.

O(2n) – “big O of 2n” means that for an operation, we have to touch every object in the data structure twice at worst case.

O(n2) – “big O of n-squared” means that for an operation, we have to touch every object in the data structure once for every object, at worst case.

There are a myriad of other ways to express complexity including using the logarithm of n, or factorials of n.  I’m not really going to cover these here.

Confused?  That’s ok.  Here’s some more concrete examples:

Let’s start with a basic array, defined as a basic indexed series of objects.  Let’s say our array holds 1000 numbers (how many doesn’t matter) and we want to search for the number 99.  We can imagine that the number 99 may exist at the first index (index 0) or the last index (999) or anywhere in the middle.  Regardless, we know that it will never take more comparisons than 1000 to find 99 if it exists.  It will also take no more than 1000 comparisons to determine whether it exists at all.  Because n = 1000, we say that the complexity is O(n) since it will always take n comparisons to find a particular value in an array.

Another example.  Let’s say we have our array of 1000 numbers, and we want to sort it.  Let’s consider a basic sort that compares each value to every other value.  To iterate over the array will take 1000 steps, and comparing one element to every other will take another 999 steps.  So we’re talking about 1000 x 999 steps, or about 1000 squared.  Therefore we say that the sort operation runs in n-squared time or O(n2).

Big-O is not necessarily something you always think about, but when you’re trying to optimize your code, the complexity of the algorithms you use on your data structure can become a big deal.

NS Data Structures

When we delve into the documentation for data structures like NSArray, we begin to discover that an array is not quite what we expect.  RidiculousFish points out that some operations on CFArray, and consequently, NSArray are in O(N*lgN) (n times the base 2 log of n, which is bigger than n), not in straight O(n) as we might think.  Operations such as searching.  This is kind of a big deal.  What gives?

The prevailing Apple wisdom seems to be that our data structures only need to look like the real thing, rather than act like it.  For instance, in a real honest-to-god array, an operation like [NSArray objectAtIndex:] should return run in what we call constant time, or O(1), meaning that it’s instantaneous.  No need to count or search; we’re able to jump right to where we need to go.  The CFArray comments RidiculousFish mentions say that it could run in O(lg n).  For the mathematically impaired, this is way slower.

The computer scientist in you should feel cheated an betrayed.  Your inner programmer should be thinking of sending Steve Jobs a strongly worded email about this telling him that arrays indexing should be constant time and nothing else.  Don’t click send just yet.  99 times out of 100 the NSArray implementation will work fine for what you need.  The same holds for all the other data structures that comes standard in Foundation.  But what about those rare times where you actually need not only the interface of a data structure (the methods on it) but also the implementation that goes along with it?

Let’s think about an example.  Imagine a queue, just like a line at the bank, where the first person in line is the first person served.  First in, first out.  Let’s assume you needed that implementation exactly.  You need an enqueue method to add an item to the end of the line and a dequeue method to remove an item to the front.  You might easily wrap an NSMutabableArray in the following manner:

  1. To enqueue an item, simply use the addObject: method on NSMutableArray
  2. To dequeue an item, simply use the removeObjectAtIndex method with index 0, effectively removing the first item at the front of the array.

Oh and did I mention you want it to be fast?  Knowing what you know about NSArray, you can see how this would wind up being a poor performance implementation.  Enqueue would be fast, since you only need to find the end of the array, probably O(1) since we’d know how big the array is.  Dequeue on the other hand would be slow and expensive since adding removing the zeroth object would involve shifting all the other objects down by 1.  This would run in O(n) time.  A better implementation would be to use some kind of chained list where lopping off the front of the list wouldn’t require everything to be re-indexed.

Stacks and Trees and Graphs . . . Oh My

There’s a plethora of data structures defined in the abstract sense, from trees to lists, to fully connected webs.  Questions of data structure choice can arise all the time in applications and choosing the right one can greatly enhance the speed and efficiency of your code.  You can of course opt to write your own, either by adapting one of the built in data structures like NSArray or by working from scratch.  In fact, if you’ve never written data structures, its always a worthwhile exercise to write some implementations to get a feel for how they work.  CHDataStructures is also a great library for getting implementation-exact structures for list, circular buffers, and others.

The foundation structures often pamper us into using them.  They’re nice, comfortable, familiar – like your favorite pair of jeans.  It’s important to remember that there are other things out there.  Things that may be tailored exactly to your needs.  Things worth checking out.