Generating Signing Keys for Apple iPhone Phone Gap Builds

When you are building applications that should work across multiple platforms using Phone Gap, you will need to generate a set of signing Keys to work with the different platforms:
Keys

Generating a Key for Apple iOS from MacOS

To manually generate a Certificate, you need a Certificate Signing Request (CSR) file from your Mac. To create a CSR file, follow the instructions below to create one using Keychain Access.

Create a CSR file.

In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.

Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.

  • In the Certificate Information window, enter the following information:
    • In the User Email Address field, enter your email address.
    • In the Common Name field, create a name for your private key (e.g., John Doe Dev Key).
    • The CA Email Address field should be left empty.
    • In the “Request is” group, select the “Saved to disk” option.
  • Click Continue within Keychain Access to complete the CSR generating process.

Generating a Key for Apple iOS from Windows

I have a Windows computer and I found it very hard to generate a key. If you follow the steps below, you might find it easier:

  1. Install Visual C++ 2008 Redistributables
  2. Download Open SSL for Windows. http://slproweb.com/products/Win32OpenSSL.html and install it onto c:OpenSSL-Win32
  3. Make sure the bin folder is installed in c:OpenSSL-Win32bin
  4. Change your PATH variable to have this path:
    • Select Computer from the Start menu
    • Choose System Properties from the context menu
    • Click Advanced system settings > Advanced tab
    • Click on Environment Variables, under System Variables, find PATH, and click on it.
    • In the Edit windows, modify PATH by adding the location of the class to the value for PATH. If you do not have the item PATH, you may select to add a new variable and add PATH as the name and the location of the class as the value.
  5. The first thing you need to do is generate a private key. Go to the command line and navigate to whatever directory you want to store the generated files in. Then type in the following to generate the key:
    openssl genrsa -des3 -out ios.key 2048

    Keys2
    The result will be a new file called “ios.key” in this folder.

  6. Next you need to generate a Certificate Signing Request or CSR file. You can do this by running the following command, which uses the ios.key file generated earlier:
    openssl req -new -key ios.key -out ios.csr -subj "/emailAddress=contact@carra-lucia-ltd.co.uk, CN=CARRA-LUCIA-LTD, C=UK"

    Change the items in red to match your needs.
    Keys3

  7. Now you need to go to your Apple Developer iOS Provisioning Portal in order to generate an iOS Development Certificate, using the ios.csr file you’ve just generated. Click on “Certificates” in the left hand side, and then “Request”.
    iOSCertificatesAdd Ios Certificate

    You will be prompted to upload a .csr file, and then wait for the certificate to be issued, which it will quite quickly, refresh the browser if you need to.
    csr file

  8. Now download the development certificate that was issued and save it in the same directory where the other generated files are.
    app_distribution
  9. You now need to convert it to a PEM file which you can do with:
    openssl x509 -in ios_distribution.cer -inform DER -out ios_distribution.pem -outform PEM

    Where ios_development.cer is the name of the development certificate created on the Apple Provisioning Portal and ios_development.pem is the PEM file that we want to generate.

  10. Next file is the P12 file, which uses both our private key (ios.key) and the iOS distribution certificate (ios_distribution.pem):
    openssl pkcs12 -export -inkey ios.key -in ios_distribution.pem -out ios_distribution.p12

    You will be asked to enter the access phrase for the ios.key file (which you noted from earlier) and you will need to generate an export password for the P12 file and verify it. The ios_distribution.p12 file is then generated.
    keys4

  11. The last file you need to generate is the provisioning profile, which again requires you to return to the Apple Provisioning Portal.
    iOsProvisioning
  12. If you plan to use services such as Game Center, In-App Purchase, and Push Notifications, or want a Bundle ID unique to a single app, use an explicit App ID. If you want to create one provisioning profile for multiple apps or don’t need a specific Bundle ID, select a wildcard App ID. Wildcard App IDs use an asterisk (*) as the last digit in the Bundle ID field. Please note that iOS App IDs and Mac App IDs cannot be used interchangeably.
  13. Select the certificates you wish to include in this provisioning profile. To use this profile to install an app, the certificate the app was signed with must be included.
  14. Bear in mind that such certificates need to be tied to your iOS testing devices via their UDIDs, and again there is documentation on how to do this.
    provisioning profile
    Once the provisioning profile is generated, download it (e.g. iOS_Development.mobileprovision) and save it in the same place as the other files. This file will also need to be installed on each of your iOS testing devices.

You should now have everything that you need to generate an iOS signing key for PhoneGap Build:

  • P12 certificate file
  • provisioning profile
  • certificate password

These steps can also be used to generate a distribution key for the iTunes Store.

Advertisements

How to build your first PhoneGap application

I recently started looking into PhoneGap again (been a few months and the upgrade from 2.7 to 3.3 went smoothly).

PhoneGap is a distribution of Apache Cordova. You can think of Apache Cordova as the engine that powers PhoneGap, similar to how WebKit is the engine that powers Chrome or Safari. (Browser geeks, please allow me the affordance of this analogy and I’ll buy you a beer later.)

Over time, the PhoneGap distribution may contain additional tools that tie into other Adobe services, which would not be appropriate for an Apache project. For example, PhoneGap Build and Adobe Shadow together make a whole lot of strategic sense. PhoneGap will always remain free, open source software and will always be a free distribution of Apache Cordova.

Currently, the only difference is in the name of the download package and will remain so for some time.Cordova Logo

What is Apache Cordova to a PhoneGap developer? (i.e. someone who just wants to build apps)

As a developer building PhoneGap applications, nothing has changed. PhoneGap is still free, openly licensed, and the main focus of the PhoneGap team. If your goal is to build cross platform apps with HTML, JS and CSS then keep on using PhoneGap for everything you need. This isn’t to say the transition has been perfect. We messed up the last release by not correctly updating the documentation to reflect the name change which confused new users. Future releases will have checks in place to ensure our documentation has the correct references. If you happen to be reading this and nodding in frustration, I encourage you to use http://docs.phonegap.com as the canonical source for edge documentation. If you want to help us keep this stuff on point, please read on.

 

he Command-Line Interface

This guide shows you how to create applications and deploy them to various native mobile platforms using the phonegapcommand-line interface (CLI). This tool allows you to create new projects, build them on different platforms, either locally or on a remote server, and run them within an emulator or device. You can also use the CLI to initialize project code, after which you use various platforms’ SDKs to develop them further.

Prerequisites

Before building projects locally, you need to install SDKs for each platform you wish to target. (See the Platform Guides for details on how to install each.) Otherwise, you can use the cloud-based PhoneGap Build service to compile apps for the following platforms remotely:

  • Android
  • iOS
  • BlackBerry 6
  • Windows Phone 7
  • WebOS
  • Symbian

Unlike PhoneGap Build, local builds support BlackBerry 10. The WebOS and Symbian platforms are only available when building remotely. The following platforms are only available when building locally:

  • Windows Phone 8
  • Windows 8

See Platform Support for an overview of all available options. See below for details on how to use PhoneGap Build to build remotely.

If building locally, you need to run the command-line interface from the same machine that supports the platform’s SDK. The CLI supports the following combinations:

  • iOS (Mac)
  • Android (Mac, Linux)
  • BlackBerry 10 (Mac, Linux, Windows)
  • Windows Phone 7 (Windows)
  • Windows Phone 8 (Windows)

On the Mac, the command-line is available via the Terminal application. On the PC, it’s available as Command Prompt underAccessories.

The more likely it is that you run the CLI from different machines, the more it makes sense to maintain a remote source code repository, whose assets you pull down to local working directories.

To install the phonegap command-line tool, follow these steps:

  1. Download and install Node.js. Following installation, you should be able to invoke node or npm on your command line.
  2. Install the phonegap utility. In Unix, prefixing the additional sudo command may be necessary to install development utilities in otherwise restricted directories:
    $ sudo npm install -g phonegap
    

    The installation log may produce errors for any uninstalled platform SDKs. Following installation, you should be able to run phonegap on the command line.

Create the App

Go to the directory where you maintain your source code, and run a command such as the following:

    $ phonegap create hello com.example.hello HelloWorld

The first argument specifies a hello directory to be generated for your project. Its www subdirectory houses your application’s home page, along with various resources under cssjs, and img, which follow common web development file-naming conventions. The config.xml file contains important metadata needed to generate and distribute the application.

The other two arguments are optional: the com.example.hello argument provides your project with a reverse domain-style identifier, and the HelloWorld provides the application’s display text. The -i and -n command-line options and their corresponding flags make these explicit:

    $ phonegap create hello -n HelloWorld -i com.example.hello
    $ phonegap create hello --name HelloWorld --id com.example.hello

Alterately, you can edit both of these optional values in the config.xml file later during development.

 WHAT I GOT

I went through all the steps and I got a few errors:

apache_errors
Obviously – this comes from disregard of the prerequisites: iOS native environment requires Mac OSX.
Second, I did not install any Java tools (Android SDK).

To get the Android SDK, you need to go to the Android Developer Website: http://developer.android.com/sdk/index.html and download the Android SDK Zip for your computer (in my case, Windows, X64). The zip file is quite big (400Mb+) and unarchived, goes up to a staggering 2GB. Once you apply all the updates that you need, it will go close to 2.5GB.

How to create a shortcut on the Home Screen on Android with Phone Gap

Home Shortcuts

This is the plugin to create/delete Shortcuts (Android) in Apache Cordova/PhoneGap!

The Shortcut plugin for Apache Cordova allows you to create or delete the shortcut in the home of any andorid device.

Usage Instructions

Add the following xml to your config.xml to always use the latest version of this plugin:

<gap:plugin name="com.plugins.shortcut" />

or to use this exact version:

<gap:plugin name="com.plugins.shortcut" version="0.1.1" />

Docs

Documentation for this plugin can be viewed here.

Android Install/Uninstall Shortcut Example

Nowadays many android apps installs a shortcut on home screen when you install the app and run it for the first time. This is a nice strategy to engage user by compiling them to use your app. Most of times when a user install an app, the app is deep buried in list of apps making it almost difficult to discover. So its always a good idea to make a shortcut right on home screen.

Android comes with simple yet undocumented API to add and remove shortcuts of any app on home screen. Let us check how to do this.

1. Install Shortcut on Home screen

Android provide us an intent class com.android.launcher.action.INSTALL_SHORTCUT which can be used to add shortcuts to home screen. In following code snippet we create a shortcut of activity MainActivitywith the name HelloWorldShortcut.

First we need to add permission INSTALL_SHORTCUT to android manifest xml.

<uses-permission
        android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

The addShortcut() method create a new shortcut on Home screen.

private void addShortcut() {
    //Adding shortcut for MainActivity
    //on Home screen
    Intent shortcutIntent = new Intent(getApplicationContext(),
            MainActivity.class);
    
    shortcutIntent.setAction(Intent.ACTION_MAIN);
    Intent addIntent = new Intent();
    addIntent
            .putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "HelloWorldShortcut");
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
            Intent.ShortcutIconResource.fromContext(getApplicationContext(),
                    R.drawable.ic_launcher));
    addIntent
            .setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(addIntent);
}

Note how we create shortcutIntent object which holds our target activity. This intent object is added into another intent as EXTRA_SHORTCUT_INTENT. Finally we broadcast the new intent. This adds a shortcut with name mentioned as
EXTRA_SHORTCUT_NAME and icon defined by EXTRA_SHORTCUT_ICON_RESOURCE.

Note: One thing worth noting here is when you define your activity that is invoked from shortcut, you must define android:exported=”true” attribute in <activity> tag. You’ll see this in our demo.

2. Uninstall Shortcut from Home screen

Similar to install, uninstalling or removing shortcut in Android uses an Intent (UNINSTALL_SHORTCUT) to perform the task. In following code we remove the shortcut added on home screen.

Again we need a permission to perform uninstall shortcut task. Add following permission to Android manifest xml.

<uses-permission
        android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

The removeShortcut() method does exactly reverse of addShortcut(). Most of the code is similar except removeShortcut calls UNINSTALL_SHORTCUT intent.

private void removeShortcut() {
    
    //Deleting shortcut for MainActivity
    //on Home screen
    Intent shortcutIntent = new Intent(getApplicationContext(),
            MainActivity.class);
    shortcutIntent.setAction(Intent.ACTION_MAIN);
    
    Intent addIntent = new Intent();
    addIntent
            .putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "HelloWorldShortcut");
    addIntent
            .setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(addIntent);
}

Let us check the full functionality by creating a demo application.

3. Demo Application

The demo application is very simple. The user interface has two buttons: one to add shortcut to home screen and another to remove it.

Following is the simple layout consiting of two buttons.

layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
        
    <Button
        android:id="@+id/buttonAddShortcut"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Add Shortcut" />
    <Button
        android:id="@+id/buttonRemoveShortcut"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Remove Shortcut" />
    
</LinearLayout>

The layout looks something like following:
android_add_shortcut_demo

The MainAcitivity is the activity class that handles user interface events. We add OnClickListener event handlers to both Add and Remove shortcut buttons. Each calls appropriate method to perform the task.

MainActivity.java

package net.viralpatel.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //Add listener to add shortcut button
        Button add = (Button) findViewById(R.id.buttonAddShortcut);
        add.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                addShortcut(); //Add shortcut on Home screen
            }
        });
        
        //Add listener to remove shortcut button
        Button remove = (Button) findViewById(R.id.buttonRemoveShortcut);
        remove.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                removeShortcut(); //Remove shortcut from Home screen
            }
        });    
    }
    
    private void addShortcut() {
        //Adding shortcut for MainActivity
        //on Home screen
        Intent shortcutIntent = new Intent(getApplicationContext(),
                MainActivity.class);
        
        shortcutIntent.setAction(Intent.ACTION_MAIN);
        Intent addIntent = new Intent();
        addIntent
                .putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "HelloWorldShortcut");
        addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
            Intent.ShortcutIconResource.fromContext(getApplicationContext(),
                        R.drawable.ic_launcher));
        addIntent
                .setAction("com.android.launcher.action.INSTALL_SHORTCUT");
        getApplicationContext().sendBroadcast(addIntent);
    }
    
    private void removeShortcut() {
        
        //Deleting shortcut for MainActivity
        //on Home screen
        Intent shortcutIntent = new Intent(getApplicationContext(),
                MainActivity.class);
        shortcutIntent.setAction(Intent.ACTION_MAIN);
        
        Intent addIntent = new Intent();
        addIntent
                .putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "HelloWorldShortcut");
        addIntent
                .setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
        getApplicationContext().sendBroadcast(addIntent);
    }
    
}

Also following is the Android manifest file for reference.

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.viralpatel.android"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    
    <uses-permission
        android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <uses-permission
        android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
   </application>
</manifest>

Screenshots of App

On clicking Add Shortcut button a toast message appears saying the shortcut has been successfully added on home screen.
android_install_shortcut_success

If you check the home screen, you will find the shortcut present.
android_shortcut_home_screen

The remove shortcut button triggers UNINSTALL_SHORTCUT intent and removes the shortcut from home screen. It also prints a toast message with confirmation.
android_unistall_shortcut_demo