Kevin Sylvestre

A Ruby and iOS developer and designer living in Santa Monica, California.
  • About
  • Contact
  • rss
  • archive
  • Non-Blocking Long Running Tasks on iPhone

    iOS applications containing long running tasks - such as HTTP requests or data processing - that block the main thread are annoying and often appear sluggish. The following snippet can be used to fix this issue:

    //
    //  SampleTableViewController.m
    //  Sample
    //
    //  Created by Kevin Sylvestre on 10-04-22.
    //  Copyright Kevin Sylvestre 2010. All rights reserved.
    //
    
    #import "SampleTableViewController.h"
    
    @implementation SampleTableViewController
    
    #pragma mark - Helpers
    
    - (void)load
    {
      [NSThread sleepForTimeInterval:4.0];
      self.results = [NSArray arrayWithObjects:@"Canada", @"England", @"France", @"Spain", nil];
      [self.view performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    }
    
    #pragma mark - Main
    
    - (void)viewDidLoad
    {
      [super viewDidLoad];
    
      NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
      [queue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(load) object:nil] autorelease]];
    }
    
    @end
    
    • 3 years ago
    • #apple
    • #cocoa
    • #ipad
    • #iphone
    • #mac
    0 Comments
  • Cocoa Copy Paste Menu

    I spent some time earlier today playing with the UIMenuController available in the iOS SDK and realized two thing: sometimes Apple’s examples suck and having an environment that often gives no feedback is terrible.

    In this case, I implemented a copy of an example that was supposed to present a semi-modal cut / copy / paste menu. It didn’t. After spending nearly an hour trying to identify why nothing was happening, I found I had missed copying a line. Anyways, for the record, here is the concise example of how to present a UIMenuController:

    //
    //  SampleViewController.m
    //  Sample
    //
    //  Created by Kevin Sylvestre on 10-03-25.
    //  Copyright Kevin Sylvestre 2010. All rights reserved.
    //
    
    #import "SampleViewController.h"
    
    @implementation SampleViewController
    
    #pragma mark - Helpers
    
    - (void)menu
    {
      [self becomeFirstResponder];
    
      UIMenuController *menu = [UIMenuController sharedMenuController];
    
      [menu setTargetRect:CGRectMake(100, 100, 0, 0) inView:self.view];
      [menu setMenuVisible:YES animated:YES];
    }
    
    #pragma mark - Main
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
      [self menu];
    }
    
    - (BOOL)canBecomeFirstResponder
    {
      return YES;
    }
    
    #pragma mark - Actions
    
    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
    {
      if (action == @selector(cut:) || action == @selector(copy:)) return YES;
      return NO;
    }
    
    - (void)cut:(id)sender { NSLog(@"cut"); }
    - (void)copy:(id)sender { NSLog(@"copy"); }
    
    @end
    
    • 3 years ago
    • #cocoa
    • #iphone
    • #ipad
    • #apple
    • #mac
    0 Comments
  • Extending Objects in Cocoa With Categories

    Cocoa extensions provide a great way to modify existing classes with additional functionality. Here is a good example of extensions in action:

    NSDate+Accessors.h

    //
    //  NSDate+Accessors.h
    //  Illustrate
    //
    //  Created by Kevin Sylvestre on 10-03-24.
    //  Copyright 2010 Kevin Sylvestre. All rights reserved.
    //
    
    @interface NSDate (Accessors)
    
    @property (nonatomic, retain, readonly) NSString *distance;
    
    @end
    

    NSDate+Accessors.m

    //
    //  NSDate+Accessors.m
    //  Illustrate
    //
    //  Created by Kevin Sylvestre on 10-03-24.
    //  Copyright 2010 Kevin Sylvestre. All rights reserved.
    //
    
    #import "NSDate+Accessors.h"
    
    @implementation NSDate (Accessors)
    
    # define SINGULAR (1)
    
    - (NSString *)distance
    {
      // Load interval.
      NSTimeInterval interval = [self timeIntervalSinceNow];
    
      // Calculate interval.
      NSInteger seconds = round(abs(interval));
      NSInteger minutes = round(abs(interval) / 60);
      NSInteger hours   = round(abs(interval) / 3600);
      NSInteger days    = round(abs(interval) / 86400);
      NSInteger weeks   = round(abs(interval) / 604800);
      NSInteger months  = round(abs(interval) / 2629743);
      NSInteger years   = round(abs(interval) / 31556926);
    
      // Calculate direction.
      NSString *direction;
      if (interval > 0) direction = @"until";
      if (interval < 0) direction = @"ago";
    
      // Create unit and amount.
      NSString *unit = nil;
      NSInteger amount;
    
      // Set unit and amount.
      if (interval == 0);
      else if (years)   { amount = years;   unit = amount == SINGULAR ? @"year"   : @"years";   }
      else if (months)  { amount = months;  unit = amount == SINGULAR ? @"month"  : @"months";  }
      else if (weeks)   { amount = weeks;   unit = amount == SINGULAR ? @"week"   : @"weeks";   }
      else if (days)    { amount = days;    unit = amount == SINGULAR ? @"day"    : @"days";    }
      else if (hours)   { amount = hours;   unit = amount == SINGULAR ? @"hour"   : @"hours";   }
      else if (minutes) { amount = minutes; unit = amount == SINGULAR ? @"minute" : @"minutes"; }
      else if (seconds) { amount = seconds; unit = amount == SINGULAR ? @"second" : @"seconds"; }
      else return @"now";
    
      // Format string and return.
      return [NSString stringWithFormat:@"%i %@ %@", amount, unit, direction];
    }
    
    @end
    

    Accessing extensions is simple: just import the header file. In the case above, easily readable dates are now at the finger tips!

    • 3 years ago
    • #apple
    • #cocoa
    • #iphone
    • #ipad
    • #mac
    0 Comments
  • A Few Reasons Cocoa Isn’t That Hot

    Over the past half-year I have been developing software for the iPhone (and recently iPad). Although I feel that Cocoa is excellent overall, a few rough edges prevent it from being a truly great experience:

    The Language

    Objective-C is the language of choice for most Cocoa developers (Cocoa can be accessed through bridges by Ruby, Python and a handful of other tools, however the vast majority of Cocoa programmers use Objective-C). It provides a thin layer on-top of the C program language, adding support for dynamic typing and messaging.

    Objective-C’s very fast execution speeds do not compensate for the amount of code required to perform trivial tasks (especially compared with Ruby or Python). Issues such as memory management and duplicate feature sets (NSString and string, NSArray and [], etc.) leave developers wanting something better.

    The Controls

    Interface builder is one of the best GUI designers available. That said, the iPhone and iPad controls are not nearly as verbose as the Mac desktop application controls. The lack of support for grids, checkboxes, color pickers, and even good looking buttons does not make any sense. It is obvious that Apple had to exclude tools that will not work on the mobile platform, but their over-zealous axing of features ultimately ended up increasing the workload for developers.

    Although Cocoa offers great customization of controls, developers must revert to code to get certain core features working. A great example is creating form elements within a table (something done in thousands of applications, including the ‘Settings’ app). Developers will need to setup delegates, protocols, and data-structures for something that should be drag-and-drop. For static forms, this is wasteful and time consuming.

    The Ecosystem

    Having recently spent some time developing in Ruby on Rails, I feel confident stating that the Cocoa ecosystem is terrible. Although a few great libraries and extensions exist the non-existence of a package manager means that third-party software is few and far between.

    Installation of almost anything introduces dependency headaches and is completely non-standard. A look through the 10-20 step guides required for any framework will make some cringe and others cry.

    Conclusion

    Given Apple’s reputation, it is a wonder better options are not available for Mac and iOS development. The benefits of releasing a 25 year old language on brand new mobile devices without not upgrading existing SDK’s with new languages (Microsoft has gone through at least four) are hard to find. Hopefully Apple attempts to improve both the languages and the frameworks in the future.

    • 3 years ago
    • #cocoa
    • #iphone
    • #ipad
    • #apple
    • #mac
    0 Comments
© 2009–2013 Kevin Sylvestre