Update 6/13/2014: Fixed instructions to support XCode 5.1.1
Update 11/4/2015: Fixed filename of the entitlements file (use hyphens, not underscores)
We use PhoneGap Build to compile a number of iOS apps. It saves us the complexity of setting up and maintaining XCODE/PhoneGap build environments. We simply upload our web code and corresponding configuration files and get back an .ipa file ready for distribution.
One of our clients uses the app we build for in-house enterprise deployment. They need a copy of the .ipa file signed with their Enterprise certificate and their provisioning profile. They said “please just provide us an .xcarchive file so we can open it in the XCODE Organizer and distribute it.” But all we get from PhoneGap Build is an .ipa file. So what do we do?
Edit 2/27/2014 — There’s a new 3rd Party Plugin on PhoneGap Build that is probably a much better way to do this. I haven’t personally tried it yet, but check out the Customer URL Scheme plugin: https://build.phonegap.com/plugins/433
I love PhoneGap Build. It makes the whole process of building a hybrid app easy. No messing around with build servers for each type of device, no installing of patches when PhoneGap versions come out, and they have an API for automating builds. But the hidden cost is the inability to modify the native code when you want to. You are stuck with the options Build offers you. One of these limitations is in URL schemes.
iOS has always supported URL Schemes. This allows your app to respond to a URL. You’ve probably noticed that any url that starts with “mailto://” opens the Mail app and “maps://” opens the Maps app. You can register your own scheme so that “myapp://” opens your app and you can see any information passed in that URL. It’s a great way to make web pages link to your app and to have two apps talk to each other.
But while recent versions of PhoneGap have some built-in support for URL schemes, setting it up requires registering the scheme in your info.plist file. It’s a straightforward entry where you set CFBundleURLName and CFBundleURLSchemes (nice tutorial for iOS devs here). But since PhoneGap Build does not let you alter the info.plist file and the config.xml file does not support setting these values, you’re out of luck. There are requests to get this support added, but Adobe has not added it yet.
Never fear – I found a great workaround. Yes, it’s something of a hack, but it works. The secret is to use the officially supported FacebookConnect plugin. This plug in is meant to give access to Facebook for Single Sign On. We don’t need that functionality, but when the plugin is included in your project, it does setup the info.plist with a URL scheme.
When playing video on an iPad or iPhone, you never know how good a connection you will have. Are they on WiFi? 3G? Worse? And the quality of the connection could change in the middle. How do you play video on a mobile website and have it automatically adjust the quality in response to the connection? The answer is “HTTP Live Streaming”.
In HTTP Live Streaming, which unfortunately is only supported for Mobile and Desktop Safari (and native apps, I believe, but I’m focused on web right now), the video is broken into 10 seconds chunks that are then played like a playlist. You can have multiple sets of these chunks at different qualities, and the browser automatically adjusts to pull the highest quality stream it currently can afford. It’s pretty slick.
(image from Apple documentation)
There is a lot of good documentation out there, especially from Apple about how this works. Check out https://developer.apple.com/resources/http-streaming/ I won’t attempt to recreate all of that, but I did have a few hiccups and workarounds when I did it, so I wanted to document my steps.
As cool as the new HTML5 Video and Audio tags are for avoiding the need for plug-ins, in iOS (mobile Safari), it still has some problems. Miller H. Borges Medeiros has a good blog post covering the issues. Here are topics he discusses in more detail:
- Can’t screenshot a video frame
- Can’t play sound and video together
- Can’t play multiple sounds or videos at the same time
- Can’t play video inline on iPhone
- Can’t play sound or video without user interaction
- Multiple HTML5 video elements on the same page cause bugs
- Can’t play HTML5 video backwards (OK, I’m not sure why I’d do that anyway)
I recently was using JWPlayer which provides a nice one-stop Flash with HTML5 fallback (or vice-versa). But it has the same limitations on iOS. No real workarounds—just know the limitations and design around them.
Designer Michael Critz did a nice page showing all the fonts supported by Mobile Safari. Since the @font-face tag only supports SVG fonts (with some limitations as documented here, it’s best to use these whenever possible:
Also, Yummygum just posted hundreds of free icons for iPad:
I had a web app that I wanted to shift a toolbar’s location to bottom in portrait mode and to the right in landscape mode. I got this working fine in Mobile Safari, but then ran into some issues when I moved it into PhoneGap. Here is how I got it working.
I tried all sorts of things to get Tivo content to my iPhone. Tivo has a paid version of its own software, and I tried things using trial versions of other paid software like VideoRedo, but it always seemed either expensive or convoluted. Google searches kept steering me to these same approaches.
But today I found an open source Java-based program that does it all. It’s called kmttg – I have no idea what it stands for. You download it from http://code.google.com/p/kmttg/ and follow the installation instructions. Then you run it.
The interface isn’t fancy, but it gets the job done. You enter your media access key for your Tivo and then you can browse the Tivo. Once you find a movie you just need to select the boxes for “decrypt” and “encode” and select the encoding profile (there’s one for iPhone, iPad, Droid, etc.). It does its thing, and at the end you have an mp4 ready to open in iTunes and sync.
It even allows you to set up AutoTransfers so your favorite shows are ready to go.
I haven’t tried all its advanced features, but for getting my favorite shows where I can watch them on a plane, I’m hooked!