Janrain: User management platform for the social web

Janrain Engage for iOS Documentation

Before You Begin

  • You need to have created a Janrain Engage application
  • If you would like to do server-side authentication, you'll need to create a token_url

Additional Documentation:

Introduction

Getting the Library

Using the Library



Introduction


The current version of the library is 2.3.X, which includes support for Xcode 4 and iOS 5; an updated social sharing UI; the ability to dynamically exclude providers from list of sign-in providers or directly authenticate with one provider; better handling when your application quits or goes into the background; and several bug fixes.


User Experience

Sign In

The Janrain Engage for iPhone library gives your application the ability to authenticate users through their existing social identity provider accounts — e.g., Google, Facebook, Twitter, etc. When you are ready to authenticate a user, the library presents a modal dialog displaying a list of the providers that you configured in your Engage application. The user can select his desired provider and sign in through the provider's web interface. The library remembers his preference for a better return experience.

Below are some screen shots demonstrating the sign-in process on the iPhone.

iPhone Screen Shots

For an example application demonstrating authentication with the Engage for iOS library, the Janrain Quick Sign-In* app is available for free from the AppStore.

Social Sharing

Additionally, the Engage for iOS library includes a social sharing API, giving your users the ability to share their activities on several social networks. You can compose an activity, and when you are ready, the library presents a modal dialog that allows your users to add their comments and share the activity. They can post it to a number of social providers, as well as share it through email and sms.

Below are some screen shots demonstrating social sharing on the iPhone.

iPhone Screen Shots

For an example application demonstrating how you can share an activity with the Engage for iOS library, the Janrain Quick Publish* app is available for free from the AppStore.

On the iPad:

The Engage for iOS SDK also works, as is, on the iPad and with universal apps. No changes to your code are required. The library dynamically detects the device and presents its dialogs in modal views optimized for the iPad.

Below are some screen shots demonstrating sign-in and social sharing on the iPad.

iPad Screen Shots
* The Quick Sign-In and Quick Publish applications are free and the source code for both applications ship with the library.

Components

The following components are the main actors that are required for social sign-in and sharing:
  • An iPhone/iPad Application*
  • The Janrain Engage for iOS library
  • The Engage server (rpxnow.com)
  • Sign-in and social sharing providers — e.g., Google, Facebook, Twitter, etc.
  • An optional web service* with an auth_info token URL
* Samples come with library

Sign-In Flow

  1. Your iOS application requests that the Engage for iOS library present the sign-in dialog.
  2. The user chooses a provider.
  3. The library takes the user to the provider in an embedded web browser where she signs in.
  4. Janrain Engage completes authentication and sends the auth_info token, the user's authentication information, and the user's unique identifier back to the library.
  5. The library closes the dialog and passes the profile data to the calling application.
  6. Optionally, the library can post the auth_info token to a token URL to complete server-side authentication:
    1. If you would like to do server-side authentication, you'll need to create a token URL. (See also, Janrain's sample code.)
    2. The library opens an HTTP/S connection to the token URL, in which:
      1. The library POSTs the auth_info token to the token URL.
      2. Your token URL server POSTs to the Engage auth_info url with the supplied auth_info token and your Engage API key. You may also make additional calls against the Engage API.
      3. The Engage server will respond to your server with the user's authentication information and the user's unique identifier.
      4. Your token URL server then creates a session tied to the user's identifier, and responds to the library with a session token.
    3. The response from your server's token URL, containing the session token you created, is passed to your JREngageDelegate via the jrAuthenticationDidReachTokenUrl:withResponse:andPayload:forProvider: method.
    4. Your mobile application stores the session token supplied in the token URL's response, and uses it to communicate securely with your web service — to conduct purchases, access user data, or perform other sensitive transactions.
  7. The application parses the profile data and the user is signed in.

Sharing Flow

  1. The application creates an activity object and populates the object's fields.
  2. The application initiates social sharing, passing the activity object to the library.
  3. The user can add comments and choose which provider he wishes to share the activity with.
  4. If the user is already signed in, he can post the activity to the provider.
  5. If the user is not signed in, the library takes the user to the provider's web interface where he authenticates, and then the activity is shared.
  6. The user can share to multiple providers, and the dialog is closed when the user presses the "Close" button.


Getting the Library


Prerequisites


Download the Library

You can either:
  • Download an archive of the library, or
  • clone the Janrain Engage for iOS library from GitHub:

    git clone git://github.com/janrain/engage.iphone.git

We recommend you clone the GitHub repository, and checkout a specific release tag. This way it's easy to keep up with the latest version of the Engage for iOS library — just git pull the master branch to get the latest stable release.

The current version of the library is 2.3.X, which includes support for Xcode 4 and iOS 5; an updated social sharing UI; the ability to dynamically exclude providers from list of sign-in providers or directly authenticate with one provider; better handling when your application quits or goes into the background; and several bug fixes.


Add the Library to Your Xcode Project

Xcode 4

  1. Open your project in Xcode.
  2. Make sure the "Project Navigator" pane is showing. (View → Navigators → Show Project Navigator ⌘1)
  3. In the "Project Navigator" pane of your Xcode project, right-click the root project node for your application — with the blue Xcode icon — and select the menu option New Group, to create a new group in your project tree. Rename this group "JREngage".
  4. Right-click the JREngage group, and select the menu option Add Files To "[your project name]"...
  5. Navigate to the location where you placed the engage.iphone, open that folder, and then open the JREngage subdirectory. Select the directories "Classes", "Resources", "Security", and "JSONKit", and the file "JREngage-Info.plist".
  6. In the dialog, do NOT check the "Copy items into destination group's folder (if needed)" box, make sure the "Create groups for any added folders" is selected, and that the "Add to targets" check box is selected for your application's targets. Click Add.
  7. You must also add the Security framework and the MessageUI framework to your project. As the MessageUI framework is not available on all iOS devices and versions, you must designate the framework as "weak-linked". Instructions for adding frameworks in Xcode 4 can be found in Apple's iOS Developer Documentation.

Working with ARC

The Janrain Engage for iOS library does not, itself, use automatic reference counting (ARC), but you can easily add the library to a project that does.

To use the Engage for iOS library with an ARC project, please follow the instructions below:

  1. Add the JREngage files to your project by following the above instructions for Xcode 4.
  2. Go to your project settings, select your application's target(s) and click the "Build Phases" tab.
  3. Expand the section named "Compile Sources".
  4. Select all the files from the JREngage library, including SFHFKeychainUtils.m and JSONKit.m.
  5. Hit Enter to edit all the files at once, and in the floating text-box add the -fno-objc-arc compiler flag.

Xcode 3.5

  1. Open your project in Xcode.
  2. Open the JREngage library in Xcode.
  3. Under the "Groups & Files" pane of the JREngage Xcode project, click the JREngage folder and drag it into the "Groups & Files" pane under your application's Xcode project.
  4. In the dialog, do NOT check the "Copy items" box, make sure the "Recursively create groups..." option is selected, and then click Add.
  5. Add the Security framework to your project by right-clicking the "Frameworks" group under your project and selecting
    Add → Existing Frameworks. Then locate "Security.framework" from the list, and add it to the project.
  6. (Optional) If you interested in adding social sharing though email and SMS, you must also add the MessageUI framework to your project. As this framework is not available on all versions of iOS, you must designate the framework as "weak-linked". Instructions for doing this can be found in the Email and SMS section of the documentation.

Upgrading the Library from a Previous Version

We recommend that you upgrade the library from versions 2.2.1 and below to the current version (v2.3.0), as this version has been updated for iOS 5. As there has been some changes to the files in the Engage for iOS Library, the easiest way to update the references in Xcode is to remove the JREngage group and re-add it.

  1. Open your project in Xcode.
  2. Locate the JREngage folder (group) under the "Project Navigator" pane — or the "Groups & Files" pane if you're using Xcode 3 — of your Xcode project.
  3. Right-click the JREngage folder and select Delete.
  4. In the dialog, make sure you select the Remove References Only button.
  5. Re-add the JREngage files following the above instructions for Xcode 3.5 or Xcode 4. You shouldn't have to add the Security or MessageUI frameworks if you have already done so.


Using the Library


You can use the JREngage library in three easy steps:

  1. Instantiate the library with your Engage application's Application ID, your server's token URL (optional), and the delegate class that implements the JREngageDelegate protocol
  2. Begin authentication or sharing by calling one of the "show...Dialog" methods
  3. Implement the JREngageDelegate protocol to receive notifications and profile information for your authenticating users

Quick Start Guide

To begin, sign in to Engage and configure the providers you wish to use for authentication and/or social sharing. You will also need your 20-character Application ID from the Engage Dashboard.


Import the JREngage headers:

#import "JREngage.h"


Initialize

To initialize an instance of the library, pass the Application ID of your Janrain Engage application (found on the Engage Dashboard), an optional token URL, and an optional delegate object to the JREngage class method jrEngageWithAppId:andTokenUrl:delegate: which returns a pointer to the shared instance of the JREngage object:

NSString *appId = @"<your app id>";

...

JREngage *jrEngage = [JREngage jrEngageWithAppId:appId andTokenUrl:nil delegate:self];

If you wish to implement server-side authentication you can optionally pass your token URL to this method. Make sure that your delegate class implements the JREngageDelegate protocol.


Social Sign-In

In the section of code where you wish to launch the library's authentication process, send the showAuthenticationDialog message to your JREngage object:

[jrEngage showAuthenticationDialog];

To receive the user's basic profile data, implement the jrAuthenticationDidSucceedForUser:forProvider: method from the JREngageDelegate protocol:

- (void)jrAuthenticationDidSucceedForUser:(NSDictionary*)auth_info
                              forProvider:(NSString*)provider
{
    NSString *preferredUserName = [[profile objectForKey:@"profile"]
                                            objectForKey:@"preferredUsername"];
  
    UIAlertView *alert = [[[UIAlertView alloc]
                            initWithTitle:[NSString stringWithFormat:
                                            @"Hello, %@!", preferredUserName]
                                  message:[NSString stringWithFormat:
                                            @"You have successfully signed in to %@!",
                                            provider]
                                 delegate:self
                        cancelButtonTitle:@"OK"
                        otherButtonTitles:nil] autorelease];
    [alert show];
}

Social Sharing

If you want to share an activity, first create an instance of the JRActivityObject and populate the activity object's fields:

JRActivityObject *activity = [[[JRActivityObject alloc]
                                initWithAction:@"added JREngage to her iPhone application!"
                                        andUrl:@"http://janrain.com"] autorelease];

Then pass the activity to the showSocialPublishingDialogWithActivity: message:

[jrEngage showSocialPublishingDialogWithActivity:activity];

Even Quicker Quick Start Guide

Just copy and paste!

  1. Sign in to Engage, create an application, and configure the providers you wish to use for sign-in and/or social publishing.
  2. Import the JREngage headers:
    #import "JREngage.h"
  3. To authenticate*:
    JREngage *jrEngage = [JREngage jrEngageWithAppId:@"<your app id>"
                                         andTokenUrl:nil
                                            delegate:self];
    
    [jrEngage showAuthenticationDialog];
    
  4. To share*:
    JREngage *jrEngage = [JREngage jrEngageWithAppId:@"<your app id>"
                                         andTokenUrl:nil
                                            delegate:self];
    
    [jrEngage showSocialPublishingDialogWithActivity:
              [JRActivityObject activityObjectWithAction:@"<just did something fabulous>"
                                           andUrl:@"http://<your_url>"]];
    
  5. Implement the JREngageDelegate protocol:
    - (void)jrEngageDialogDidFailToShowWithError:(NSError*)error { }
    
    - (void)jrAuthenticationDidNotComplete { }
    
    - (void)jrAuthenticationDidSucceedForUser:(NSDictionary*)auth_info
                                  forProvider:(NSString*)provider { }
    
    - (void)jrAuthenticationDidFailWithError:(NSError*)error
                                 forProvider:(NSString*)provider { }
    
    - (void)jrAuthenticationDidReachTokenUrl:(NSString*)tokenUrl
                                withResponse:(NSURLResponse*)response
                                  andPayload:(NSData*)tokenUrlPayload
                                 forProvider:(NSString*)provider { }
    
    - (void)jrAuthenticationCallToTokenUrl:(NSString*)tokenUrl
                          didFailWithError:(NSError*)error
                               forProvider:(NSString*)provider { }
    
    - (void)jrSocialDidNotCompletePublishing { }
    
    - (void)jrSocialDidCompletePublishing { }
    
    - (void)jrSocialDidPublishActivity:(JRActivityObject*)activity
                           forProvider:(NSString*)provider { }
    
    - (void)jrSocialPublishingActivity:(JRActivityObject*)activity
                      didFailWithError:(NSError*)error
                           forProvider:(NSString*)provider { }
    

Add code to the delegate messages you care about receiving, replace anything <between angle brackets>, and you're good to go!

* The first time your application uses JREngage on any device, the library contacts the Engage servers to retrieve your application's list of providers and other configuration information JREngage needs to work. Once this has been downloaded, the library caches this information for subsequent launches, updating the cache only when the information has changed (e.g., you add or remove a provider).

While you can initialize the JREngage library immediately before you call one of the show... methods, please understand that your users may encounter our loading screen during the delay in which the library contacts the Engage servers.

Server-side Authentication

If you would like to access any of the extra features available in Janrain Engage's API or if you would like to complete server-side authentication, you can do so by implementing a token URL that does the following:

  1. Implement a method to which the JREngage library can POST the token
  2. Extract the token
  3. Make a call to auth_info with the token and your application's 40-character Application Key
  4. Parse the profile data returned from the call to auth_info, and do anything to log your user in to your web application, create session cookies, etc.
  5. Use the token to access other Janrain Engage features via the API, such as get_contacts* and map*
  6. Send a response back to the JREngage library with any additional information that your application may need
* Some features may be limited to Pro, Plus and Enterprise customers only.

To use your token URL, you can pass it into the jrEngageWithAppId:andTokenUrl:delegate: method when initializing the shared instance of the library:

static NSString *appId = @"<your app id>";
static NSString *tokenUrl = @"<your token url>";
...

jrEngage = [JREngage jrEngageWithAppId:appId andTokenUrl:tokenUrl delegate:self];

Alternatively, you can change the token URL* at any time using the updateTokenUrl: method:

- (void)updateTokenUrl:(NSString*)newTokenUrl;
* The JREngage library will only post the token if this value is not null.

IMPORTANT: Whether or not the library posts the token to the token URL, your iPhone application should not contain the Application Key.


Email and SMS Sharing

You can also share your activity through email and sms.* This additional feature uses the iPhone SDK's native MessageUI framework, which you will need to add to your Xcode project:

  1. Add the MessageUI framework to your project by right-clicking the "Frameworks" group under your project and selecting Add > Existing Frameworks.
  2. Locate MessageUI.framework from the list, and add it to the project.

As this framework is not available on all versions of the iOS, you must designate the framework as weak-linked:

  1. Once you have added the framework to your project, expand your Application Target and select the target's build phase called "Link Binary With Libraries".
  2. Once this is selected, go to the "Detail" view and you can change the MessageUI's role from "Required" to "Weak".

As not all devices have the ability to share via email or sms, designating the MessageUI.framework as weak-linked will allow the library to dynamically detect the functionality of the device and allow the user the option to share only if email and/or sms are available. If the device is not capable of sending and email or sms, this is detected the option(s) will not be available to the user.

Device can only share email

Device can only share sms

Device can share email and sms


To share with email or sms, create an email or sms object, populate the object's fields, and add the object to the email or sms property in your JRActivityObject. The given content is supplied to the MFMailComposeViewController or MFMessageComposeViewController class when the user wants to share your activity via email.

* Although the actual sending of an email or sms does not go through the Engage servers (it solely uses the iOS MessageUI framework), Engage will track when an activity is successfully shared via email/sms.

Email

Create a JREmailObject and populate the fields of the object:

JREmailObject *email =
    [JREmailObject emailObjectWithSubject:@"Check out this article from the Janrain Blog!"
                           andMessageBody:@"<html><bod><br /> \
                                            I found this article on Janrain's Blog, \
                                            and I thought you might be interested! \
                                            <br /> \
             <a href=\"http://www.janrain.com/blogs/social-login-iphone-janrain-engage\"> \
                                            Click here to read it.</a> \
                                            <br /> \
                                            Learn more at <a href=\"http://janrain.com\"> \
                                            http://janrain.com</a><br /> \
                                            <br /></body></html>"
                                   isHtml:YES
                     andUrlsToBeShortened:nil];

Add the object to the your JRActivityObject and pass it to the library.*

JRActivityObject *activity =
    [[[JRActivityObject alloc]
        initWithAction:@"shared an article from the Janrain Blog."
                andUrl:@"http://www.janrain.com/blogs/social-login-iphone-janrain-engage"]
        autorelease];

activity.email = email;
[jrEngage showSocialPublishingDialogWithActivity:activity];

SMS

Create a JRSmsObject and populate the fields of the object:

JRSmsObject *sms =
    [JRSmsObject smsObjectWithMessage:
                    [NSString stringWithFormat:
                      @"Check out this article from the Janrain Blog!\n\n%@",
                      @"http://www.janrain.com/blogs/social-login-iphone-janrain-engage"]
                 andUrlsToBeShortened:nil];

Add the object to the your JRActivityObject and pass it to the library.*

JRActivityObject *activity =
    [[[JRActivityObject alloc]
        initWithAction:@"shared an article from the Janrain Blog."
                andUrl:@"http://www.janrain.com/blogs/social-login-iphone-janrain-engage"]
        autorelease];


activity.sms = sms;
[jrEngage showSocialPublishingDialogWithActivity:activity];
* If you do not supply a JREmailObject or JRSmsObject to the JREActivityObject, the option of sharing via email or sms (respectively) will not be available to the user. Likewise, if you do supply an email or sms object to the activity, but the device does not have this capability, the option will not be available to the user as well.

URL Shortening

If your email message body contains URLs that you would like shortened to an http://rpx.me/ URL (with which you can track click-throughs), you can do this by using the urls property of the JREmailObject or the urls property of the JRSmsObject. The library will contact the Engage servers to obtain up to 5 shortened URLs for email and sms each and replace the URLs in your email and sms message bodies.

Create an email or sms object, and populate the message body/message fields with your content, including the URLs that you would like shortened:

JREmailObject *email =
    [JREmailObject emailObjectWithSubject:@"Check out this article from the Janrain Blog!"
                           andMessageBody:@"<html><body><br /> \
                                            I found this article on Janrain's Blog, \
                                            and I thought you might be interested! \
                                            <br /> \
             <a href=\"http://www.janrain.com/blogs/social-login-iphone-janrain-engage\"> \
                                            Click here to read it.</a> \
                                            <br /> \
                                            Learn more at <a href=\"http://janrain.com\"> \
                                            http://janrain.com</a><br /> \
                                            <br /></body></html>"
                                   isHtml:YES
                     andUrlsToBeShortened:nil];

JRSmsObject *sms =
    [JRSmsObject smsObjectWithMessage:
                    [NSString stringWithFormat:
                    @"Check out this article \
                      from the Janrain Blog!\n\n%@",
                      http://www.janrain.com/blogs/social-login-iphone-janrain-engage]
                 andUrlsToBeShortened:nil];

Create an array, add the exact URLs to the array, and add the array as the urls property of the email/sms object:

NSArray *emailUrls = 
  [NSArray arrayWithObjects:
    @"http://www.janrain.com/blogs/social-login-iphone-janrain-engage",
    @"http://janrain.com", nil];

email.urls = emailUrls;

NSArray *smsUrls =
  [NSArray arrayWithObjects:
    @"http://www.janrain.com/blogs/social-login-iphone-janrain-engage", nil];

sms.urls = smsUrls;

Once you pass the activity object to the library, it will contact the Engage servers to obtain shortened URLs for all the URLs that you provided in the url arrays. Once this connection returns, the library will replace any instance of your URLs in your email/sms message body with the http://rpx.me URL. When a user clicks on any shortened URL, it will redirect them to the original URL and Engage will track the referral.

When obtaining the shortened URLs, the connection to the Engage server is made as soon as your application opens the library's sharing dialog. To maintain the best user experience, this call is non-blocking, but, if there are network latency issues, the connection may not return before the user is ready to share your activity via email/sms. If the user does attempt to share the activity via email before the connection to shorten the URLs is returned, the email will contain the original URLs and the click-throughs will not be tracked. As soon as the connection returns, the activity is modified to contain the shortened URLs.


Copyright © 2017 Janrain, Inc.