Skip to content

Instantly share code, notes, and snippets.

@judsonmitchell
Last active December 22, 2022 16:39
Show Gist options
  • Save judsonmitchell/b8d319b37a2cbae1183b to your computer and use it in GitHub Desktop.
Save judsonmitchell/b8d319b37a2cbae1183b to your computer and use it in GitHub Desktop.
A quick guide to developing Android and iOS apps using only a Chromebook.

How I Develop iOS and Android Apps Using a Chromebook.

(Current as of July, 2014)

I'm a Chromebook fanboy, I admit it. I had one of the first CR-48s and am now happily possessed of an Acer C720. I use it for everything, from writing legal briefs to developing apps, and I am thoroughly satisfied with it.

Mobile App development on a CB poses some special issues, however. Most developers have dedicated OS-specific machines to develop mobile apps (on iOS this is almost a requirement), but I simply refuse to buy an Apple computer just to create a mobile app. After much trial and error, I have found it possible, even enjoyable, to create apps on my CB. Here's how I do it.

1. Preparing the Chromebook

Before you do anything, you must first put your Chromebook into developer mode. There are various ways of doing this depending on your model, so just Google it. Once you've successfully done that, it's time to install Crouton on your machine. The wonderful piece of software allows you to have full stack Ubuntu on your machine and is what really makes this all possible. Once Crouton is installed, set up your development environment in your Ubuntu chroot and get started.

N.B. - This guide assumes you are going to be doing all of your coding inside the Crouton chroot. It's theoretically possible to avoid that altogether by using an online IDE like Cloud 9 or Nitrous.io. This is not my personal workflow, so I'll refrain from giving any advice on it.

2. Code Your App!

This guide assumes that your are creating your apps using html, javascript, css, a text editor, and PhoneGap. This is not a guide to using XCode on a Chromebook (impossible, by the way).

There are a great many frameworks out there that facilitate mobile app development such as App, Jquery Mobile, and my personal favorite Bootstrap. Choose one and start coding your app, remembering to take advantage of Chrome Developer Tools emulation so you can see how your app will look on a mobile device while you work.

3. PhoneGap Build

PhoneGap allows us to transform our html and js into native code which will run on mobile devices. You can download PhoneGap via node, but this still requires you to install an Android SDK and will lock you out of iOS completely. Luckily, we now have Adobe's PhoneGap Build which is an online build service which takes away all of the hassle around building native binaries. Build supports importing code directly from Github and is free for open source projects.

Here is a project starter for a Build project. There's nothing too complicated about it. The main thing to know is that you must have a valid config.xml file in your project root before you import to Build.

Once you have signed up for Build, create your first project and build it. You can test out your app on mobile devices by scanning your project's QR code and then downloading. Remember to enable debugging and hydration in your project while you're in the development stage (Hydration allows you to reload new code on your phone without have to re-download the binary file). Important: When you make changes to your config.xml file, disable hydration and then rebuild and re-download. If not, strange things happen which will completely annoy you. Also, disable debugging before submitting to any app stores.

4. Get Ready for App Stores

Once your app is ready, you will need Apple Developer and Google Play Developer accounts. In order to upload, you will have to deal with getting the appropriate keys and certificates. Usually, XCode or Eclipse will handle this for you, but on a CB, you'll have to do it yourself. Here's how.

Make sure you have OpenSSL installed on your Crouton instance (it should be). Assuming you already don't have a private key, execute:

openssl genrsa -out mykey.key 2048

Apple Specific

Now, create a certificate signing request:

openssl req -new -key mykey.key -out CertificateSigningRequest.certSigningRequest -subj "/emailAddress=email@address.com, CN=Your Name, C=US"

Upload the certSigningRequest to the Apple Developer site. Apple will then provide you a link to a .cer file. Download it. You now need to convert it to .pem:

openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM 

Then, create the p12 file:

openssl pkcs12 -export -inkey mykey.key -in developer_identity.pem -out iphone_dist.p12 

Now, set up your Devices, App id and Provisioning on the Apple Developer site. Upload the provisioning and .p12 files to Build and you will have a valid signing key for iOS.

Android Specific

Things are bit easier with Android (they usually are). You just need to generate a keystore and upload it to the Android Developer Console. To do this you will need the Java SDK. To check if it is already installed on your CB (it probably isn't):

which java

If nothing is returned, you will have to install Java. The easiest way to do this as of now is:

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer

Assuming all is well, you can now use keytool:

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

You can then upload the keystore to Build and you're ready to sign your Android app.

5. Generating Icons and Splash Screens

You're going to need some graphics. Pixlr is the best Chrome App I've found for creating and manipulating images on a Chromebook.

If you want to save yourself some hassle, use Pixlr to create an icon that is 2048 x 2048 square. If you do this, you can use this script to quickly generate icons and splash screens in all the correct sizes for all platforms. To do this, install imagemagick:

sudo apt-get install imagemagick

Then install the phonegap icon generator script:

git clone https://github.com/judsonmitchell/phonegap-icon-splash-generator.git

Now, put your icon file (png extension) in the the same directory as the bash script and:

bash phonegap-icon-splash-generator.sh YOUR_FILE.png "#FFFFFF"

The html color code argument is the color you want for the background of your splash screen. All the necessary files will be created in the new directory res/. Copy that directory to the root of your project. Now add the icon info to your config.xml:

<icon src="icon.png" />
<icon src="res/icon/icon.png" />
<icon src="res/icon/android/icon-36-ldpi.png"   gap:platform="android"    gap:density="ldpi" />
<icon src="res/icon/android/icon-48-mdpi.png"   gap:platform="android"    gap:density="mdpi" />
<icon src="res/icon/android/icon-72-hdpi.png"   gap:platform="android"    gap:density="hdpi" />
<icon src="res/icon/android/icon-96-xhdpi.png"  gap:platform="android"    gap:density="xhdpi" />
<icon src="res/icon/ios/icon-29.png"   gap:platform="ios"   width="29" height="29" />
<icon src="res/icon/ios/icon-40.png"   gap:platform="ios"   width="40" height="40" />
<icon src="res/icon/ios/icon-50.png"   gap:platform="ios"   width="50" height="50" />
<icon src="res/icon/ios/icon-57.png"   gap:platform="ios"   width="57" height="57" />
<icon src="res/icon/ios/icon-58.png"   gap:platform="ios"   width="58" height="58" />
<icon src="res/icon/ios/icon-72.png"   gap:platform="ios"   width="72" height="72" />
<icon src="res/icon/ios/icon-76.png"   gap:platform="ios"   width="76" height="76" />
<icon src="res/icon/ios/icon-80.png"   gap:platform="ios"   width="80" height="80" />
<icon src="res/icon/ios/icon-100.png"   gap:platform="ios"   width="100" height="100" />
<icon src="res/icon/ios/icon-114.png"   gap:platform="ios"   width="114" height="114" />
<icon src="res/icon/ios/icon-120.png"   gap:platform="ios"   width="120" height="120" />
<icon src="res/icon/ios/icon-144.png"   gap:platform="ios"   width="144" height="144" />
<icon src="res/icon/ios/icon-152.png"   gap:platform="ios"   width="152" height="152" />

<gap:splash src="res/screen/android/screen-ldpi-portrait.png"  gap:platform="android" gap:density="ldpi" />
<gap:splash src="res/screen/android/screen-mdpi-portrait.png"  gap:platform="android" gap:density="mdpi" />
<gap:splash src="res/screen/android/screen-hdpi-portrait.png"  gap:platform="android" gap:density="hdpi" />
<gap:splash src="res/screen/android/screen-xhdpi-portrait.png" gap:platform="android" gap:density="xhdpi" />
<gap:splash src="res/screen/blackberry/screen-225.png" gap:platform="blackberry" /> 
<gap:splash src="res/screen/ios/screen-iphone-portrait.png"    gap:platform="ios"     width="320" height="480" />
<gap:splash src="res/screen/ios/screen-iphone-portrait-2x.png" gap:platform="ios"     width="640" height="960" />
<gap:splash src="res/screen/ios/screen-iphone-landscape.png"    gap:platform="ios"     width="480" height="320" />
<gap:splash src="res/screen/ios/screen-iphone-landscape-2x.png"    gap:platform="ios"  width="960" height="640" />
<gap:splash src="res/screen/ios/screen-iphone5-portrait.png"    gap:platform="ios"     width="640" height="1136" />
<gap:splash src="res/screen/ios/screen-iphone5-landscape.png"    gap:platform="ios"     width="1136" height="640" />
<gap:splash src="res/screen/ios/screen-ipad-portrait.png"      gap:platform="ios"     width="768" height="1024" />
<gap:splash src="res/screen/ios/screen-ipad-landscape.png"     gap:platform="ios"     width="1024" height="768" />
<gap:splash src="res/screen/ios/screen-ipad-portrait-2x.png"      gap:platform="ios"     width="1536" height="2008" />
<gap:splash src="res/screen/ios/screen-ipad-landscape-2x.png"      gap:platform="ios"     width="2008" height="1536" />

Upload the new files to Github and then do a rebuild on Build.

6. Taking Screenshots

Taking screenshots is a pain. I've not found a good way to automate this as of now, so here's what I do. Open your app in Chrome with Developer Tools set to emulate the specific device. (Apple, for example, will require a screenshot of iPhone 3.5, iPhone5, and an iPad; these screenshots must meet the required size down to the precise pixel). On your CB, use control-shift-F5 (F5 is the "Switch Window" key). Select the app area using the pointer and the control key. This will create a screenshot which can then be uploaded to Pixlr to be resized to the required size.

7. Ready to Upload

Make sure that you have removed hydration and debugging from your app. Rebuild the app, making sure that you are using the correct signing key. On Android, this can just be the key your created earlier. In iOS, it must be a key created with a distribution provisioning profile.

iOS

You will need an iTunes Connect account to upload your app. Go to Manage Your Apps in Connect and then "Add New Apps". Most of the steps here are self-explanatory: name your app, upload screenshots, etc. Apparently, Apple used to let you upload your binary file directly on iTunes Connect, but this is - for whatever reason - no longer allowed. So, here is the one step where you need a computer other than your Chrombook. Either find a friend's Mac or use a virtual Mac service like MacInCloud. Make sure the Application Loader is installed on the Mac (it is by default on MacInCloud). Use the Application Loader to upload your .ipa file to iTunes Connect. Assuming you don't get any errors, your app will then be in "Waiting for Review" status. As of this writing, waiting to get your app reviewed takes weeks - with an s.

Android

Uploading to Google Play is pretty straightforward. Go to the Developer Console on Google Play. Create the new app record by putting in your app information, screenshots, etc. and then upload your .apk. Your app will be in the Google Play Store within a couple of hours.

Examples

If you would like to see some examples of apps built using this method, have a look at some of my repos:

LaCrimBook

LEA

Screenshots below:

@tonejac
Copy link

tonejac commented Nov 3, 2018

How do you handle when you need to deploy a dev version of your compiled iOS app to an iOS device? What is your workflow in that scenario?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment