Category Archives: Code

Lessons from AngularJS

AngularJS

AngularJS

The past two weeks I’ve been working on a web project using AngularJS.  Angular is a Javascript MVC framework with the backing of Google.  I always enjoy taking some time to learn a new language or tool from time to time.  As iOS developers I think there’s a couple of concepts we could learn from Angular.

Bindings – Bindings everywhere.

One of the first thing you learn in Angular development is its two way binding system.  Placing a binding in your HTML template is dead simple; simply enclose the variable in the handlebars: {{myvar}} or link it via the ng-model attribute on an input tag.  The binding is two way such that changing the value of a text field will update that in your model.

Unfortunately iOS is often much more difficult and manual when it comes to keeping your model and UI in sync.  MacOS provides bindings to developers but there’s no once and done solution for iOS.  However binding is not difficult to implement using KVO.  KVO has its downside when it comes to performance, but it may be worth it for the simplicity.  I haven’t tried to implement it myself to be able to tell.

Thin models; thin controllers

Angular makes very few assumptions about what your model in the MVC way of thinking is.  In fact, the model for any controller is expected to be a special variable called the $scope.  The $scope object is provided by the controller, whose entire job is to do nothing but populate the scope.  Compared to iOS view controllers, Angular controllers are extremely light.

iOS view controllers have a bad habit of being very involved in both in view-ish things and model-ish things, as well as its dictated function of handing controller-ish things.  How many times have you managed a view directly in your view controller as well as managed changes back to the model?  Probably a lot.  One of the downsides of UIViewController is that they often wind up being behemoth and barely manageable monster objects. Angular’s documentation strongly advises that you don’t make changes to the DOM (the literal view of a web application) from within the controller, delegating those tasks elsewhere.  The result is a very simple controller that does its job of exposing the model to the view well and without needless other operations.

Greater separation of the view and the controller

Web applications have an inherently strong presentation layer: the HTML and CSS that handles display in the browser.  In Angular style, the HTML provides structure of a view, CSS provides the presentation of the view, and Angular does the job of providing data to the view.  As mentioned above it’s all too common in an iOS application to jam all this functionality into a single view controller.

It’s not a stretch to say that UIViewControllers are often required to do far too much for any non-trivial application.  A view controller might be responsible for loading data from somewhere, maybe through an NSURLConnection, doing any formatting or transformation of the data, creating a view in loadView: and laying all the pieces out.  It may also be the datasource and delegate for a table view providing cells and handling cell selection.  After all of that it might also be accepting event callbacks from UI controls and altering the model appropriately.  That’s a huge set of tasks and I’m as guilty as anyone of writing multi-thousand line view controllers.

Applying the lessons

So how should we break up a UIViewController subclass into more manageable chunks?  I think Angular presents a couple of ideas.

  1. The most simple task is to separate the model related concerns of a UIViewController from its view related concerns.  In iOS development you need to have view controllers, but there’s no rule that you can have other controllers to handle other tasks.  NSFetchedResultsController provides a great example of a way to separate the needs of dealing with CoreData from the other responsibilities of the view controller.
  2. Relegate the UIViewController subclass to what its name implies:  management of the view.  Offload data related concerns to a custom defined model controller.
  3. Make views a little smarter.  HTML and CSS provide a natural separation between controllers and views.  Interface builder is one of the best tools and iOS developer has but there’s no reason we can’t make smarter views that know more about it’s layout and the properties of it’s subviews.  If reuse is concern there’s nothing wrong with the root view of a view controller being a custom subclass that arranges other pre-made components.
  4. Attempt bindings using KVO.  You could easily inject a transformer into the mix for formatting.

Fully realizing these are all a little abstract right now I’m planning to take a concrete stab at these in some future posts.  For now the takeaway is that learning a different way of doing things can always open your eyes to some better ideas in your current workflow.

Advertisements

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.

Mastering Copy and Paste in iOS – Part 1

System wide copy and paste is built into most of the stock iOS controls without the developer having to do any extra work to enable the feature.  Sometimes for security purposes you may wish to lock down the functionality (to not allow copy and paste at all) or disallow copying and pasting between your app and other apps that may be on the device.  Restricting this functionality is a pretty common requirement for the growing market of security frameworks out there for enterprise applications such as GOOD and MobileIron.  They commonly refer to this as “data leakage”.

In this 3-part series I’ll explore the copy and paste system in iOS and how you can use it to fit the needs of your specific application.

This first part will focus on locking down the copy and paste system completely.

In the second part I’ll show you how you can create an application specific pasteboard to allow copy and paste within your own application while still preventing data leakage to other apps as well as posting other types of data to UIPasteboard.

In the third part I’ll explore other types of data on the pasteboard with simple drawing sample app.

Locking down copy and paste

All controls in UIKit expose a single method you can override to control actions such as copy and paste..  To lock down system wide we really only need to implement a category on the specific controls.  In preparing the sample code for this I attempted a category on UIResponder, but that seems to have unintended side effects. Adding it to the classes directly seemed to be the most consistent approach.

At a high level you’ll want to use code like this:

@interface UITextField (lockdown) @end
@implementation UITextField (lockdown)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    SEL copy = @selector(copy:);
    SEL cut = @selector(cut:);
    SEL paste = @selector(paste:);
    if (action == copy ||
        action == cut ||
        action == paste)
    {
        return NO;
    }
    return YES;
}
@end

You can find the sample code for this here that will lock down UITextField, UITextView, and UISearchBar.  Remember that since this method exists on UIResponder, you can use it to lock down any control, even complex ones like UIWebView.

One more note:

When you first implement this you may notice that you get a compiler warning about reimplementing a method in a category that already has an implementation elsewhere.

You can prevent this code by wrapping it in the following:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
// ...
#pragma clang diagnostic pop

Be sure to check out part 2 of this series for digging deeper into copy and paste and the UIResponderStandardEditActions protocol.

UIAppearance Is Better Than You Think

You already know about the UIAppearance protocols added to iOS. You know that UIAppearance makes it WAY simpler to customize the appearance of the common UI elements is iOS. You probably know that you can customize the appearance of the duly marked UI_APPEARANCE_SELECTOR methods on your own subclasses as a means of differentiating certain elements from others of the same type (such as specifying a class of UIBarButtonItem as a cancel button and therefore always red).

What you might not know is that it’s trivial to use UI_APPEARANCE_SELECTOR on your own custom subclasses for visual elements that are not in the standard set of appearance selectors.  Here’s a quick example of how you might use this:

Say you have a particular class of view you have all over your application that has border around it (using the CALayer backing the view).  You could hard code this look into a view subclass, or you could do it the hard way by setting this on every individual view.  You can also use a UI_APPEARANCE_SELECTOR on your custom class and set it with an appearance proxy.  This functionality and behavior falls squarely under “I can’t believe it’s this easy”.

Here’s the interface:

#import <UIKit/UIKit.h>

@interface TestView : UIView

@property (nonatomic, retain) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, retain) UIColor *borderColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, retain) UIFont *font UI_APPEARANCE_SELECTOR;
@end

Here’s the implementation:

#import "TestView.h"
#import <QuartzCore/QuartzCore.h>

@implementation TestView
@dynamic backgroundColor;
@dynamic borderColor;
@synthesize font = _font;

- (void)drawRect:(CGRect)rect
{
    NSLog(@"%@", self.font);
}

- (void)setBackgroundColor:(UIColor *)backgroundColor
{
    [super setBackgroundColor:backgroundColor];
}

- (UIColor *)backgroundColor
{
    return [super backgroundColor];
}

- (void)setBorderColor:(UIColor *)borderColor
{
    self.layer.borderWidth = 4.0;
    self.layer.borderColor = [borderColor CGColor];
}

- (UIColor *)borderColor
{
    return [UIColor colorWithCGColor:self.layer.borderColor];
}

@end

And in the App Delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.window.backgroundColor = [UIColor whiteColor];

    MainViewController *mainView = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];

    self.window.rootViewController = mainView;
    [self.window makeKeyAndVisible];

    [[TestView appearance] setBackgroundColor:[UIColor blueColor]];
    [[TestView appearance] setBorderColor:[UIColor redColor]];
    [[TestView appearance] setFont:[UIFont systemFontOfSize:12]];
    return YES;
}

And here’s the result:

And the NSLog prints the font that was set:

2012-05-16 17:03:43.517 test[26634:f803] font-family: “Helvetica”; font-weight: normal; font-style: normal; font-size: 12px

What’s the advantage?

Well it depends on your development strategy and the scope of the project.  For large, running projects it’s helpful to separate as much of the presentation code (fonts and colors) from the logic of the application.  This allows you to keep all of your styles centralized in one place as opposed to littered throughout a bunch disparate classes in much the same way that CSS can separate presentation logic from the HTML structure of a website.  Additionally, if you’re writing framework level code for a static library it offers greater flexibility and code reuse where you’re not as able to edit the implementation of a class.  This of course all depends on the purpose of your app.  For once-and-done style apps it may not make quite as much sense.

Technical notes:

You will find that if you tinker around that the UI_APPEARANCE_SELECTOR macro isn’t really necessary.  In fact, the code above will work just fine without it.  The macro #define’s to nothing, so I’m not personally sure if there’s more grandiose future plans for if it’s just a placebo macro to let developers know what will be guaranteed to be supported.  In truth, virtually any display related property on a UIView can already be set using UIAppearance proxies, though like all non-official APIs Apple can change that without notice.  By taking the approach above you’re likely future proofing your code for later.  If I were to take a guess at the internals of UIAppearance it seems like a clever hack on KVC more than a real, run-time enforced protocol.

Regardless, there’s a lot of power to be exploited using this protocol and it should change the way you think about creating a great visual style for your apps.

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

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!

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!

This? You just need to watch this.

Greg Wilson – What We Actually Know About Software Development, and Why We Believe It’s True from CUSEC on Vimeo.

A Cool KVO Trick

A coworker of mine attended the Voices that Matter conference in Boston a couple of weeks ago and shared this idea about KVO observing from Mike Ash during his Defensive Programming talk.  He suggests supplying a static pointer to the context parameter:


static void *p = &p;

[someObj addObserver:self forKeyPath:@"aPath" options:NSKeyValueObservingOptionNew context:p];

// ...

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == p)
    {
        // do stuff
    }
    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

Seems like a lot of magic at first, but by specifying a context every time and using one that’s not only unique to your object but also to the file containing your subclass you can ensure that the message sent to you is actually for you and you avoid potentially stepping on the toes of your super class. Neat stuff! It’s also worth noting that checking the context pointer first is a super-fast way to see if you need to care about the observation method.

Side note: if you’re not subscribed to Mike Ash’s Friday Q&A blog (link above), you definitely should. I learn something new there every week.

Updates to PZIndexedArray

I posted another update to PZIndexedArray that fixes some bugs with sorting and key deletion as well as some greater conveniences for checking keys and lack thereof.

It’s up on GitHub as always.