Archive

Archive for the ‘Software Engineering’ Category

Emoji Gem 1.0 Release

02/12/2014 Comments off

Emoji Gem:

Earlier this week, we are proud to release the complete 1.0 version of the emoji gem on RubyGem.org for public use.

What is Emoji?

Emoji are cartoonish icon characters, distributed as a UTF-8 font, like this heart: ❤. Using emoji began in Japan with mobile phones, but has grown in popularity throughout the internet over the last 3-4 years. Unfortunately, emoji character support is incomplete in many cases (like the Chrome browser). Users of Polar Polls easily add emoji on their iPhones and we wanted to support them. However, we needed a way to support emoji on unsupported web platforms.

Enter the emoji gem. The emoji gem bundles a comprehensive emoji index and a complete emoji image library from Phantom Open Emoji. This gem provides a fast and simple Ruby translation between UTF-8, moji characters, and image representations. Additionally, this gem implements a Rails engine that serves up the Emoji image library when replacing characters with images. This gem works in all Ruby interpreters, but will load a native-optimized string engine if it’s available (everywhere but JRuby).

Backstory

This project began after-hours at the Burlington Ruby Conference in August of 2013. I was having dinner with Steve Klabnik and a handful of other developers at Farmhouse, when Steve mentioned his plans for building an emoji gem. We had struggled with web support for emoji at Polar Polls after enabling emoji support in our iOS app. I exchanged information with Steve and hoped to work together on building a solution.

After the conference, I worked for several weeks putting the first working version together. Steve and I roughed out an outline for the architecture and tools. Shortly after, we opened up the gem to review/contribution from other folks. We were lucky to get several pull requests and I polished a version that Polar Polls could use in production. Over the last 6 months, we’ve collected a handful of fixes and performance tuning to prepare for our 1.0 release.

Thank You!

I’ve been a huge beneficiary of open source software and the community supporting Ruby/Rails. I’m glad to have a chance to build something useful and give back to the community. None of this would have been possible without the following folks:

  • @steveklabnik – for the idea, securing rights to “emoji” gem name, guidance, and publicity for the project
  • @ryan-orr – for transferring the emoji gem account for our new project
  • @mikowitz – for contributing code and adding Ruby String extensions.
  • @semanticart – for contributing code and expanding Ruby version support.
  • @parndt – for improving our docs and README.

Cookies in Hybrid Android Apps

01/17/2013 9 comments

Sharing Cookies between WebViews and native code

Hybrid mobile applications require a close collaboration between native code and WebViews. Unlike iOS, Android doesn’t provide any implicit bridge between HTTP cookies in WebViews and native HTTP requests made through HttpConnection or Apache’s HttpClient interfaces. As a developer, it’s up to you to manually synchronize these systems if you want to share state or authentication context between them.

This is often a useful feature for integrating third party web services via their login page in your app’s WebView. Authentication credentials stored as HTTP cookies should be shared for subsequent HTTP calls, whether they’re native or a WebView.

Android Cookie Management and Persistence

Add CookieManager and CookieSyncManager hooks to properly setup your application to accept and save cookies, while writing them to disk periodically or when the application pauses or shuts down.

Application

public class YourApplication extends Application {
  public void onCreate() {
    super.onCreate();

    //Setup Cookie Manager and Persistence to disk
    CookieSyncManager.createInstance(this);
    CookieManager.getInstance().setAcceptCookie(true);
  }
}

Main Activity

public class MainActivity extends BaseActivity {
  public void onResume() {
    CookieSyncManager.getInstance().stopSync();
  }

   public void onPause() {
     CookieSyncManager.getInstance().sync();
   }
}

Synchronizing Android CookieManager to Apache HttpClient

Now that cookies have an application wide cookie store that will save WebView cookies and persist the cookie store to disk, we need to sync cookies from this store for use by native code.

Synchronize native HttpClient with App’s Cookie Store
This example shows populating an Apache CookieStore configured in an HttpClient that is pre-populated with any HTTP Cookies that apply to this URL. Then, after executing the request, writing all of the cookies saves in the CookieStore into the App’s Android CookieManager.

public static String getURLContentsAsString(String url) {

  DefaultHttpClient httpClient =  new DefaultHttpClient();

  //Injects App's CookieManager cookies for this URL into HttpClient CookieStore
  syncCookiesFromAppCookieManager(url, httpClient);

  HttpGet hp = new HttpGet(url);
  HttpResponse response = hc.execute(hp);

  //Save's cookies from HttpClient in App's CookieStore
  syncCookiesToAppCookieManager(url, httpClient);

  // Process Response here
  //...
}

syncCookiesFromAppCookieManager()
This helper function fetches all cookies for this URL from the Android CookieManager, which gives us a raw Cookie HTTP header value. The Apache CookieStore expects Cookie objects, which we will generate using the RFC2109Spec that matches the format of the Android CookieManager.

public static void syncCookiesFromAppCookieManager(String url, DefaultHttpClient httpClient) {

  BasicCookieStore cookieStore = new BasicCookieStore();
  httpClient.setCookieStore(cookieStore);

  CookieManager cookieManager = CookieManager.getInstance();
  if (cookieManager == null) return;

  RFC2109Spec cookieSpec = new RFC2109Spec();
  String rawCookieHeader = null;
  try {
    URL parsedURL = new URL(url);

    //Extract Set-Cookie header value from Android app CookieManager for this URL
    rawCookieHeader = cookieManager.getCookie(parsedURL.getHost());
    if (rawCookieHeader == null) return;

    //Convert Set-Cookie header value into Cookies w/in HttpClient CookieManager
    int port = parsedURL.getPort() == -1 ?
      parsedURL.getDefaultPort() : parsedURL.getPort();

    CookieOrigin cookieOrigin = new CookieOrigin( parsedURL.getHost(),
                                                  port,
                                                  "/",
                                                  false);
    List<Cookie> appCookies = cookieSpec.parse(
      new BasicHeader("set-cookie", rawCookieHeader),
      cookieOrigin);

    cookieStore.addCookies(appCookies.toArray(new Cookie[appCookies.size()]));
  } catch (MalformedURLException e) {
    // Handle Error
  } catch (MalformedCookieException e) {
    // Handle Error
  }
}

syncCookiesToAppCookieManager()
This helper extracts Cookie objects from the Apache CookieStore and converts them into Set-Cookie header strings for the Android CookieManager.

public static void syncCookiesToAppCookieManager(String url, DefaultHttpClient httpClient) {

  CookieStore clientCookieStore = httpClient.getCookieStore();
  List<Cookie> cookies  = clientCookieStore.getCookies();
  if (cookies.size() < 1) return;

  CookieSyncManager syncManager = CookieSyncManager.getInstance();
  CookieManager appCookieManager = CookieManager.getInstance();
  if (appCookieManager == null) return;

  //Extract any stored cookies for HttpClient CookieStore
  // Store this cookie header in Android app CookieManager
  for (Cookie cookie:cookies) {
    //HACK: Work around weird version-only cookies from cookie formatter.
    if (cookie.getName() == "$Version") break;

    String setCookieHeader = cookie.getName()+"="+cookie.getValue()+
      "; Domain="+cookie.getDomain();
    appCookieManager.setCookie(url, setCookieHeader);
  }

  //Sync CookieManager to disk if we added any cookies
  syncManager.sync();
}

A Year of WOW (20% time) at PatientsLikeMe

01/27/2012 1 comment

What is WOW Week?

PatientsLikeMe has built our own version of Google’s “20% Time” that we call “WOW Week”. WOW Week is a week of unstructured development time for engineers, where they can work on anything they choose to improve our products. This lets people focus on their personal passions or explore riskier ideas. See my more detailed post about what WOW Week is and how it works for PatientsLikeMe.

2011 WOW Week Projects in Review

It’s easy to pay lip-service to the idea of 20% time, but PatientsLikeMe actually dedicates entire weeks at a time. This post showcases what a year of WOW produced in 2011. Each of these projects was initiated by an engineer in their own time and most made it into production.

Clinical Trials (In Production)

Credit: James Kebinger and Jeff Dwyer

Provide a friendly search interface to National Clinical Trial registry and automatically match patients within PatientsLikeMe to relavant trials they qualify for.

Clinical Trials

Read more…

WOW Week at PatientsLikeMe

01/20/2012 2 comments

What is WOW Week?

PatientsLikeMe has built our own version of Google’s “20% Time” that we call “WOW Week”. WOW Week is a week of unstructured development time for engineers, where they can work on anything to improve our products as long as they demo their progress in front of the company at the end of the week.

The engineering team works in 2-week long development sprints. After three development sprints in a row, we have a “Technical Debt” week and a WOW Week.

Why a Week at a time versus 20% Time?

It’s easy to pay lip-service to the concept of 20% time for engineers while scheduling a full load of work. I’ve seen this happen many times at other companies. PatientsLikeMe avoids this pitfall by creating a public block of time for the entire company. See the 2011 WOW showcase to see how much we build.

Scheduling a complete week allows a single context-switch into innovation mode for everyone. This maximizes the value of this time, instead of dividing it into smaller chunks that are diluted by context switching and deadlines.

Read more…

What Makes a Great Startup Engineer?

03/20/2011 1 comment

(The following is an answer to this question on Quora)

What Makes a Great Startup Engineer?
Working in a startup is both difficult and awesome for the same reasons: very little process/politics, but always more work than anyone has time to do.

  1. Organized & Driven – aka they can Get Shit Done
  2. Smart
  3. Energetic/Passionate
  4. Quick Learner
  5. Not an Asshole, you should enjoy spending time with them

Read more…