#within40feet

#within40feet

Yay!! @nest

Yay!! @nest

Our big helper today. How does she get her feet under the pillow? #puppy

Our big helper today. How does she get her feet under the pillow? #puppy

12 tons of rock. This is our weekend project.

12 tons of rock. This is our weekend project.

Phonegap sucks.

Like every development shop, we get a lot of people coming to us wanting to create an app for both iOS and Android. They want to figure out a way to save time and money by not completely duplicating work on their app for each OS. So naturally we’ll talk with these potential clients about architecture options using HTML content and web views. (Our most recent client wanted to share functionality between an iOS app and a website as well, so we were especially directed toward using HTML in the mobile app.) Along this path, the thought of using Phonegap always comes up. We’ve been down this road a few times, and here are our conclusions.

Phonegap sucks. Here’s why:

  • Learning a whole new framework when you should be learning Obj-C or Java.

  • Depending on them to support OS features (cross your fingers it exists and works! cross your fingers they support new stuff quickly!)

  • Mess of an organization — Phonegap? Cordova? Which is it?!?!?! (Just use Phonegap and you’ll be fine — Okay… oh wait, I have to use the cordova CLIto add plugins?!)

  • Outdated, incorrect, and confusing documentation (partly due to the above point)

  • The community around it is more concerned with supporting every device on the planet instead of helping a developer take some HTML content and publishing it effortlessly in one of the main 2 OSes. (Well that’s what Phonegap Cloud is for — tried to use it 3 times, it’s broken.)

In short, Phonegap is focused on making you 10% satisfied on 100% of the devices in the world. In our experience, clients care about being 100% satisfied on only 2 of the devices in the world — iOS and Android.

So what’s our solution? Embrace Obj-C and Java! HTML content in an app is a great way for simple apps to have a single code base on multiple platforms, but you need fine grain control over the entire app and you need to follow Apple and Google’s instructions on how to take advantage of their OS features. So we have frameworks (iOS nearly ready for open sourcing & Android still in early works) that contain one web view and then use small, open source libraries to create a bridge between that web view and the native application. This allows us to write our own Javascript API to call whatever native code we write. (For iOS, we use the awesome WebViewJavascriptBridge by Marcus Westin)

For example, when we have HTML content that wants to share a link to Facebook or Twitter, we wrote our own Javascript API to say:

bridge.callHandler(‘facebookShare’, ‘http://ducksarethebest.com’); and then in Objective-C, we wrote the handler to take that URL and use the official Facebook iOS SDK to share that link:

[_bridge registerHandler:@”facebook_share” handler:^(id data, WVJBResponseCallback responseCallback) { FBAppCall *appCall = [FBDialogs presentShareDialogWithLink:[NSURL URLWithString:data] handler:fbHandler]; }];

This is a dramatically better experience than letting the web view share that link because if the user already has the Facebook app and is signed into it, the Facebook SDK won’t require them to log in again, whereas the web view sharing method will.

It’s even better for solutions where there isn’t a web alternative, like in-app purchases. And especially something so vital to the success of your app — users paying you money — you want to make sure it’s done correctly in the most up-to-date and recommended way. The only way to do that is to follow Apple or Google’s guidelines in their official SDK.

This approach gives us the flexibility to write whatever JS API works best for us, the immediacy of taking advantage of any feature available in the iOS or Android SDKs, and it improves our development skills in a language and SDK that actually matter to our long term careers. Most importantly, the client is happy that we’re in full control of the app, we’re not relying on some 3rd party group to support features that Apple or Google released months ago, and the app can be as truly native or web-based as it takes to create the best user experience.

iOS Certificates & Provisioning Profiles

For a new iOS developer, they can be really confusing. You have an app that you simply want other people to be able to test on their device, and you get directed to the Apple developer portal with certificates, devices, and provisioning profiles. Before your body goes into shock, read the rest of this post for a simple explanation of it all.

The combination of certificates, devices, and provisioning profiles is Apple’s answer to some difficult questions:

Q: How do you guarantee the app you’re downloading hasn’t been modified by some hacker and it’s actually from the developer/company that it says it’s from?

A: Certificates. Ever learned about PGP encrypted email? That whole business where there’s a public key and a private key? That’s what’s going on here, except you’re abstracted from having to worry about that because of the Mac app “Keychain Access”. When you add a new certificate in the portal and follow the instructions to use “Keychain Access” to upload a certificate request, “Keychain Access” uses your private key to create a public key, which is then embedded into the certificate request that gets sent to Apple. Apple hands you back a certificate that you then put into your keychain (now you can download and add it through Xcode automatically).

(Update: it looks like you can have Xcode manage your certificates/”Signing identities” in preferences as well.)

Note that there are different certificates for different scenarios too. Developer certificates are used when you’re just getting any old app (app id: *) to work and you’re developing locally and on your development device that’s tethered to your computer. An AdHoc certificate is used when you want to allow a few testers to install your app on their device before the public AppStore release. AppStore and AdHoc certificates are tied to a specific app (app id), and they usually use an organization’s certificate, since the certificate is how Apple knows what to show on the “Developed By” line in the App Store listing.

Q: How can we allow a handful of testers to install the app on their phone and try it out before we release it to the whole world through the App Store?

A: Devices & Provisioning Profiles. Apple only allows its users to install apps through the App Store. But when you’re a developer and you want some people to try it out before it goes to the App Store, you need to use provisioning profiles and devices.

First, you get someone to give you their device UUID (universally unique identifier), which usually is done through a service like Testflight or HockeyApp where a person can sign up to be one of your testers and the service will automatically email you their UUID. In order to prevent you from circumventing the App Store, Apple restricts you to only adding 100 devices in a year to your iOS developer account.

Then you create a provisioning profile. Each provisioning profile incorporates a certificate in order to sign the app securely from a specific person/organization. Provisioning profiles also declare who is able to install the build of the app. In the case of an App Store provisioning profile, it’s saying that that build of the app can be installed by anyone as long as it’s downloaded through the App Store.

When you’re getting some testers on board, you’ll want to use an Ad Hoc provisioning profile (and certificate). In the “Edit” screen of the provisioning profile, you’ll be able to select any of the devices listed in “Devices” in your developer portal. Check the box next to the ones you want to include (Note: you can always check or uncheck more or less later).

Generate this profile, download it manually or through the Xcode preferences, select it when archiving your app, and then you’ll be able to upload that .ipa file to a service like Testflight for your testers to install.

Some more guiding images:

  • Having Xcode automatically download provisioning profiles and certificates for you:

  • Updating certificate (“Signing identity”) selected in the project’s build settings in Xcode:

Just woke up from a nap look. #puppy

Just woke up from a nap look. #puppy

Snuggling puppy.

Snuggling puppy.

Work swag. @dojo4

Work swag. @dojo4

This has been my life for the past 5 weeks. Sophie - our black lab puppy.