The Conversation Always Continues On HuffPost Live for iPad

It’s been almost 7 months since I joined Huffington Post’s iOS team. I’ve been so excited about what we’ve been working on that I forgot to write about the first app that we published a few months ago: HuffPost Live for iPad.

For those of you who haven’t heard of HuffPost Live, it is a live-streaming video network that uses the best content on the Huffington Post and around the web to jumpstart community-driven conversation and commentary.

HuffPost Live launched last August but it’s already experienced great success. Last December it was named Mashable’s biggest media innovation of 2012. At the moment, the app itself is number 15 on Apple’s Top Free iPad News Apps, ahead of HuffPost’s flagship news app (#19) and the Huffington magazine (#26).

Things are only going to get better and better for HuffPost Live. It makes me very proud that I could be a part of it.

Without further ado, this is what the app looks like when you first open it in landscape:

A couple of things to notice here:

  • Live Segment: Each segment is about 30 minutes long. Each segment has its own topic, its own host and its own set of guests.

  • Comments section: Each segment also has live comments. Sometimes, the host will feature interesting comments that add to the conversation.

  • Be An On-Air Guest: Anyone from the community who has something useful to contribute can tap on the red button, complete a short audition process and join a live segment as a guest using Google Hangout.

  • Coming Up: Right under the live segment is the list of upcoming segments. While a segment is in “green room” mode, you can audition to be a guest or leave a comment.

If you tap on the segmented control below the sharing button, the app will take you to the segment’s resource well:

The resource well is a repository of different types of information (HuffPost articles, photos, tweets, etc…) relevant to the current segment.

Now, if you turn the iPad on its side…

Portrait mode looks completely different than landscape mode. The live video takes up half of the screen. The list of upcoming segments is still accessible if you swipe the comments section to the right.

Notice the white button above the title? That wasn’t there in landscape mode. Tapping on it takes you to…

Grid-style comment (or sexy mode as we know it internally). If you tap on the arrow button you can even make these grid comments full-screen:

Why would you need full-screen comments in a video streaming app, you ask? Second screen experience, my friend.

In this mode, you can send the video stream to your Apple TV using AirPlay and interact with the comments at the same time. This is something unique to the iPad app that the website can’t do.

Live content is great, but what if you want to watch a previous segment? Simply tap on the Archive button and it will take you to this screen:

Here you can see all the recently aired segments. If you want to go further back, you can do a search on the top right.

Tapping on an archived segment takes you to a similar screen as the live segment, but with minor differences. This is what an archived segment looks like:

You can download HuffPost Live for iPad here or watch it on your browser on live.huffingtonpost.com. Hope you like it!

Comments { 0 }

iPeru version 1.0

Hungry for some Peruvian food? I know I am. The problem is that I usually don’t know where to find good Peruvian restaurants around me. Yes, I could open up any number of websites and apps (among them Yelp, Foursquare, good ol’ Google search) and look for Peruvian restaurants the old fashioned way. However, all of these traditional methods take too many steps. I just want to open up an app and instantly see all the Peruvian restaurants around me on a map or a list. Enter iPeru.

iPeru is the easiest way to locate Peruvian food when you are hungry for some ceviche. It cuts out all the noise by just showing you the information you need – your current location and the Peruvian restaurants around you. Some other features:

★ Peruvian restaurants are displayed on a map or a list. Tapping on a restaurant shows you its mini map, address and phone number.

★ You can search for Peruvian restaurants using any given address, city, or zip code. Search works in all countries.

★ Once you find a Peruvian restaurant that you like, you can save it as a “Favorite” so you don’t have to find it again in the future.

Special thanks to the folks at Foursquare for allowing developers to use their API. iPeru will be available in the App Store in 2-3 weeks (Edit 11/25/2012 - iPeru is live in the App Store today, much sooner than expected!) It’s something I’ve always wanted to have on my phone and I hope you like it too.

The source code for iPeru is available on Github. The only thing missing from the repository is the file “TPSettings.m” because it contains my Foursquare API keys.
Comments { 0 }

How to hide the cursor in a UITextField when using a UIDatePicker/UIPickerView

10/13/2012 – Since the first version of this post, I’ve put the subclassed UILabel up on Github. It comes complete with a working demo for the iPhone and iPad.

A UITexField is a native iOS object that allows a user to input text with a keyboard. However, in some cases what you really want to do is to allow only a discrete number of text inputs.

The first thing you may try is to bring up a UIDatePicker or a UIPicker instead of the normal keyboard when the user taps on a text field. Then, you could try changing the UITextField‘s value based on what the user selects on one of these pickers.

This is accomplished by rewriting a UITextField‘s inputView property.


//Create a UIDatePicker
UIDatePicker datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:@selector(datePickerChanged:) forControlEvents:UIControlEventValueChanged];

//Set the textField's inputView to be the UIPicker
self.textField.inputView = datePicker;

But then you run into this problem:

The cursor is still there. This may seem like a small problem but it is really, really bad. The user could use the cursor to copy-paste whatever he or she wants in there. This defeats the purpose of limiting possible inputs and can even corrupt your data if you are sending this input to a backend server.

Then there is the UI design problem. The user is confused. Do you want me to type or do you want me to choose? Keeping the cursor there is sloppy.

There may be other ways around this problem, including hiding the UITextField behind another UITextField, using invisible buttons, disabling copy-paste functionality, etc… These all feel like they are cool little hacks (I couldn’t get any of them to work) but the way I’m proposing here is simple, elegant and object-oriented. It’s a UILabel subclass that I’m calling PRLabel until I can find a better name for it.

Header file:


#import <UIKit/UIKit.h>

@interface PRLabel : UILabel

@property (strong, nonatomic, readwrite) UIView* inputView;
@property (strong, nonatomic, readwrite) UIView* inputAccessoryView;

@end

Implementation file:


#import "PRLabel.h"

@implementation PRLabel

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}

- (BOOL)isUserInteractionEnabled
{
return YES;
}

- (BOOL)canBecomeFirstResponder
{
return YES;
}

# pragma mark - UIResponder overrides

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self becomeFirstResponder];
}

@end

PRLabel overrides five things from the original UILabel. The first two are the properties inputView and inputViewAccessory. These properties are inherited from the UIResponder and they determine what views (keyboard, date picker, etc) come up when a UIResponder object becomes firstResponder.

Both of these properties are read-only by default in a UILabel so we have to override their pointers in the implementation file (e.g. @property (strong, nonatomic, readwrite) UIView* inputView).

Third, you need to override the getter method isUserInteractionEnabled to always return YES. This property determines whether or not a UI object should respond to touch events. The default is NO for the UILabel class because static text is not supposed to be interactive.

Fourth, UILabel cannot become firstResponder by default. The inputView only comes up when an object becomes first responder so we also need to override the method canBecomeFirstResponder in our UILabel subclass so that it always returns YES.

Finally, we need to override the touchesEnded method that is inherited from UIResponder so that the PRLabel object becomes first responder by default when it detects a touch. This can also be done with a gesture recognizer, but doing it this way maintains a clean UIResponder chain.

After all these changes have been made, you can use your new PRLabel instead of a UITextField and you won’t have to worry about the cursor when you hook it up to a picker.

Comments { 5 }

Replica Power closes down in 2012

Replica Power 2008-2012

There’s something about my online identity that few people know about. There’s the usual stuff. I use social networks. I appreciate a good meme. I read HackerNews and TechCrunch and generally try to keep up with new technologies.

But there’s something else.

For almost four years, I owned and operated an e-commerce store called Replica Power. That link was a screen shot of what the homepage used to be. As of today, the actual URL, replicapower.com, points to nothing.

More on that later.

Replica Power was my biggest side project during college. It never grew past the size of a hobby but it did teach me a lot about running a small business. I learned how to incorporate a business in the state of Virginia. I learned how to work with accountants, programmers, designers and freelancers. I learned what to say to a dissatisfied customer. I learned how to negotiate better.

Replica Power took me to Silicon Valley for the first time ever. Back in October, Princeton’s entrepreneurship club was organizing a week long trip to the valley. Close to a hundred students applied for the twenty spots on the trip. The only thing I had going for me was my online store so I featured it prominently in my application.

Long story short, Replica Power was my ticket to the promised land. We visited the usual suspects (Google, Apple, Facebook) as well as many well known startups like Nest, Path and Square. We met Jack Dorsey, Meg Whitman, John Doerr among many others.

At this point you may be wondering what Replica Power actually sold. Glad you asked! At its peak, I was selling movie prop replicas, video game replicas and medieval replicas. We’re talking Harry Potter’s wand, William Wallace’s Braveheart sword and that one sword that defeated Sauron the first time around. If it was geeky and had the potential to make the owner slightly embarrassed, I sold it.

At one point, I worked with 8 suppliers and had more than a thousand products online. I didn’t even need to own any inventory. Whenever I got an order, I would simply forward it to the right wholesaler and they would take care of fulfillment. My main job was to sell.

I tried many different things to increase sales over the years. I added a 1-800 number and convinced by girlfriend to record a message with her voice. “Thank you for calling Replica Power…”. I signed up for a UPS Box so I would have a credible mailing address. ”4196 Merchants Plazasounded much better than a P.O. box. I experimented with live chat and e-mail marketing. I tried Google Adwords, customer testimonials, free shipping, discount coupons. It was like playing with legos.

So what went wrong? There were a few things. As time went on I started to get worried about my product line. Early on, Paypal shut down my merchant account because they thought I was selling weapons. I called them right away and explained that they were collectibles, not weapons. None of the “swords” had a real edge. They were meant to be displayed on a wall.

But that got me thinking. Do I really want to be selling these things? What if someone got hurt? I got into the sword business not because I like swords (I don’t even own one) but rather because the guys I learned e-commerce from owned a sword store. It seemed like a viable niche and I didn’t know where else to start so I went for it.

Then there was the problem of time. Replica Power was a one-man show for most of its life. The problem was that I was also a full time college student. As much as I wanted to focus on cool side projects, I found that I couldn’t force myself to ignore academics. Sad, but true.

I would sometimes get calls from customers right in the middle of lecture. Orders would pile up during finals week. People would get mad. I solved this problem by hiring part time help from a virtual assistant in the Philippines. She was more responsive and reliable than I could ever be. Still, I felt that I wasn’t providing the kind of customer service that I have come to expect from top-notch companies. This bothered me a lot.

Then there was the issue of technology. Replica Power was built on Yahoo’s e-commerce platform. In 1995, Paul Graham and his co-founders started a company called Viaweb. It was one of the first (maybe the first?) startup to offer an end-to-end e-commerce solution to small businesses. No longer did small business owners have to spend a small fortune to be online. They would simply sign up with Viaweb and use their intuitive WYSIWYG interface to create their online store. In 1997, Viaweb was acquired by Yahoo for a good chunk of money.

I have great respect for Paul Graham and what he’s done with Y-Combinator. In its time, Viaweb was on the bleeding edge of technology. The problem is that the technology is now 15 years old. The Internet has been reinvented more than a couple of times since then. In Internet years, 1995 brings us back to the stone age. Viaweb predates Facebook, Twitter and Google. It’s easy to blame Yahoo about not keeping up with the times, but it’s kinda like the subway in New York City. How do you update your systems without pissing off millions of people?

Anyways, hindered by all of these problems, I slowly started scaling back Replica Power. I cut down the number of suppliers. I took down all anything that could be misrepresented as a weapon. I eliminated international shipping. After doing all of this, it didn’t make business sense to keep the store running anymore. That’s why I’m closing it down today.

Looking back, the most lasting influence from my e-commerce days comes from the people that I grew to admire while I was working on Replica Power. People like Scott Sanfilippo, Shawna Seigl and Rob Snell. Scott co-founded  Solid Cactus, the company that did the custom design and programming work for Replica Power. Shawna also runs a company that specializes on building Yahoo stores. I never worked with her team but I used to listen to her e-commerce radio station religiously. Rob wrote the best book on Yahoo stores and he is a frequent speaker on the topic.

What I admired the most about them was the independence they had built for themselves. They all ran successful companies that focused on helping people. This allowed them to lead fulfilling and interesting lives. That, to me, was the American dream come true.

What I’ll miss the most about Replica Power is working with my customers. A couple of years ago around February, I got on the phone with a woman who was trying to decide what to get her boyfriend for Valentine’s day. She ended up choosing a replica of Gimli’s battle helmet from Lord of the Rings. She was concerned that the shipping she’d pay for wouldn’t get her the helmet on time. I upgraded the shipping at no extra charge and she thanked me profusely. She then wrote an e-mail to my “manager” explaining how helpful I’d been. That short, thoughtful e-mail made me happy for days.

Then, last month, when I thought no one cared about Replica Power anymore, I received this letter in the mail from a boy named Justin from Madera, CA.

I am always going on your website and saving pictures of your wands to just dream. I love your work you have an amazing gift. I have always begged my parents for them to buy me McGonagall’s wand and sadly, they won’t :( . And is the wand of Grindelwald just a stick, because that’s what it looks like (no offense).

I really like the constructive input he gives me on Grindelwald’s wand. Justin doesn’t know I don’t make the Harry Potter wands myself, but that’s not the point. The point is that a young boy in California used to check my website regularly to “just dream”. To just dream! That’s invaluable to me.

At the end of the letter, Justin politely asks if I can send him McGonagall’s wand because he can’t afford one right now. No worries Justin, I got you covered.

As I’m powering down Replica Power, I can’t help but think that this experiment could have been much, much more. Out of no where, I would get calls from TV shows like Deadliest Warrior and 30 Rock because they urgently needed to get one of my products. I sold a helmet to Deadliest Warrior but I didn’t call back the lady from 30 Rock on time (also, I can’t imagine what they needed). I was regularly approached by manufacturers from India and China that wanted to work with me. I got invitations to go to trade shows in Shanghai.

But no, I’m starting my first job in two weeks and I want to devote all my creative energy into that. It pays to know when to say no.

Lastly, there is only one thing that bugs me about the whole experience. All this time, I was extremely secretive about this personal project. This is the first time that I’m publicly attaching my name to Replica Power. The only people that knew about it before were my immediate family members and my closest friends. Everyone else was on a need-to-know basis.

I don’t know why I didn’t want to tell anyone. Was it that I wasn’t proud of my work? Would I feel vulnerable? Judged? Legally liable? I don’t know what it was but it was not a good feeling. From now on, everything I do will have my name on it. No more fear.

This post was much longer than I intended it to be. It has much more detail than you ever cared to know but I wrote this more for me than for you. It’s difficult to say goodbye to something you’ve done for four years.

Comments { 0 }

Glue iOS app

Design by Alice Zheng

Back when I was in college I would sometimes forget to make dinner plans and I’d end up eating alone in the dining hall. Other times, I would want to watch a movie but I wouldn’t know who was around or available at that moment so I’d end up not going.  I pretty much sucked at planning.

How can it be that in the age of e-mail and Facebook I was having trouble getting together with my friends? I knew I wasn’t the only one with this problem. Startups like Meetup and GrubWithUs are out solving some version of the same problem. Even Sean Parker’s new company Airtime is aimed at “eliminating loneliness”.

Asking your friends to spend time with you one by one (via phone, SMS, e-mail) is feasible but it is painfully slow and cumbersome. It is also too formal. Instead, I wanted to be able to broadcast an open invitation to my close friends. “FYI, I’m having lunch in Chipotle right now. Come if you’d like to join me.” In this sense what I was envisioning was not really an invitation. It was more of an uber-social Foursquare check-in with less focus on location and more focus on informal, spontaneous gatherings.

This idea bounced around in my head for a while. I even pitched it on Princeton Pitch during my senior year of college to see if it would get any traction. I didn’t win but it got mentioned in the Daily Princetonian (I called it EatWithMe at that point).

Then a golden opportunity presented itself. I enrolled in COS 333, taught by the legendary Brian Kernighan. The class was mostly based on a huge team project that students start halfway through the semester. I knew I wanted to learn iOS and that I wanted to test this system of open invitations.

Long story short, I teamed with a talented designer/coder, my friend Alice Zheng, to build Glue. She focused on the back end server while I focused entirely on iOS and Objective-C. We did not submit the app to the App Store and the end product was not anything mind blowing but making the app was an amazing learning experience.

What follows are some technical specifications for Glue, pretty generic stuff as far as a modern iOS app goes. I also included a short demo I put up on Youtube:

FRONT-END (Yours truly)

Glue is an iPhone application built for iOS 5.1 using Xcode 4.3.2. There are two important things about Glue’s development environment. First, Glue uses Xcode’s ARC functionality (automatic reference counting). ARC saves us the trouble of having to do any sort of memory management in Objective-C, which used to be a common source of frustration and bugs before iOS 5.

Second, Glue also uses Storyboards. Storyboards lets developers drag and drop most user interface elements (e.g. navigation bars, buttons) onto a canvas and to define different views (e.g. login page, settings page) and segues between those views. Before Storyboards was released in iOS 5, developers had to work with individual UI files, called .xib or “nib” files, and had to set up a lot of the app’s UI programatically. Using ARC and Storyboards changes the source code substantially, so knowing how they work is important.

Understanding MVP (model-view-controller) and how objects communicate in Objective-C was also crucial for building an app. To access information about the user that is currently logged in (e.g. name, e-mail), I used a singleton class to represent the current user. In addition, if I wanted to pass information from one view to another, I would typically use the method prepareForSegue (unique to iOS 5) or delegation.

BACK-END & GRAPHICS (Alice Zheng)

Glue needed to have a back end server in order to handle users and to coordinate user-created events. Glue’s server was hosted on an Amazon Red Hat Linux EC2 instance running Apache 2.2.15. We chose to store data in a flat file instead of using an actual database like mySQL or mogoDB. This was mostly done for simplicity because we were going for proof of concept rather than robustness. This next bit was written by Alice:

“The server-side code is written in Python using the Bottle microframework, which essentially allows us to write functions to handle every supported request by attaching functions to routes. We also use Bottle to access GET parameters. For documentation and instructions on how to install Bottle, check this out“.

A working demo of Glue:

 

 

Comments { 0 }

5 Things I Learned From CrossFit

It is no secret that I’m not very fond of going to the gym. It’s not that I don’t like to exercise – I do. It’s just that there is always something more interesting or urgent that gets in the way. For years I was unhappy with the amount of exercise that I used to get but I simply couldn’t find a way to change my old habits. Then I found Crossfit.

Crossfit is very different from a traditional gym. Every day there is a different “WOD” (workout of the day). Most of the exercises that make up the WODs are functional movements like push-ups, pull-ups and flipping 500 lb tires down a parking lot. This means there are no ellipticals or weigh lifting machines in a Crossfit gym.

The WODs are always performed as a group, which adds camaraderie and competitiveness, and they are guided by a professional trainer. When you are done with the WOD, you write your time on the wall. Since you know your score is going to be public, you actually try (very hard) not to look like a fatty.

I did Crossfit for 2 months and I was surprised with the results. I’m still new to Crossfit, but my limited experienced with it has taught me a few important things:

1. Dont change yourself, change the context
This was the biggest lesson for me. As you probably know, it is extremely hard to change a habit. You can’t simply “will” yourself to eat better, save more money or be more disciplined. However, people are extremely context-sensitive. If you can’t change yourself, change the context around you in a way that makes you adapt in a positive way.

Crossfit is a change of context. It makes working out a social activity, almost like a high school or college sports team. You are no longer working out by yourself but rather you are a part of a community. Over time you get to know everyone by name. This change of context creates accountability, which motivated me to show up every day and go all out. Amazing.

2. There are always people who are better than you
Always. I thought I was in relatively good shape until I went to Crossfit. There are 45 year-old moms that beat me at every single WOD. In whatever field you are in, no matter how good you are, remember that there are always going to be people lightyears ahead of you. Accept this. Find these people and learn from them.

3. Do things that you are barely qualified to do
I’m not going to lie, I’m barely making it in most of the WODs. I’m usually one of the last ones to finish a workout. When I feel discouraged, I start to think, who is getting more out of this workout, the 45 year-old mom who is kicking my butt or me? Me. Her improvements are incremental at best whereas I’m doubling my strength in some cases.

Crossfit taught me to seek things that break me past my current abilities (e.g. intellectually, physically). Why go to a regular gym when I can go to a gym that asks me to do things that I cannot currently do? The only way to improve is by pushing yourself day in and day out.

4. Embrace unreasonable expectations
Some of the WODs seem impossible to accomplish. 50 handstand pushups, followed by 50 pull-ups and 50 dead lifts, all of that 10 times for time? You got it (gulp). When you actually do the WOD, however, you realize that they are really, really hard but definitely possible.

Doing things that are (on the surface) “impossible” is probably the best exercise if you want to do something interesting with your life. Not getting dissuaded by the “impossible” is a skill. Like any skill, you get better with practice.

5. Think different
Crossfit has spread far and wide because it gets people hooked. It just so happens that the Crossfit model is the *complete opposite* from the traditional gym model. I bet many people scoffed at the idea of having a gym without ellipticals and without tons of weight lifting machines. All you really needed was some basic equipment, a little competitiveness and a lot of team spirit.

Crossfit is a great example of challenging the assumptions in the old way of doing things and coming up with something awesome.

 

Comments { 0 }