Socialcam for Android version 1.3

We're cranking hard on Socialcam for Android. Now, with version 1.3,  our Android friends can enjoy some of the same hit features from the iOS version.

With the latest update, you can share your videos over Facebook, Twitter, Posterous, Tumblr, and Dropbox, with improved UI. You can also find new friends via Facebook, Twitter, and your address book, or search by name. There were a few remaining bugs that were causing crashes. These have been banished! 

Update ASAP

I Broke Justin.tv

*Note: This post comes from Ammon Bartram. You can read more about Ammon on our Jobs Page

I broke Justin.tv on my 2nd day on the job. I was fresh out of college, and I'd never done any real programming work. I typed video33 instead of video3 in a console. This small mistake shutdown a production server with thousands of streams. Damn! Three weeks later, I failed to remove daemon init scripts from a re-purposed server, and unleashed a pack of rogue daemon processes on the site. (Rogue daemons on the loose! Unholy apocalypse!!!) Finally, a few months into the job, I wrote “break” where I meant “continue,” and caused our payments servers to shutdown one-by-one over the course of several weeks.
  
These were not my brightest moments as a programmer. Still, I think that these examples show some of the best things about working at Justin.tv: 1) we work fast, 2) we push code often, and 3) we throw new engineers into real projects and expect them to do real work.
 
This culture has allowed us to build our own global live video CDN with a capacity of hundreds of gigabits per second, to archive and transcode all of this video, and to create the Internet's largest live video community in just a few years -- all with under 20 engineers. Pushing code fast and often does have a cost, but the benefit in productivity is well worth it.
 
Beyond productivity, our coding culture is rewarding. When I interviewed at Justin.tv, I was also considering a bunch of larger tech companies. What stood out at JTV was the scrappiness - no RFID badges or red tape here. I was interviewed in a storage closet, between a drink cooler and a broken chair. I remember Emmett telling me during my Interview that the company had more systems than engineers, and that I would thus be fully responsible for at least one critical system. This was scary at the time, but also exciting. And it's why I chose JTV over my other offers.
 
It was a great way to start a career. My first assignment was to come up with a better content replication algorithm that would allow us to expand to multiple data centers. I spent a week trying different things, while learning Python and trying to get a handle on the codebase. After I had a working algorithm, I put together a simulation to show that it was better than what we had before. The first attempt to push it to production hosed the DB. But after I'd optimized the queries and re-pushed, it worked. Three weeks out of college, and I'd just re-written the core content replication algorithm of the site.
 
After starting, I went to work full-time on the video back-end. We added data centers across the US, built real-time transcoding, developed an iPhone viewer, and fended off DOS attacks. After 8-months, when my teammate decided to move to rails work, I became the lead video engineer. Finally, six months ago, Socialcam was born, and I moved to that team. We spent two months designing protocols and interfaces, working hard to bring Socialcam 1.0 to the iPhone App Store and Android Market. Socialcam is off the ground now - yay for 1M downloads!, but we're still in early product mode, making big changes with every release.     
 
Things are not quite as wild-west at Justin.tv as they once were. We now have QA (Thanks B!), monitoring and deploy management. The office is nicer (interviews no longer take place in the storage closet). The site goes down less often now (editor’s note: It never goes down now).  But we still have way more critical systems than engineers, and we push code to production tens of times every day. And I'm still looking forward to what's coming.

- Ammon

Thank You! Socialcam Passes 1 Million Downloads

Thank you to each and every Socialcam user. Today, we're proud to announce that we've surpassed the 1 million download mark. Those of you who haven't yet tried it out, please do so now

Check out the coverage in TechCrunch

We're also releasing the latest version of the iPhone application (v2.3) today. We are comitted to our original value proposition: Socialcam is the easiest way to share videos with friends. We've also talked with a lot of you, our users, about features you want. Taken together, these two directives have produced a clear product roadmap that makes the app even better.

See below for the newest features. We're already working on hard on the next iteration, and it's coming soon. Stay tuned! 

New Features in v2.3

  • Activity feed. It’s now easier to see what your friends are up to. We created a new activity feed so you can see what your friends are commenting, liking and following in the app at a glance (see screenshot below).
  • Trim feature. Our users told us they wanted some basic editing functionality. As a first step, we’re rolling out a simple “trim” feature so that you can select only the best footage while in the creation flow (see screenshot below). 
  • Tap-to-focus. This is another simple feature to help make the video content a little better, and easier to capture. 

Other Recent Features

  • Multiple log-in options. The original app required Facebook authentication. You can now create a fresh Socialcam account with your email address. 
  • More sharing options. The list now includes Facebook, Twitter, Email, SMS, Posterous, Tumblr and save to DropBox. 
  • More Friend Discovery. People want friends to share their videos with. In the original app, finding friends was not so easy. We heard the users loud and clear, and created a way to scan your Facebook friends, Twitter followers, and your entire address book.
  • Translations. The US is still by far and away our biggest geo, but we found that Europe, Asia and the Middle East are also huge. So we've done a batch of translations in order to give these folks a native app in their own languages. French, Italian, Chinese, Arabic, Japanese, and more.

Win an iPad 2 by using Socialcam!

 We have some big news coming next week about Socialcam.

To celebrate early we are running a two week long contest with the help of our friends at PunchTab. The prize: an iPad 2!

The contest is social like our app, you will earn entries to win the iPad 2 for all of the Facebook Likes your videos generate and for helping to spread the word. At the end of two weeks we'll draw a winner.

It's super easy to enter and the contest is Worldwide. Remember, the more friends you invite and likes you get the higher your chances of winning.

Participate here

New Version of Socialcam for iPhone Released

We've just released the latest version of Socialcam for iPhone (version 2.2). Install the new app here.

This version includes some of the most requested feature enhacements that we've heard from Socialcam users over the last months. Thank you for all of your feedback. Please keep it coming!

The new version includes:   

New Log-in Options
In addition to Facebook log-in, you can now create a fresh Socialcam account using your email address. This was one of the most-requested features and now it's available.

Find Friends
You now have more options to find friends using Socialcam. You can now scan your Facebook friends, Twitter followers, and your entire address book. Then simply "Follow" them to see their videos automatically. 

We're Global
Socialcam is popular all over the world, so we've translated the app into 11 new languages including French, Italian, German, Arabic, Japanese, Chinese and more.

Personalize your Profile
Now you can edit your profile by changing your name and choosing your own profile picture. 

New Version of Socialcam for Android Released

We just released a new version of the Socialcam app for Android (version 1.0.4). We've been cranking hard on making the app even better. This version has some small, but important, improvements. 

First, we fixed a memory problem that was occurring only on HTC Thunderbolt phones. It turned out to be due to a different default buffer size from what we've seen on some other phones. Supporting all of the 300+ Android phones on the market is one of the pleasures of developing for Android. Makes iOS seem downright boring. ;) 

Second, we made some changes to the architecture and threading strategy that should result in general performance improvements, and more responsive UI. Hurray! 

Finally, we fixed some bugs that had popped up here and there. Thanks everyone for your help in identifying these. 

So please download the new version, enjoy it, and share it with your friends. 

Launch: New Web Interface for Socialcam

Behold! We've just launched a new Web interface for all your Socialcam activity. Check out the coverage over at TechCrunch

Until now, Socialcam has been a very mobile-centric experience. Now you can view all those wonderful videos that you and your friends share on your phones, on the Web too. And all of that activity is synched between the Web and Mobile platforms. Comment or "like" a video ont he Web, and it now appears on the mobile version, and vice versa. 

New Web features include: 

 Online Profile

  • Your videos archive
  • List of videos you’re tagged in
  • List of your followers
  • List of the people you're following

Online Video Feed

  • Feed includes all of your videos and the videos of the people you're following

Video Page

  • Comment, like, embed videos from website
  • See who is tagged in a video from the website
  • Click through to friends (and friends of friends) profiles

Check out the mockup below which shows the same video on the Web and on the phone. You can see how all the activity is psynched between the two. Now go give it a try! 

 

On Making Socialcam's User Interface (Or, The #%$&ing Red Line)

We started working on Socialcam as we now know it about three months ago. We planned on launching Socialcam 1.0 at SXSW, giving us two months to complete everything. A tight deadline, to say the least. However, the Socialcam team is composed of incredibly smart people who are able to work very hard. 

In the end, we met our deadline. We had our ups and downs, moments of doubt and more of triumph — and every other emotion in between. In the end the launch went off as it should, that is, without a hitch. Since then, over 250,000 people have downloaded Socialcam.

One of the things that kept coming up throughout building Socialcam’s UI is that what will wind up as a tiny detail to the end user, can easily turn into an engineering challenge. In the case of Socialcam, one of those tiny details is this small red line at the bottom of every navigation element.

That little red line has a nice flair to it. There is no doubt that Socialcam looks much better with the red line in place than without. So we needed to keep it. But making that damned red line appear when it should, and disappear when it shouldn't be there, is a deceptively complicated task.

Why? There is no way to use a custom navigation bar with the navigation controller provided by Apple in their code; custom navigation bars can only be set with Interface Builder[1]. And Socialcam's user interface is laid out in code, rather than using Interface Builder.

Solution 1: Add a View to the Main Window

When an iOS app is opened, a main window is created and visible in -application:didFinishLaunchingWithOptions:. 

Normally, this window only has one view in it: the root view controller that is responsible for displaying every other view. In the typical case, - application:didFinishLaunchingWithOptions: will look something like:

- (BOOL) application:(UIApplication *) application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions {
        // possibly do some initialization and ensure that
        // the main view was created somewhere

        [_window addSubview:_navigationController.view];
        [_window makeKeyAndVisible];

        // the rest of the app launch process
}

However, there is nothing that prevents a second, third or nth view to the main window. So, lets add another view to the main window, and turn the previous code snippet turns into something along the lines of the following:

- (BOOL) application:(UIApplication *) application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions {
        // possibly do some initialization and ensure that
        // the main view was created somewhere

        CGFloat yOrigin = [UIApplication sharedApplication].statusBarFrame.size.height + _tabBarController.selectedViewController.navigationBar.frame.size.height);
        _redLineView = [[UIView alloc] initWithFrame:CGRectMake(0, yOrigin, 320., 3.)];
        _redLineView.backgroundColor = [UIColor colorWithRed:(0xED / 255.) green:(0x27 / 255.) blue:0. alpha:1.];

        [_window addSubview: _navigationController.view];
        [_window addSubview:_redLineView];
        [_window makeKeyAndVisible];

        // the rest of the app launch process
}

This method of adding a red line will get something on screen. Very quickly. It's a great and quick hack to prototype an idea out and know if it works well in practice, rather than on a Photoshop mockup.

And yet, this solution sucks. For the sake of brevity, here's a limited list of reasons as to why[2]:

  1. Adding a red line directly to the window is poor design; it breaks the Model-View-Controller paradigm by having a view is owned by the app delegate, rather than a view controller.
  2. Due to an implementation detail of UIView, UIViewController and UIWindow, only the first view's controller added to the screen will receive device rotation notices.
  3. You have to play cat and mouse with Apple for animation timings and curves if you need to push a view on screen that doesn't require a red line or pop the red line back on afterwards.
  4. If you present a view controller modally, the view will slide in beneath the red line, rather than sliding up with it. This looks very wrong. 
  5. Some views within Socialcam have a secondary navigation element. In that case, the red line should be below the secondary element, rather than below the navigation bar. A second red line is needed somewhere in order to show the red line without any weird animations. This brings us back to problem 4, playing cat and mouse with Apple over timings in order to know how to show/hide the red line. Additionally, it leads to modifying viewWillAppear: and viewWillDisappear: for every view that can possibly be before or after a view that didn't need a red line underneath the primary navigation element; lots of code duplication and calls to the app delegate to modify a view's state.

Solution 2: Make Our Own View Hierarchy

Apple's recommended way of laying out a view in code is to override - loadView and set a UIViewController's view property. This view should be a UIView (or subclass) that has all your views added to it as subviews. We can take advantage of this and make a superclass that sets our view to be one that contains the red line and than in our view controller subclasses.

This sounds good, right? This solution would fix all of the problems with Solution 1. Unfortunately, the red line isn't this simple. Which brings us to…

Why this solution actually sucks:

  1. Prevents the use of Interface Builder to create views. While Socialcam doesn't currently use Interface Builder to design any of its views, it would be bad to limit future options.
  2. Prevents the use of any built-in controllers provided by UIKit, such as UITableViewController.
  3. This blatantly ignores how - loadView is designed to work; in - loadView, you set the view to be displayed, not get the view and than set it based on what the view contains.
  4. The red line isn't part of the navigation element; it is either drawn directly below the navigation bar, or outside the bounds of the view on screen.
  5. Because the red line is part of the superclass, either every subclass will have to account for it when laying views out or the superclass will have to do some trickery of its own in order to avoid having a view get covered up by a few pixels.

Solution 3: Insert the Red Line into the Existing View Hierarchy

Make a set of subclasses for common view controllers such as UIViewController and UITableViewController that override methods such as - init, and - viewWillAppear: or - viewDidLoad to add a red line to the view's hierarchy as needed.

Again, this sounds like a good idea. In addition to fixing all the problems in Solution 1, by using this solution, we can fix problems 1 and 3 from Solution 2.

However, this solution sucks as well:

  1. Problems 2, 4 and 5 from Solution 2 still exist.
  2. This leads to a lot of boilerplate code to do the same thing across several classes[3].
  3. We would have to remember to call - viewWillAppear: at the end of the first subclass of one of our subclasses. This is an implementation detail that could easily be forgotten and lead to a messed up UI and an afternoon lost in debugging.

Solution 4: Archive a Navigation Controller Using our Navigation Bar Subclass to Disk and Read it Back at Runtime

A xib generated by Interface Builder is an xml representation of how a view is supposed to look. However, a view can be represented in other formats, such as in a binary plist that is archived to disk using NSKeyedArchiver's + archiveRootObject:toFile:[4]. Combine this with a tool such as `xxd` to get a hex representation of the file, we can put our archived navigation controller into a static C struct and unarchive it at runtime with NSKeyedUnarchiver's + unarchiveObjectWithData:length: method in an category added to UINavigationController[5] return a UINavigationController created with the unarchived data. Sounds complicated, right? It turns out that the code is more straightforward than the description of what the code is doing. You can take a look at it over on GitHub.

This solution is actually pretty great. It fixes all of the problems we encounter with solutions 1, 2 and 3. Which is to say, all known problems. In many ways, it is the ideal solution… except that its not very intuitive and should be very well documented for any future maintainer - including ourselves.

So, Which Solution does Socialcam use?

For better or worse, Socialcam 1.0 shipped with solution 1, albeit with several more hacks that were added in the days before release to work around problems discussed above (and many others). After spending the post-launch weekend catching up on sleep, the first thing I did after getting in on Monday was to try and figure out how to fix the red line. That morning led to the following three ideas. And the afternoon led to the previously linked github projects and their integration into Socialcam.

----------

*1. Radar #9299840 was filed with Apple about this.

*2. If you ever ask me about the making of the red line in person, I have many more things that I can to add to the list of problems. For the sake of brevity, the list is limited to five items.

*3. While you can avoid most of the boilerplate code by using the ObjC runtime directly, you lose out on compile-time type checks and wind up with code that is much harder to maintain in the future. Don't do that.

*4. If you're not familiar with NSKeyedArchiver and NSKeyedUnarchiver, a high-level way of thinking about them is is that that are a way to save information about a class to disk in an architecture-independent format and read it back again. See the docs.

*5. Typically, this might have been done in a UINavigationController subclass, however Apple strongly recommends not subclassing UINavigationController directly and it isn't good practice to override methods in categories. Putting it in a separate category method is a safe way to avoid both of these problems."

- Zach Drayer