HackStar Boston 2011 (Part 2)

TechStarsIn the first part of the article, I recount my HackStar experience at TechStars Boston. Today, I am going to talk about the impact of HackStar has on me and my current endeavor of doing a startup.

Before joining the program, I had thought that my time as a HackStar would be spent mostly coding, which is something I was more than happy to do. While being a HackStar is a lot of hard work, the truth is that I found that there is more than just battening down the hatches and code. To my surprise, HackStars are actually treated as participants of the program, just like any of the team members in the program. While Hackstars don’t get the one-on-one mentorship (since we are not founders), we like the teams have access and participate in activities like lectures, talks, and workshops led by mentors and guest lecturers. Of course there are times when I had to skip a few of the classes and events as I needed to spent more time working in tasks that may be time sensitive. However, I found these lectures and workshops extremely valuable (more so than the classes on entrepreneurship that I took in business school). TechStars lectures and workshops have highly relevant, useful content for starting entrepreneurs to take their startup to the next level. I would encourage any HackStar to attend these classes as much as possible. At the end of the day, it is all about time management and balancing between working on a project and attending classes. Nonetheless, HackStars at TechStars Boston really have unprecedental access and opportunities.

As an entrepreneur who recently started a startup called Invantory, I regularly seek veterans who are doing or have done a startup before. Conversation with them often bring new insights and perspectives, which adds tremendous value and clarity to what I am doing. The network that I built at TechStars has been very beneficial in this regards. Since starting Invantory, I have met with mentors and alumni asking them for their help and advice. In fact, many of them were enthusiastic about helping me in my endeavor. I have also found it gratifying to see how the teams grew in maturity and confidence during the course of the program. I am happy for the alumni of TechStars 2011, with whom I still maintain close interpersonal relationship. I really enjoyed the camaraderie of TechStars Boston.

I have had a long career working in big firms. Nonetheless I have always contemplated with starting my own company and struggled in pondering what is best for me. Do I choose job security and stability over starting my own startup with no or little money? The HackStar program provided that opportunity for aspiring entrepreneurs like me to try out the startup life for 3 months and gain skills that they can immediately apply when they can become real entreprneurs. The program has influenced my outlook, identified seeing what is missing, and discovering what are needed to be done in the context of building my startup.

TechStars’s official HackStars webpage provides a pretty comprehensive list of compelling reasons for joining HackStar. But if you are an aspiring entrepreneur and that your objective is to gain more exposure as well as expanding your network in this space, the choice is a no-brainer. Feel free to reach out to me if you have any questions about the program.

HackStar Boston 2011 (Part 1)

TechStarsIn this blog I hope to share my personal insights to TechStars Boston, a startup accelerator program, from the perspective of a HackStar. The term HackStar is a TechStars slang for a hacker (typically a software developer, a UX designer, or any technical contributor) who provides his/her time and technical skills to help companies selected for the program to become viable businesses by the end of the program. I joined TechStars Boston class of 2011 as a Hackstar in March 2011. For me, I didn’t apply for the program directly or formally. In fact the process happened quite impromptu. I first learned about the program from friends Brent and Eric at Everture, one of the incoming teams, two days before the start of the program. As I already know the managing staff at TechStars, I quickly arranged a meeting to meet with them to learn more about the program before being invited to join the program as a HackStar by the end of the day. The opportunity was great timing since I was transitioning from the industry to the freelance consultancy and entrepreneurship space in the software and Internet space. I already had some spare capacity which allowed me to commit to the program full-time. I also can’t pass up the opportunity of working with the incoming TechStars cohort and learning more about doing a startup. So my decision was really a no brainer. I accepted the invitation and joined the program.

TechStars Boston 2011 WorkshopThere were 12 teams that participated in TechStars Boston 2011. The teams brought a diverse background to the program. Geographically, half of the team were from outside of Boston with 3 teams from the UK, Estonia, and Israel. There was also more female representation in the program with 2 female founders and 1 female co-founder. The teams represent a pretty diverse group of businesses ranging from enterprise software to game to even hardware. I just love the diversity of the cohort. One of the important aspects of TechStars Boston has always been the people. The staff, teams, interns, and HackStars at TechStars Boston are all part of a very big, fun family. Everyone learn from each other. It’s an amicable, highly-collaborative environment. Teams and HackStars collaborated with each other. HackStars have as much to receive and learn from the teams as they do in contributing to the teams. Strong relationships extend beyond the program. TechStars also fosters building strong relationships with mentors, investors, and the startup community. The program invited veterans in the startup space to come mentor the teams or run workshops with variety of topics that are pertinent to the success of the companies.

Skill sets and seniority can very considerably among HackStars. However that didn’t distinguish any HackStar from the others. We are all equals despite our age, seniority, and background. HackStars assist anyone (staff and teams) in every way possible. Nonetheless, it is easy to get overwhelmed sometimes. HackStars could be assigned to a team long-term or be allocated to different teams or projects for quick hacks. There were 12 teams in our cohort and every team needed engineering help in some form or capacity. As a result, it was important to coordinate any work with the managing director. Katie Rae, the managing director at TechStars Boston, often asked for our preference in the types of projects we are interested in working. This helps her to coordinate and manage the needs as well as interests between the teams and Hackstars. The first six weeks at TechStars can be overwhelming for everyone. Something that I learned in my former job is that the busier people get, the more important it is for everyone to meet and sync up on a regular basis. One advice I have for any HackStar reading this post is that you should try meeting with the managing director at least once a week to sync up even if it is for 10 minutes. During the meeting, try to provide some feedback of the teams, update him/her what you are doing, and mention any coming tasks (standard stand-up meeting format from the Agile methodology). In general, there is no right or wrong way of doing things. The HackStar program, just like TechStars is constantly evolving. It’s a startup environment, so don’t be afraid to be a self-starter and be creative, while staying professional (always).

There are more I would want to write. But I have babbled enough (for now). I will continue the second part of this article in the next blog post tomorrow.

Blogging (Again)

BloggingI am ashamed of myself. I have not been updating this blog for sometime. So when my business partner Ian wrote a blog post on our company blog about derelict blogging and why it may not be good for everyone, I realize that something need to be done with this blog site. I can’t just leave it untended. So it’s blogging time again.

HTTP basic access authentication with Objective-C and iOS

iOS SDKIn this blog post I am going to show how you can make an HTTP request to a webserver that supports basic access authentication using Objective-C and the iOS framework. Regretfully, I don’t have the time to create an Xcode project as an example. But the information and code should give you an idea of how you can build basic access authentication support in your iOS code.

Before we dive into the code, let’s do a quick review of how basic access authentication works. Before an HTTP request is sent to the server, we need to append an HTTP header called Authorization to the request. Here are the steps to generating the Authorization HTTP header:

Using username = myusername and password = mypassword as reference.

  1. Concatenate user name + colon + password. ie. “myusername:mypassword”
  2. Encode the concatenated string with the base64 algorithm. ie. “myusername:mypassword becomes” “bXl1c2VybmFtZTpteXBhc3N3b3Jk”
  3. Append the Base64 encoded string to the “Basic ” string. ie. “Basic bXl1c2VybmFtZTpteXBhc3N3b3Jk”
  4. Finally assign the value to the Authorization header

In Objective-C code, the above logic is translated to:

NSString *authStr = [NSString stringWithFormat:@"%@:%@", @"myusername", @"mypassword"];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:@"Authorization"];

Just one problem, NSData doesn’t inherently support Base64 encoding. We need to add Base64 encoding algorithm to NSData via Category, a mechanism Objective-C that allows programmers to extend an existing class without subclassing it. Anyway, you can download the Base64 encoding code below.

NSData+Additions source code

Credits and Reference:

Note that you can certainly implement Base64 encoding using C functions or by other means. But I find Category most intuitive to achieving our goal.

Tip
If you are still stuck, use the curl command on a shell to troubleshoot. Here are some examples:

% curl -v -H 'Authorization: Basic bXl1c2VybmFtZTpteXBhc3N3b3Jk' 'http://host/path'

% curl -v --trace-ascii dump.txt 'http://myusername:mypassword@host/path'

Creating multi-variants of an iOS app from a single Xcode project

iOS SDKWhen someone at work asked me about creating multiple variants of an iOS app  from a common codebase (ie. from a single Xcode project), I thought couldn’t this be achieved through defining multiple targets in that Xcode project?

I have done this before for a project where I created a “lite” version and an “HD” (iPad-only) version from a full-featured iPhone codebase I originally created. I was about to document the process on this post before coming across this blog post from Just2Us, which does a great job in explaining the entire process. Instead of duplicating the content, just refer to the blog post.

One thing I would do differently from what is described in the referenced post is that instead of adding a new target, I would recommend duplicating an existing target – this way I avoid the hassle of configuring the new build target and including the files to my target phases manually.

Duplicating a build target in Xcode

I have also created a project to demonstrate the multi-target in Xcode. You can download the file here.

Quick guide to iOS dateformatting

iOS SDK

This blogpost will focus on the setDateFormat: method of NSDateFormatter which allow us to define the date format of the textual representation of the date and time in iOS/Cocoa. Here’s a summary of the specifiers used in the date format string.

The most commonly used date format specifiers are (keep in mind that they are case sensitive):

  • y = year
  • Q = quarter
  • M = month
  • w = week of year
  • W = week of month
  • d = day of the month
  • D = day of year
  • E = day of week
  • a = period (AM or PM)
  • h = hour (1-12)
  • H = hour (0-23)
  • m = minute
  • s = second

In general, the number of characters in a specifier determine the size of date field. Let’s use an example to illustrate date formatting.

eg. Input date = 2011-05-01 Sunday

1-character = 1-digit/character number or word (if number/word can’t be 1 character long then abbreviation or fullname is displayed).

[dateFormatter setDateFormat:@"E, d M y"];  // Output: Sun, 1 5 2011

2-character = 2-digit/character number or word (if number/word can’t be 2 character long then abbreviation is displayed).

[dateFormatter setDateFormat:@"EE, dd MM yy"];  // Output: Sun, 01 05 11

3-character = 3-digit/character number or word, or abbreviation (generally).

[dateFormatter setDateFormat:@"EEE, ddd MMM yyy"];  // Output: Sun, 001 May 2011

4-character = full name (generally).

[dateFormatter setDateFormat:@"EEEE, dddd MMMM yyyy"];  // Output: Sunday, 0001 May 2011

Here’s the weird part though, if you specify 5 E’s, you get an rather unexpected output. You would think that the output date field would be longer than 1 character:

[dateFormatter setDateFormat:@"EEEEE, ddddd MMMMM yyyyy"];  // Output: S, 00001 M 2011

For date formatting, the following reference table has been very useful:

Date Field Symbol Table (UTS #35 Unicode Locale Data Markup Language)

Back to blogging and a quick update

WordPress LogoIt’s been a while since I last blogged. Life has been so hectic that I hardly have the time to blog (not that I have been blogging regularly). I have been working on multiple projects since the beginning of the year. So I have been super busy with work.

In the beginning of the year, I have been toying with the idea of creating a new business in producing my own independent software products. But after careful consideration, I decided to focus on developing my consulting services in mobile and digital interaction development to establish a more steady stream of cash flow. I am still incubating these product ideas of mine on the side. Hopefully, I can start spending more time by Fall and turn one of these ideas into a viable business.

Materials for my iOS frameworks talk at MobileCamp Boston

Presentation Screen IconI will be speaking at MobileCamp Boston on Feb 19, 2011 (later today). I will be giving a presentation on building RESTful iOS apps using Three20 and RESTKit frameworks. I will write a blog entry with a more detailed coverage of my talk later. For now, here are the presentation slides and the TwitterReader Source Code I will use at the talk. Enjoy.

Icon credits: Jack Cai

TTTableViewController showMenu:forCell: example

iOS SDKA week ago, I was looking for ways in Three20 to create an animated row menu similar to the behavior in the Facebook app where a the table cell switches to a view with a “Like” and a “Comment” button. Upon more investigation, I discovered showMenu:forCell: in TTTableViewController that does exactly what I am looking for. Unfortunately Three20 documentation and samples shed little light on how showMenu:forCell: should be used. I also googled around and found a simple example and found this post on Three20 discussion thread on Google Groups, which was enough to get me started in right direction.

iPhone table view iPhone table view show menu

I messed around with the code further and came up with a more coherent technique in creating the animated show menu effect using showMenu:forCell: Here’s a snippet of the same code demonstrating how you can trigger the menu view by swipe gesture.

- (void) viewDidLoad {
  // Register the swipe gesture.
  UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc]
                                          initWithTarget:self
                                          action:@selector(swipeDidOccur:)];
  [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight |
                            UISwipeGestureRecognizerDirectionLeft)];
  [self.view addGestureRecognizer:recognizer];
  [recognizer release];

  [super viewDidLoad];
}

- (void) swipeDidOccur:(UISwipeGestureRecognizer *)recognizer {
  // Get the start point so that we can do a hit test on the table view.
  CGPoint startPoint = [recognizer locationInView:self.tableView];
  NSIndexPath *path = [self.tableView indexPathForRowAtPoint:startPoint];
  TTTableViewCell* cell = (TTTableViewCell*) [self.tableView
                                              cellForRowAtIndexPath:path];

  // Add menuView to the cell.
  UIView *menuView = [[UIView alloc] initWithFrame:cell.contentView];

  // Now call showMenu with the menu to display on the associated cell.
  [self showMenu:menuView forCell:cell animated:YES];
  [menuView release];
}
The code relies on detecting swipe touch gesture on TTTableViewController and using a selector to handle the gesture. Given a gesture touch point, you can determine the cell where the swipe occurred. Once you have a reference to a cell, you can call the showMenu:forCell:
What if we need to trigger the menu view by touch a button on the table view cell? This is what I did:
Create a subclass of TTTableViewCell and add a UIButton to the view.

The code relies on detecting swipe touch gesture on TTTableViewController and using a selector to handle the gesture. Given a gesture touch point, you can determine the cell where the swipe occurred. Once you have a reference to a cell, you can call the showMenu:forCell:
What if we need to trigger the menu view by touch a button on the table view cell? This is what I did:

Create a subclass of TTTableViewCell and add a UIButton to the view.

@interface MyViewCell : TTTableViewCell {
}

- (id) initWithName:(NSString *)name target:(id)target action:(SEL)action {
  // ...

  UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
  moreButton.frame = CGRectMake(268.0f, 6.0f, 32.0f, 32.0f);
  [moreButton setImage:TTIMAGE(@"bundle://Icon_More.png")
              forState:UIControlStateNormal];
  [moreButton addTarget:target action:action
       forControlEvents:UIControlEventTouchUpInside];
  [self moreButton];

  // ...
}

Next, create a subclass of TTTableViewController and add the custom TTTableViewCell to the data source.

@interface MyTableViewController : TTTableViewController {
}

- (void) createModel {
  self.dataSource = [TTListDataSource dataSourceWithObjects:
    [[[ContactViewCell alloc] initWithName:@"Cell 1"
                                    target:self
                                    action:@selector(plusButtonDidPress:)]
                                    autorelease],
    [[[ContactViewCell alloc] initWithName:@"Cell 2"
                                    target:self
                                    action:@selector(plusButtonDidPress:)]
                                    autorelease],
    nil];
}

In the action handler, that’s where showMenu:forCell: is called. The trick is to determine which cell the button belongs to and consequently replace that cell withe the menu view. This is how I did.

- (void) plusButtonDidPress:(id)sender {
  // Load our custom menu view from a nib.
  UIView *menuView = [[UIView alloc] initWithFrame:cell.contentView];

  UIButton *moreButton = (UIButton *) sender;
  // Convert plusButton bounds to the the coordinate system of table view
  // and then get the cell containing the button.
  CGRect coord = [plusButton convertRect:moreButton.bounds toView:self.tableView];
  NSIndexPath *path = [self.tableView indexPathForRowAtPoint:coord.origin];
  TTTableViewCell* cell = (TTTableViewCell*) [self.tableView
                                              cellForRowAtIndexPath:path];

  // Now call showMenu with the menu to display on the associated cell.
  [self showMenu:menuView forCell:cell animated:YES];
}

Here’s the entire source code on GitHub. Enjoy.

Update

Since some of you asked, I have updated the sample on GitHub to include an example of you can “wire” the buttons on the MenuView to the appropriate action handlers.

First, create a base view controller called BaseCatalogViewController containing the action handlers and have the other 3 controllers inherit the base class. The file’s owner of MenuView.xib should be of type BaseCatalogViewController. Lastly, associate each button in MenuView.xib to an IBAction. You can find the source code at GitHub. Good luck.

Proper URL (Percent) Encoding in iOS

iOS SDKIf you are developing an iPhone app makes RESTful remote calls to a server in the Internet, you will likely need to encode your parameter to a percent encoded string (aka URL-encoding) so that you can properly embed the information in a URI before passing it to the remote server. For example, say you have an address that looks like this:

One Broadway, Cambridge, MA

Under URL encoding, the string becomes:

One%20Broadway,%20Cambridge,%20MA

To encode a string using URL-encodng, simply use following method in NSString:

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

Conversely, you can use the following method to decode a URL-encoded string to back to its original text:

stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding

Full example:

NSString *rawText = @"One Broadway, Cambridge, MA";

NSString *encodedText = [rawText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Encoded text: %@", encodedText);
NSString *decodedText = [encodedText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Original text: %@", decodedText);

Here’s the output:
Encoded text: One%20Broadway,%20Cambridge,%20MA
Original text: One Broadway, Cambridge, MA

But there’s just one problem, stringByAddingPercentEscapesUsingEncoding doesn’t encode reserved characters like ampersand (&) and slash (/). For example:

NSString *rawText = @"Bed Bath & Beyond - URL=http://www.bedbathandbeyond.com/";

NSString *encodedText = [rawText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Encoded text: %@", encodedText);
NSString *decodedText = [encodedText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Original text: %@", decodedText);

Here’s the output:

Encoded text: Bed%20Bath%20&%20Beyond%20-%20URL=http://www.bedbathandbeyond.com/
Original text: Bed Bath & Beyond – URL=http://www.bedbathandbeyond.com/

As you can see, & and / (in bold red) aren’t encoded. As a workaround, use Foundation function CFURLCreateStringByAddingPercentEscapes instead (as suggested by Simon). Full example here:

// Encode a string to embed in an URL.
NSString* encodeToPercentEscapeString(NSString *string) {
  return (NSString *)
  CFURLCreateStringByAddingPercentEscapes(NULL,
                                          (CFStringRef) string,
                                          NULL,
                                          (CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                          kCFStringEncodingUTF8);
}

// Decode a percent escape encoded string.
NSString* decodeFromPercentEscapeString(NSString *string) {
  return (NSString *)
  CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
                                                          (CFStringRef) string,
                                                          CFSTR(""),
                                                          kCFStringEncodingUTF8);
}

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  NSString *rawText = @"Bed Bath & Beyond - URL=http://www.bedbathandbeyond.com/";

  NSString *encodedText = encodeToPercentEscapeString(rawText);
  NSLog(@"Encoded text: %@", encodedText);
  NSString *decodedText = decodeFromPercentEscapeString(encodedText);
  NSLog(@"Original text: %@", decodedText);

  [pool drain];
  return 0;
}

And the output:

Encoded text: Bed%20Bath%20%26%20Beyond%20-%20URL%3Dhttp%3A%2F%2Fwww.bedbathandbeyond.com%2F
Original text: Bed Bath & Beyond – URL=http://www.bedbathandbeyond.com/

This time it correct encode the & and / characters. Of course, you won’t be encoding the entire URL but only the URI parameters. There’s no code download for this, simply cut the above code snippets to your code and paste to your code base.

Errata (Feb 18, 2011)

CFURLCreateStringByAddingPercentEscapes returns a string reference with a retain count of +1. So remember to release it when you are done using it.