<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NathanHJones.com &#187; business</title>
	<atom:link href="http://nathanhjones.com/category/business/feed/" rel="self" type="application/rss+xml" />
	<link>http://nathanhjones.com</link>
	<description>just thinking outloud</description>
	<lastBuildDate>Fri, 11 Nov 2011 06:55:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>A Single Sign-on Pattern for Enterprise iOS Applications</title>
		<link>http://nathanhjones.com/2011/11/11/a-single-sign-on-pattern-for-enterprise-ios-applications/</link>
		<comments>http://nathanhjones.com/2011/11/11/a-single-sign-on-pattern-for-enterprise-ios-applications/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 06:30:32 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iphone sdk]]></category>
		<category><![CDATA[mSSO]]></category>
		<category><![CDATA[single sign-on]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=341</guid>
		<description><![CDATA[In conversations with clients, we continue to hear how important single sign-on is to their enterprise mobile application strategy. According to a study earlier this year by Kelton Research 250 IT Managers, 21% of respondents indicated that they plan to deploy 20, or more, enterprise applications to their organization this year. In order for enterprises [...]]]></description>
			<content:encoded><![CDATA[<p>
In conversations with clients, we continue to hear how important single sign-on is to their enterprise mobile application strategy.  According to a <a href="http://www.echannelline.com/usa/story.cfm?item=26463">study earlier this year by Kelton Research 250 IT Managers</a>, 21% of respondents indicated that they plan to deploy 20, or more, enterprise applications to their organization this year.
</p>
<p>
In order for enterprises to realize the productivity gains factored into the investment decisions for those applications, IT Managers must explore options for enabling single sign-on for their users. In this post, we&#8217;ll outline a mobile single sign-on (mSSO) pattern for enterprise iOS applications.
</p>
<h2>Assumptions</h2>
<ol>
<li>Your company has a centralized single sign-on service exposed on the network &#8211; LDAP, Novell Access Manager, etc. This approach will work with a number of identity management architectures, but you will need to tailor credential management accordingly. For this demo, our service calls are simulated with hardcoded tokens.</li>
<li>Your company has a standardized credential timeout period or a way of dynamically distributing that value to applications. For this demo, we&#8217;ll use a static 30 minute timeout period.</li>
<li>You are able to sign and distribute builds to a device. This is important because keychain activities do not function in the simulator.</li>
</ol>
<h2>Implementation</h2>
<h4>Approach</h4>
<p>
Our approach will consist of creating three applications &#8211; two mock business applications and one logout application. Each application may contain its own logout functionality, but a single logout application makes the user&#8217;s activity of killing a session intuitive.  In practice, the mSSO pattern would be implemented as a stand-alone library which could be easily dropped into each of your various enterprise applications.
</p>
<p>
The business applications retrieve a unique authentication token which is included with each service request.  This token will be stored in the device&#8217;s <a href="http://developer.apple.com/library/ios/#documentation/Security/Reference/keychainservices/Reference/reference.html">keychain</a>, which will be shared across our suite of applications.  We will also maintain an &#8216;expiration date&#8217; within the keychain so that subsequent requests from our various apps can (if required) preemptively prompt the user to authenticate.
</p>
<p>
Authentication for this demo may be simplistic, but <a href="http://blogs.captechconsulting.com/blog/jack-cox/managing-complex-mobile-transactions">existing patterns</a> cover implementing authentication in a service-based mobile application.  For example, the &#8216;store credentials&#8217; logic presented in this example would live somewhere in that pattern&#8217;s &#8220;authenticateOperation&#8221;.
</p>
<p>
One possible extension of the mSSO pattern is to confirm that your credentials have not expired before issuing a call to the service.  You would use the mSSO pattern to sign your network requests, but rely on the service and response handlers to inform you that credentials have expired.  Checking credential expiration prior to making a service call limits unnecessary network traffic.
</p>
<h4>Configuration</h4>
<p>
There are two key steps that must be completed in order for your applications to share keychain access.</p>
<ol>
<li>Each application included in your mSSO effort must share a Bundle Seed ID, which allows shared keychain access between our suite of applications. This is configured within the <a href="http://developer.apple.com/ios/manage/overview/index.action">iOS management portal</a>. We&#8217;ll configure our applications using the default &#8216;Team ID&#8217; selection.</li>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/11/app1.png"><img src="http://nathanhjones.com/wp-content/uploads/2011/11/app1-300x136.png" alt="" title="app1" width="300" height="136" class="aligncenter size-medium wp-image-354" /></a><br />
<a href="http://nathanhjones.com/wp-content/uploads/2011/11/end-result.png"><img src="http://nathanhjones.com/wp-content/uploads/2011/11/end-result-300x61.png" alt="" title="end-result" width="300" height="61" class="aligncenter size-medium wp-image-355" /></a></p>
<li>We also need to enable and add an entitlements file that specifies that this application should be able to access the shared keychain. <span style="font-weight:bold;">This step is done after the Xcode project has been created.</span></li>
<ul>
<li>Select your app target in Xcode and choose the &#8216;Summary&#8217; tab.</li>
<li>Choose &#8216;Enable Entitlements&#8217; at the bottom.</li>
<li>Set the Entitlements File name to &#8220;mSSO&#8221; and hit return. Select &#8216;Create&#8217; when prompted.</li>
<li>Unless needed for your application, remove iCloud configuration settings.</li>
<li>Add a keychain value titled &#8220;mSSO&#8221;, our Bundle Seed ID is prepended to this value for us.</li>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/11/app-target-entitlements.png"><img src="http://nathanhjones.com/wp-content/uploads/2011/11/app-target-entitlements-300x137.png" alt="" title="app-target-entitlements" width="300" height="137" class="aligncenter size-medium wp-image-360" /></a><br />
<a href="http://nathanhjones.com/wp-content/uploads/2011/11/mSSO-entitlements-file.png"><img src="http://nathanhjones.com/wp-content/uploads/2011/11/mSSO-entitlements-file-300x35.png" alt="" title="mSSO-entitlements-file" width="300" height="35" class="aligncenter size-medium wp-image-361" /></a>
</ul>
</ol>
<h4>Development</h4>
<p>
We&#8217;ll walk through how to create App1 in detail, and then let you work through App2 and the Logout application. Let&#8217;s start by opening Xcode and creating a single view application.  Before we get started, add the Security.framework and create your entitlement files as outlined above.  <a href="http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html" target="_blank">Here</a> is a good primer for interacting with the keychain.
</p>
<ol>
<li>Add the custom <code>mSSOUtils</code> and <code>DateUtils</code> classes as outlined below.  Make sure that you import accordingly.  Due to changes in iOS related to <a href="http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iOS5.html#//apple_ref/doc/uid/TP30915195-SW4">ARC</a> (developer account required), you will need to disable ARC for the <code>mSSOUtils</code> class.  You can do so by selecting your target in Xcode and viewing the <span style="font-weight:bold;">Build Phases</span> tab. Expand the <span style="font-weight:bold;">Compile Sources</span> section and double click the <code>mSSOUtils</code> class to add the <code>-fno-objc-arc</code> compiler flag.  You may need to clean and build.<br />
<span style="font-weight:bold;">mSSOUtils:</span></p>

<div class="wp_codebox"><table><tr id="p3418"><td class="code" id="p341code8"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kmSSOKeychainGroup @&quot;3Q4M6DQ9WM.mSSO&quot;</span>
<span style="color: #6e371a;">#define kAuthenticationServiceName @&quot;com.captechconsulting.msso&quot;</span>
<span style="color: #6e371a;">#define kCredentialToken @&quot;mSSOAuthenticationToken&quot;</span>
<span style="color: #6e371a;">#define kCredentialExpiration @&quot;mSSOCredentialsExpirationDate&quot;</span>
<span style="color: #6e371a;">#define kExpirationTimeout 60.0 * 30    // 30 minute timeout</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// *** PRIVATE METHODS DEF *** //</span>
<span style="color: #a61390;">@interface</span> mSSOUtils <span style="color: #002200;">&#40;</span>Private<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> keychainSearch<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> getValueForIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifer;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>value forIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> deleteValueForIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> mSSOUtils<span style="color: #002200;">:</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> authenticateWithUsername<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>username andPassword<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>password <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// for testing purposes, each call to this method authenticates successfully</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// set the token - app specific - change this in your App2 implementation</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;TokenSetFromApp1&quot;</span> forIdentifier<span style="color: #002200;">:</span>kCredentialToken<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// token set, now set the credential expiration</span>
        <span style="color: #002200;">&#91;</span>self extendCredentials<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to set token.&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> logout <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// destroy token AND expiration date</span>
    <span style="color: #002200;">&#91;</span>self deleteValueForIdentifier<span style="color: #002200;">:</span>kCredentialToken<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>self deleteValueForIdentifier<span style="color: #002200;">:</span>kCredentialExpiration<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// credential management</span>
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> extendCredentials <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>newExpireDate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>DateUtils dateWithTimeout<span style="color: #002200;">:</span>kExpirationTimeout<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>newExpireString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>DateUtils stringFromDate<span style="color: #002200;">:</span>newExpireDate withFormat<span style="color: #002200;">:</span>kDateFormat<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">BOOL</span> success <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span>newExpireString forIdentifier<span style="color: #002200;">:</span>kCredentialExpiration<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>success<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to extend credentials.&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> credentialsExpired <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// if no token exists, call credentials expired</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self credentialToken<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>expirationDate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self credentialExpirationDate<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>expirationDate<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// check for expiration</span>
        <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>DateUtils dateInPast<span style="color: #002200;">:</span>expirationDate<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// if there is no expiration date, default to 'expired'</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #11740a; font-style: italic;">// sign the request with current credentials - we'll add the token as an HTTP header field</span>
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSMutableURLRequest</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> signRequest<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSMutableURLRequest</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>request <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>token <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self credentialToken<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>token<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>request addValue<span style="color: #002200;">:</span>token forHTTPHeaderField<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;auth-token&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">return</span> request;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// methods to retrieve credential information</span>
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> credentialToken <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>token <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self getValueForIdentifier<span style="color: #002200;">:</span>kCredentialToken<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> token;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> credentialExpirationDate <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>expirationDateString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self getValueForIdentifier<span style="color: #002200;">:</span>kCredentialExpiration<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>expirationDateString<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// convert to date</span>
        <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>DateUtils dateFromString<span style="color: #002200;">:</span>expirationDateString withFormat<span style="color: #002200;">:</span>kDateFormat<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> displayAuthenticateView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIViewController <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>vc <span style="color: #002200;">&#123;</span>
    authenticateViewController <span style="color: #002200;">*</span>authenticateView <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>authenticateViewController alloc<span style="color: #002200;">&#93;</span> initWithNibName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;authenticateViewController&quot;</span> bundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    UINavigationController <span style="color: #002200;">*</span>nc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UINavigationController alloc<span style="color: #002200;">&#93;</span> initWithRootViewController<span style="color: #002200;">:</span>authenticateView<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>vc presentModalViewController<span style="color: #002200;">:</span>nc animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #6e371a;">#pragma mark -</span>
<span style="color: #6e371a;">#pragma mark PRIVATE METHODS</span>
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> keychainSearch<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>keychainSearch <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableDictionary</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>keychainSearch setObject<span style="color: #002200;">:</span>kmSSOKeychainGroup forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecAttrAccessGroup<span style="color: #002200;">&#93;</span>;   <span style="color: #11740a; font-style: italic;">// inform the search that we're using the shared keychain</span>
    <span style="color: #002200;">&#91;</span>keychainSearch setObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecClassGenericPassword forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecClass<span style="color: #002200;">&#93;</span>;   <span style="color: #11740a; font-style: italic;">// set the type to generic password - other options are certification, internet password, etc</span>
&nbsp;
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>encodedIdentifier <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>identifier dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>keychainSearch setObject<span style="color: #002200;">:</span>encodedIdentifier forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecAttrGeneric<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>keychainSearch setObject<span style="color: #002200;">:</span>encodedIdentifier forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecAttrAccount<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>keychainSearch setObject<span style="color: #002200;">:</span>kAuthenticationServiceName forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecAttrService<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">return</span> keychainSearch;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> getValueForIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>search <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self keychainSearch<span style="color: #002200;">:</span>identifier<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>search setObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecMatchLimitOne forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecMatchLimit<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// limit it to the first result</span>
    <span style="color: #002200;">&#91;</span>search setObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kCFBooleanTrue forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecReturnData<span style="color: #002200;">&#93;</span>;    <span style="color: #11740a; font-style: italic;">// return data vs a dictionary of attributes</span>
&nbsp;
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>value <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    OSStatus status <span style="color: #002200;">=</span> SecItemCopyMatching<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>search,
                                          <span style="color: #002200;">&#40;</span>CFTypeRef <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>value<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>status <span style="color: #002200;">==</span> noErr<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithUTF8String<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>value bytes<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>value forIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// check if value exists</span>
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>existingValue <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self getValueForIdentifier<span style="color: #002200;">:</span>identifier<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>existingValue<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>existingValue isEqualToString<span style="color: #002200;">:</span>value<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #11740a; font-style: italic;">// update value</span>
            <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>search <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self keychainSearch<span style="color: #002200;">:</span>identifier<span style="color: #002200;">&#93;</span>;
&nbsp;
            <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>valueData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
            <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>update <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>valueData, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecValueData, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
            OSStatus status <span style="color: #002200;">=</span> SecItemUpdate<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>search,
                                            <span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>update<span style="color: #002200;">&#41;</span>;
&nbsp;
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>status <span style="color: #002200;">==</span> errSecSuccess<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
            <span style="color: #002200;">&#125;</span>
            <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
        <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
&nbsp;
        <span style="color: #11740a; font-style: italic;">// create new entry</span>
        <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>add <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self keychainSearch<span style="color: #002200;">:</span>identifier<span style="color: #002200;">&#93;</span>;
&nbsp;
        <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>valueData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#91;</span>add setObject<span style="color: #002200;">:</span>valueData forKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>kSecValueData<span style="color: #002200;">&#93;</span>;
&nbsp;
        OSStatus status <span style="color: #002200;">=</span> SecItemAdd<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>add,<span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>;
&nbsp;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>status <span style="color: #002200;">==</span> errSecSuccess<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
        <span style="color: #002200;">&#125;</span>
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
&nbsp;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> deleteValueForIdentifier<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>identifier <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>search <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self keychainSearch<span style="color: #002200;">:</span>identifier<span style="color: #002200;">&#93;</span>;
    SecItemDelete<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>search<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p><span style="font-weight:bold;">DateUtils:</span></p>

<div class="wp_codebox"><table><tr id="p3419"><td class="code" id="p341code9"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> dateFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #a61390;">string</span> withFormat<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>format <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>dateFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter setDateFormat<span style="color: #002200;">:</span>format<span style="color: #002200;">&#93;</span>;
	<span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>date <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span><span style="color: #a61390;">string</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> date;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> stringFromDate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>date withFormat<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>format; <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>dateFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter setDateFormat<span style="color: #002200;">:</span>format<span style="color: #002200;">&#93;</span>;
	<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>dateString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter stringFromDate<span style="color: #002200;">:</span>date<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> dateString;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> dateWithTimeout<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSTimeInterval<span style="color: #002200;">&#41;</span>timeout <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>now <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDate</span> date<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>timeoutDate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>now dateByAddingTimeInterval<span style="color: #002200;">:</span>timeout<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> timeoutDate;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> dateInPast<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>date <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>date compare<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDate</span> date<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> NSOrderedAscending<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
<li>Within the generated <code>ViewController</code>, add two <code>UILabel</code> outlets/properties &#8211; token and expiration date &#8211; and a &#8220;Logout&#8221; button.  You&#8217;ll need to add two custom methods: logout and a selector to handle the foreground notification we register to receive.

<div class="wp_codebox"><table><tr id="p34110"><td class="code" id="p341code10"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span> logout<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>mSSOUtils logout<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>mSSOUtils displayAuthenticateView<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> enterForeground<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// reset labels as we've entered the foreground</span>
    self.token.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>mSSOUtils credentialToken<span style="color: #002200;">&#93;</span>;
    self.expiration.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>DateUtils stringFromDate<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>mSSOUtils credentialExpirationDate<span style="color: #002200;">&#93;</span> withFormat<span style="color: #002200;">:</span>kDateFormat<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
<li>You should only need to update two view lifecycle methods within <code>ViewController</code> &#8211; <code>viewDidLoad</code> and <code>viewWillAppear</code>.  Within <code>viewDidLoad</code>, we register to receive a notification when the app is brought to the foreground that triggers our UI updates.  The additions to <code>viewWillAppear</code> simply update our labels if there is data in the keychain.

<div class="wp_codebox"><table><tr id="p34111"><td class="code" id="p341code11"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super viewDidLoad<span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// register for enter foreground notification to update labels</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNotificationCenter</span> defaultCenter<span style="color: #002200;">&#93;</span> addObserver<span style="color: #002200;">:</span>self 
                                             selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>enterForeground<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
                                                 name<span style="color: #002200;">:</span>UIApplicationWillEnterForegroundNotification
                                               object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewWillAppear<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>animated <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super viewWillAppear<span style="color: #002200;">:</span>animated<span style="color: #002200;">&#93;</span>;
&nbsp;
    self.token.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>mSSOUtils credentialToken<span style="color: #002200;">&#93;</span>;
    self.expiration.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>DateUtils stringFromDate<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>mSSOUtils credentialExpirationDate<span style="color: #002200;">&#93;</span> withFormat<span style="color: #002200;">:</span>kDateFormat<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
<li>Add an <code>authenticateViewController</code> to your project. This will be displayed modally when the users credentials need to be re-challenged. This example simply has a login button, but this is where you would include typical login fields.

<div class="wp_codebox"><table><tr id="p34112"><td class="code" id="p341code12"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span> authenticate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// if authentication is successful, dismiss the view</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>mSSOUtils authenticateWithUsername<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;username&quot;</span> andPassword<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;hashedPassword&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self dismissModalViewControllerAnimated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>   
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
<li>Last up, we&#8217;ll need to update our application delegate to confirm our credentials are valid when the app launches or is brought back from the background.  You&#8217;ll need to update the <code>didFinishLaunchingWithOptions</code> and <code>applicationWillEnterForeground</code> methods as noted below:

<div class="wp_codebox"><table><tr id="p34113"><td class="code" id="p341code13"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>application<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application didFinishLaunchingWithOptions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>launchOptions <span style="color: #002200;">&#123;</span>
    self.window <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIWindow alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIScreen mainScreen<span style="color: #002200;">&#93;</span> bounds<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Override point for customization after application launch.</span>
    self.viewController <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ViewController alloc<span style="color: #002200;">&#93;</span> initWithNibName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ViewController&quot;</span> bundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    self.window.rootViewController <span style="color: #002200;">=</span> self.viewController;
    <span style="color: #002200;">&#91;</span>self.window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// credentials don't exist or are expired - display the authenticate view</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>mSSOUtils credentialsExpired<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>mSSOUtils displayAuthenticateView<span style="color: #002200;">:</span>self.viewController<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>applicationWillEnterForeground<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// credentials don't exist or are expired - display the authenticate view</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>mSSOUtils credentialsExpired<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>mSSOUtils displayAuthenticateView<span style="color: #002200;">:</span>self.viewController<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
<li>Now, rinse and repeat for App2.  You can follow the same steps for the Logout application, but you really just need a single view that calls <code>[mSSOUtils logout]</code> on launch and informs the user their credentials have been terminated.

<div class="wp_codebox"><table><tr id="p34114"><td class="code" id="p341code14"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>application<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application didFinishLaunchingWithOptions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>launchOptions <span style="color: #002200;">&#123;</span>
    self.window <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIWindow alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIScreen mainScreen<span style="color: #002200;">&#93;</span> bounds<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Override point for customization after application launch.</span>
    self.viewController <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ViewController alloc<span style="color: #002200;">&#93;</span> initWithNibName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ViewController&quot;</span> bundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    self.window.rootViewController <span style="color: #002200;">=</span> self.viewController;
    <span style="color: #002200;">&#91;</span>self.window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// logout to kill credentials</span>
    <span style="color: #002200;">&#91;</span>mSSOUtils logout<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>applicationWillEnterForeground<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>   
    <span style="color: #11740a; font-style: italic;">// logout to kill credentials</span>
    <span style="color: #002200;">&#91;</span>mSSOUtils logout<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</li>
</ol>
<p>
Here are a couple helpful hints while developing your solution:</p>
<ul>
<li>We&#8217;ve disabled ARC for the <code>mSSOUtils</code> class, which means you need to handle memory management yourself.</li>
<li>When building your application, if you get a Mach-O Linker error, ensure that you&#8217;ve added the Security.framework.</li>
</ul>
<h4>Testing</h4>
<p>
Our testing won&#8217;t get too crazy, but at this point you should be all set to install our suite of apps on your device.
</p>
<p>
We&#8217;ll start by opening App1 and simulating an authentication call. Once the modal view is dismissed, our token and expiration date should be updated &#8211; expiration being now + 30 minutes.  From here, jump to App2 where you should see the App1 token/expiration. Logout and re-authenticate within App2, which will update our token and expiration date.  Now, we&#8217;ll wait 30 minutes and test whether our token expires. After 30 minutes, open App1, you should be prompted with an authentication view.  Authenticate and then open the Logout app.  Enter App2 from the multi-task tray, you should be prompted to authenticate once again.
</p>
<p>
The test sequence above has been captured in the screenshots below.  Note: for brevity, I&#8217;ve excluded screenshots of each authentication view except for the final step.<br />
<a href="http://nathanhjones.com/wp-content/uploads/2011/11/mSSO-Testing.jpg"><img src="http://nathanhjones.com/wp-content/uploads/2011/11/mSSO-Testing-300x143.jpg" alt="" title="mSSO Testing" width="300" height="143" class="aligncenter size-medium wp-image-374" /></a>
</p>
<h4>Closing</h4>
<p>
This post presents a pattern for implementing single sign-on for your enterprise iOS applications. It should give you the foundation needed to begin implementing single sign-on in your applications. I&#8217;ve attached the source for App1. If you&#8217;ve got questions or are interested in additional source files, I&#8217;m <a href="http://twitter.com/nathanhjones">@nathanhjones</a> on Twitter.
</p>
<div style="border: 1px solid #cdcdcd; background-color: #ffffff; padding: 10px 0 10px 10px;">
<span style="font-weight:bold;">Project files:</span> <a href="http://nathanhjones.com/wp-content/uploads/2011/11/mssoapp1.zip">mssoapp1.zip</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2011/11/11/a-single-sign-on-pattern-for-enterprise-ios-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>12Sprints &#8211; My take on SAPs Google Wave competitor</title>
		<link>http://nathanhjones.com/2009/12/13/12sprints-my-take-on-saps-google-wave-competitor/</link>
		<comments>http://nathanhjones.com/2009/12/13/12sprints-my-take-on-saps-google-wave-competitor/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 02:20:18 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[12Sprints]]></category>
		<category><![CDATA[collaboration]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=220</guid>
		<description><![CDATA[A couple weeks ago I was given access to the 12sprints.com Beta program (thanks @12sprints for listening).  12Sprints is SAPs answer to Google Wave for the enterprise that they&#8217;ve deemed a &#8220;Virtual War Room&#8221;.  It seems to be part of the Business Objects division (based on information from emails I&#8217;ve received).  In short, I&#8217;m VERY [...]]]></description>
			<content:encoded><![CDATA[<p>A couple weeks ago I was given access to the <a href="http://12sprints.com/">12sprints.com</a> Beta program (thanks <a href="http://twitter.com/12sprints">@12sprints</a> for listening).  12Sprints is SAPs answer to Google Wave for the enterprise that they&#8217;ve deemed a &#8220;Virtual War Room&#8221;.  It seems to be part of the Business Objects division (based on information from emails I&#8217;ve received).  In short, I&#8217;m VERY impressed with the service and opportunities I see it leading to.</p>
<p>I&#8217;ve held off publishing my review to ensure I gave my self ample time to review the different aspects of the service.  I will say that my final experiment (before publishing my review, that is) was performed on a Mac in the Google Chrome browser. I was greeted by a warning message that was essentially &#8216;browser not supported, proceed at your own risk&#8217; but found no significant issues.  There were a few overflow errors (likely just CSS) but the service worked splendidly which excited me since Chrome is my browser of choice.</p>
<h3>How I&#8217;m Looking at 12Sprints</h3>
<p>So, I entered the experiment with limited exposure to Google Wave (I have an account but haven&#8217;t been that active) looking at 12Sprints purely from an enterprise operations standpoint.  How can the average enterprise use 12Sprints to succeed or make themselves better?  Four areas immediately popped into my mind with instant thoughts of SAP backend integration &#8211; purchasing, customer service, engineering and, of course, the executive suite.</p>
<p>Purchasing and customer service is probably at the top of everyone&#8217;s list.  The ability to collaborate across a multi-national corporation on large purchasing decisions or bounce a customers complaint around to different people in an organization with ease has incredible potential for the business and the consumer.  Combine the collaboration aspect of 12Sprints with integration to SAPs backend and the possibilities for process improvement are endless.  Ideally, I see purchasing and customer service being integrated with SAPs <a href="http://help.sap.com/saphelp_nw04/helpdata/en/f5/18fc39eb31a700e10000000a11402f/frameset.htm">Records Management</a> and <a href="http://help.sap.com/saphelp_crm40/helpdata/en/4c/d7fb717f7b3e4cba12953ec1b9b8c3/content.htm">Case Management</a> solutions.</p>
<p>Engineering is something that may not make it to the typical list of use-cases but I think it&#8217;s important to call out.  An organizations ability to design products and reduce the overall time to market is a competitive advantage that I see 12Sprints impacting for the better.  Couple the collaborative nature 12Sprints with SAPs <a href="http://help.sap.com/saphelp_ppm400/helpdata/en/00/e8c80ae8fc3842b5bedf5d67879dae/content.htm">cFolders</a> solution and I think you have a very interesting solution that will help reduce the time it takes for companies to hit the market introduction stage of a product.</p>
<h3>Feature Set</h3>
<p>12Sprints came loaded with a solid set of features for the typical enterprise.  Actions within 12Sprints are organized into what is called an &#8216;activity&#8217;.  Each activity can have any number of &#8216;tools&#8217; such as agenda&#8217;s, responsibility matrices (ARCI, RACI, DACI and RASIC), Cost/Benefit and SWOT analysis, Pro&#8217;s and Con&#8217;s and even a decision tool that requires that you &#8216;lock in&#8217; what was decided.</p>
<p>I think one of the really cool features is 12Sprints integration of the online note tool <a href="http://www.evernote.com/">Evernote</a>.  The process of adding content from my Evernote account was seemless and a huge draw for me personally.  I question it&#8217;s reach at the enterprise level right now (none of my clients are currently using Evernote) but at an individual user level I find it very useful.  User&#8217;s can also post content from their computers such as Excel spreadsheets,  PowerPoint presentations or that recently completed White Paper.</p>
<h3>Missing Features</h3>
<p>I think the biggest feature missing was the ability to chat with other members of an activity or your organization.  Collaboration on documents, decisions and the like is key (the major use-case here) so I don&#8217;t understand exactly why an embedded chat feature was left off the list.  My guess (hope) is that it is in the works for a future release.</p>
<p>Another feature that I&#8217;d like to see made more prominent is the services integration with various SAPs services.  Understandably, 12Sprints is still in beta (and I don&#8217;t have an SAP environment linked) but I couldn&#8217;t find any clues of it&#8217;s potential integration with an SAP backend system.</p>
<p>They do, however, have a call for developers looking to partner on the product so perhaps they&#8217;re attempting to build that &#8216;app store&#8217; ecosystem where enterprises can purchase miscellaneous extensions to enhance the service.  I think it would be a great move to drive innovation and reduce the time it takes for 12Sprints to exit Beta.  It&#8217;s obviously too early to tell but given that the apps are the flavor of the day for platform roadmaps I wouldn&#8217;t be surprised.</p>
<p><strong>All-in-all &#8211; two thumbs up so far and expect additional reviews as the 12Sprints team continues to enhance the service.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2009/12/13/12sprints-my-take-on-saps-google-wave-competitor/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Garyvee&#8217;s New ObsessedTV.com</title>
		<link>http://nathanhjones.com/2009/02/28/garyvees-new-obsessedtvcom/</link>
		<comments>http://nathanhjones.com/2009/02/28/garyvees-new-obsessedtvcom/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 00:56:05 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[gary vaynerchuk]]></category>
		<category><![CDATA[garyvee]]></category>
		<category><![CDATA[obsessedtv]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=208</guid>
		<description><![CDATA[So, I&#8217;ve seen mixed reviews of Gary Vaynerchuk&#8217;s newest venture, ObsessedTV.com.  Some love it and a couple hate it, but I&#8217;m not sure they&#8217;re really giving it a chance.  I must admit, when I first loaded it up I was a bit shocked at the direction he took but I think it&#8217;s a pretty solid [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve seen mixed reviews of <a href="http://garyvaynerchuk.com/">Gary Vaynerchuk&#8217;s</a> newest venture, <a href="http://obsessedtv.com/">ObsessedTV.com</a>.  Some love it and a couple hate it, but I&#8217;m not sure they&#8217;re really giving it a chance.  I must admit, when I first loaded it up I was a bit shocked at the direction he took but I think it&#8217;s a pretty solid play.  I mean, it&#8217;s different than we&#8217;re used to from Gary (hell, it&#8217;s not even 100% Gary) but he&#8217;s expanding his empire&#8230;what did you want him to do another wine show?!?  Perhaps something dedicated solely to Cabernet Franc, Gewürztraminer or Burgundy?!?  What gives!  He&#8217;s been there and clearly conquered that and while it will take time for people to adjust, I think it&#8217;s a step in a great direction.</p>
<p>Now, onto the show &#8211; I watched the Mark Bittman interview.  I&#8217;m not really their target demographic which is why the &#8220;set&#8221; probably wasn&#8217;t what I expected.  I can&#8217;t really take it to them for that though, it&#8217;s what I would consider a pretty standard set for interview format shows.  Overall, the episode seemed pretty &#8220;early stage&#8221; to me in that Samantha didn&#8217;t feel totally at ease, maybe even a little nervous.  Maybe it was the new setting but some of that may have been Mark who, in my opinion, seemed a bit snarky.  I think he&#8217;s earned a little of that right and I still think he&#8217;s a very interesting man.  Anyways, I look forward to future episodes as they just off the jitters and I can&#8217;t wait to see what kind of guests they can swing.  Knowing the little I do about Gary I&#8217;m sure they won&#8217;t disappoint.</p>
<p>In closing, I think it&#8217;s great idea that has real potential and it&#8217;s a bold move into a new demographic for Gary.  I want to see how it plays out but like I said earlier, he&#8217;s conquered wine and is making a play to expand his media empire.  For that my friends, you have to respect him.  As Gary would put it, he&#8217;s hustlin&#8217; and you can&#8217;t get down on someone for that!  Keep up the great work Gary and I look forward to the other stuff you plan on bringing us.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2009/02/28/garyvees-new-obsessedtvcom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apparently Intuit QuickBase Isn&#8217;t Dead</title>
		<link>http://nathanhjones.com/2008/07/03/apparently-intuit-quickbase-isnt-dead/</link>
		<comments>http://nathanhjones.com/2008/07/03/apparently-intuit-quickbase-isnt-dead/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 17:51:28 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[intuit]]></category>
		<category><![CDATA[platform]]></category>
		<category><![CDATA[quickbase]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=78</guid>
		<description><![CDATA[Ok, so almost 3 months ago when TechCrunch wrote that Intuit (the makers of TurboTax, QuickBooks, Quicken, etc) were launching a development platform within QuickBase I signed up.  I thought it would be pretty cool to at least see what they were doing and I&#8217;m really into Enterprise software (small, medium or large enterprises are [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, so almost 3 months ago when <a href="http://www.techcrunch.com/2008/04/16/watch-out-salesforce-intuit-opens-up-quickbase-to-developers/">TechCrunch wrote that Intuit</a> (the makers of TurboTax, QuickBooks, Quicken, etc) were launching a <a href="http://quickbase.intuit.com/">development platform within QuickBase</a> I signed up.  I thought it would be pretty cool to at least see what they were doing and I&#8217;m really into Enterprise software (small, medium or large enterprises are all the same to me &#8211; business is business no matter the size).</p>
<p>Well, after registering I didn&#8217;t get a confirmation email, a &#8220;thanks for registering&#8221; email or even a &#8220;you were rejected, better luck next time&#8221;.   I figured it was a good try, I guess I&#8217;m not getting that 5 minutes back.  Then yesterday, completely out of the blue, I get a note from QuickBase that  I&#8217;ve &#8220;been accepted into the <span class="nfakPe">Intuit</span> QuickBase Developer Program&#8221;.  Ok, well that&#8217;s cool but you may want to communicate a little better next time.  I figured some server troll somewhere ate my application.  Good thing you didn&#8217;t make me submit my password when I initially signed up or I would have been in trouble.</p>
<p>Anyways, I&#8217;ve completed the registration and I&#8217;m going to begin poking around what they have to offer.  At first glance it seems functional but not as visually pleasing as something I&#8217;d expect from Intuit.  It is in Beta though so I won&#8217;t give them too hard of a time.</p>
<p>More to come on QuickBase in the near future.  Maybe if I can find a few hours I&#8217;ll get an example application up.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/07/03/apparently-intuit-quickbase-isnt-dead/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google and Salesforce join forces</title>
		<link>http://nathanhjones.com/2008/04/17/google-and-salesforce-join-forces/</link>
		<comments>http://nathanhjones.com/2008/04/17/google-and-salesforce-join-forces/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 05:08:36 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[crm]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google apps]]></category>
		<category><![CDATA[salesforce]]></category>
		<category><![CDATA[salesforce for google apps]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=69</guid>
		<description><![CDATA[Google and Salesforce announced a partnership the other day that will bring a combined Google/Salesforce business suite to it&#8217;s users. The service is called &#8220;Salesforce for Google Apps&#8221; and touts &#8220;powerful yet easy-to-use productivity tools for smarter management of customers, sales and marketing.&#8221; There is the obviously emphasis on collaboration and communication between team/project members. [...]]]></description>
			<content:encoded><![CDATA[<p>Google and Salesforce <a href="http://googleenterprise.blogspot.com/2008/04/run-even-more-of-your-business-in-cloud.html">announced a partnership</a> the other day that will bring a combined <a href="http://www.salesforce.com/googleapps/">Google/Salesforce business suite</a> to it&#8217;s users.  The service is called &#8220;Salesforce for Google Apps&#8221; and touts &#8220;powerful yet easy-to-use productivity tools for smarter management of customers, sales and marketing.&#8221;</p>
<p>There is the obviously emphasis on collaboration and communication between team/project members.  My &#8216;sales&#8217; experience is relatively limited &#8211; I managed a newspaper in college and filling in for the occasional employee is about the extent of it &#8211; but the functionality seems practical.</p>
<p>One key feature I liked is the fact that email being sent (from the Gmail interface) can automatically be sent to a customers CRM account.  This provides you with a worry-free audit trail and allows your boss or someone covering for you (if you&#8217;re out sick or something) to quickly pick up where you left off.  Likewise, you can send customer emails directly within Salesforce.  I also liked the fact that you can attach/create Google Docs directly from Salesforce.  The uses for this are obvious and I think it will really be able to help the sales process.  Everything from quote notes, sales presentations and final contracts can be created directly from the Salesforce interface.</p>
<p>It didn&#8217;t look like the interface was the same between the two systems which is disappointing but I haven&#8217;t signed up for a test account yet so that&#8217;s just speculation based on the tour.  I think that offering a consistent interface between Google and Salesforce is a must and could help adoption among small businesses.</p>
<p>I don&#8217;t know much about Salesforce&#8217;s push for mobile but Google has mobile versions of Gmail and Docs and continues to improve them.  I&#8217;m curious to see what kind of mobile sales/business applications they make available to their users.  Anything less than full functionality is unacceptable, but that would be a pretty major project.  I&#8217;d also like to get some information on what the security architecture looks like.  <a href="http://mashable.com/2008/04/16/zoho-crm-enterprise/">ZOHO just announced</a> an enhanced architecture as part of it&#8217;s enterprise CRM which is a little more inline with what I see as an SAP consultant.</p>
<p>Simply put, the decision makes sense &#8211; Google is trying to break into enterprise business, Salesforce has a great customer base (and from what I read a decent set of applications) and both are competing with Microsoft in some fashion.  The partnership allows them to put the full-court press on Microsoft who has been slow to adopt a web-based business model.</p>
<p>It will obviously take time for larger corporations to make the move given the obvious security concerns (mostly on the Google front) and the fact that the majority of business users are still not comfortable with online applications.   One thing that could help Google&#8217;s case for enterprise applications is the fact that Vista has had so many bumps along the way.  The rate at which corporations have been moving to Vista has been slow at best.  I work for a technology company and we haven&#8217;t even heard rumor&#8217;s of a potential migration.</p>
<p>Here&#8217;s a <a href="http://www.salesforce.com/products/google/apps/tour/">quick video tour</a> of Salesforce for Google Apps:<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="350" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/E-o0QmS5TzM" /><embed type="application/x-shockwave-flash" width="425" height="350" src="http://www.youtube.com/v/E-o0QmS5TzM"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/04/17/google-and-salesforce-join-forces/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Time Warner is getting greedy!</title>
		<link>http://nathanhjones.com/2008/01/24/time-warner-is-getting-greedy/</link>
		<comments>http://nathanhjones.com/2008/01/24/time-warner-is-getting-greedy/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 02:11:36 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[itunes]]></category>
		<category><![CDATA[netflix]]></category>
		<category><![CDATA[time warner]]></category>
		<category><![CDATA[twc]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/2008/01/24/time-warner-is-getting-greedy/</guid>
		<description><![CDATA[According to several news sources that I frequent &#8211; Time Warner is considering a usage based charge for internet services. What a ridiculous notion &#8211; that&#8217;s never going to fly! Here is a few reasons this model is absolutely absurd: Photos: Tons of people from all ages share photos online. One bummer about photos&#8230;they tend [...]]]></description>
			<content:encoded><![CDATA[<p>According to several news sources that I frequent &#8211; <a href="http://www.readwriteweb.com/archives/time_warner_per_usage_billing.php">Time Warner is considering a usage based</a> charge for internet services.  What a ridiculous notion &#8211; that&#8217;s never going to fly!</p>
<p>Here is a few reasons this model is absolutely absurd:</p>
<ol>
<li><strong>Photos:</strong> Tons of people from all ages share photos online.  One bummer about photos&#8230;they tend to do be kind of big files, unless you limit that on your camera or edit them, which is really going to eat up your bandwidth.  More bandwidth = more money.</li>
<li><strong>Music:</strong> Downloading music from iTunes does it&#8217;s damage to your bandwidth as well.  With an average size (at least of my songs) averaging between 2.8 and 3.2 megabytes a piece you&#8217;re you could be looking at a pretty expensive internet bill if you&#8217;re an avid downloader of music.</li>
<li><strong>TV/Movies:</strong> With the rise of the internet it&#8217;s inevitable that videos and TV will eventually be delivered via the internet.  In fact, it&#8217;s already in the works. <a href="http://www.techcrunch.com/2007/12/26/apple-to-offer-fox-video-rentals-on-itunes/">Apple</a> (iTunes) and <a href="http://www.techcrunch.com/2008/01/13/netflix-offers-unlimited-streaming-as-itunes-rental-spoiler/">Netflix</a> are already offering TV and movie offerings streamed directly to you over the internet.</li>
</ol>
<p>I&#8217;m sure that part of the reason they&#8217;re looking into this is because of the rise in popularity of online video (YouTube et al) and photo sharing (pick any random website/social network and they probably offer photo hosting/sharing&#8230;) which taxes the service providers network.  While I&#8217;d like to feel sorry for Time Warner (and other internet providers for that matter) and the fact that they feel their network is being used too much (what did they think would happen)&#8230;I find it rather difficult given the fact they (Time Warner Cable: TWC) made almost $2 billion in profit for fiscal year 2006.  I hope everyone caught that hint of sarcasm.</p>
<p>I already have a problem with what cable companies are charging for &#8216;unlimited&#8217; (even though it was discovered that <a href="http://www.msnbc.msn.com/id/21376597/">Comcast</a> wasn&#8217;t exactly <a href="http://en.wikipedia.org/wiki/Network_neutrality">net neutral</a>) access to the internet and now they want to put limits or charge you more?!?  What is going through the minds of these companies these days?!?  Is that what a CEO that makes nearly $9.5 million dollars a year thinks up?</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/01/24/time-warner-is-getting-greedy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bank of America Buys Countrywide</title>
		<link>http://nathanhjones.com/2008/01/12/bank-of-america-buys-countrywide/</link>
		<comments>http://nathanhjones.com/2008/01/12/bank-of-america-buys-countrywide/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 16:11:08 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[finance]]></category>
		<category><![CDATA[bank of america]]></category>
		<category><![CDATA[countrywide]]></category>
		<category><![CDATA[housing market]]></category>
		<category><![CDATA[mortgage lending]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/2008/01/12/bank-of-america-buys-countrywide/</guid>
		<description><![CDATA[The less-than-stellar mortgage lending industry got a huge show of support yesterday when Bank of America agreed to buy Countrywide Financial for $4 Billion. Obviously this won&#8217;t solve problems but it goes a long way in showing that someone believes the housing and mortgage market will eventually recover. According to a Wall Street Journal article [...]]]></description>
			<content:encoded><![CDATA[<p>The less-than-stellar mortgage lending industry got a huge show of support yesterday when <a href="http://newsroom.bankofamerica.com/index.php?s=press_releases&amp;item=7956">Bank of America agreed to buy Countrywide Financial</a> for $4 Billion.  Obviously this won&#8217;t solve problems but it goes a long way in showing that someone believes the housing and mortgage market will eventually recover.</p>
<p>According to a <a href="http://online.wsj.com/article/SB120009769402185203.html?mod=googlenews_wsj">Wall Street Journal article</a> (quoting numbers from Inside Mortgage Finance), Countrywide and Bank of America controlled approximately 25% of the mortgage market during the first 9 months of 2007.  That puts their market share at slightly more than twice their nearest competitor which is at a distant 11%.   I&#8217;m curious to see if this plays out negatively as Bank of America seeks regulatory approval for the acquisition.</p>
<p>Given the state of the mortgage market, the acquisition will probably win Bank of America some bonus points as it teeters just below the 10% limit on U.S. deposits as regulators look to relax this restriction.  Bank of America will also be getting a relatively large (I&#8217;m assuming some Countrywide members are already BofA account holders) base of potential new business &#8211; they&#8217;ll be able to offer their new members banking and credit card services which could be a huge selling point.  I&#8217;ve also read rumors of tax breaks but nothing firm so far.</p>
<p>I think we&#8217;ll see some other large mortgage lenders at least enter into discussions, if not get bought out, by suiters.  While the mortgage lending market doesn&#8217;t look great for most of America, it&#8217;s a prime acquisition target while prices are low.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/01/12/bank-of-america-buys-countrywide/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Email Signature Etiquette</title>
		<link>http://nathanhjones.com/2008/01/02/email-signature-etiquette/</link>
		<comments>http://nathanhjones.com/2008/01/02/email-signature-etiquette/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 22:25:17 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[etiquette]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/2008/01/02/email-signature-etiquette/</guid>
		<description><![CDATA[As I&#8217;m sure many of you do, I use email constantly at work. There are some days at work that I probably spend 50+ % of my time reading and writing emails. No, I don&#8217;t type really slow! Managing a team of off-shore developers just has it&#8217;s pro&#8217;s and con&#8217;s and one of the con&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;m sure many of you do, I use email constantly at work.  There are some days at work that I probably spend 50+ % of my time reading and writing emails.  No, I don&#8217;t type really slow!  Managing a team of off-shore developers just has it&#8217;s pro&#8217;s and con&#8217;s and one of the con&#8217;s is that 75% or more of your communication is done via email.  Since the majority of my day-to-day communication is done via email and the company I work for is stingy when it comes to email storage (a measly 150MB of storage space&#8230;really?  I get 6.25 GB in my free Gmail account&#8230;but that&#8217;s a post for another day), minimizing email size is important to me.</p>
<p>That being said, here are a few email signature etiquette tips that I think everyone can take something away from&#8230;myself included.  Yes, I&#8217;ve broken these rules before but over the past couple years I&#8217;ve refined my approach.</p>
<p>Signature Format the Nathan Jones Approach:</p>
<ul>
<li><strong>Name:</strong> I think this goes without saying but I included it for good measure.  If you want to make this bold or slightly (and I mean slightly, don&#8217;t make me regret putting this in here) larger than the rest of the signature that is definitely understandable.</li>
<li><strong>C</strong><strong>ompany/Office:</strong> Many people would make this two separate lines within the signature but I don&#8217;t see the need for it.  I think it should be combined into a single line with a separator such as a dash (-) or vertical line (|).  It looks classy and it keeps the number of lines down.</li>
<li><strong>Contact Information:</strong>
<ul>
<li>Email Address: My thoughts on this are pretty to the point &#8211; it&#8217;s ok to have your email address listed on your &#8216;new email&#8217; signature but it should not be present on your &#8216;replies&#8217; signature.  In Outlook you can create multiple signatures and assign different ones to different types of emails.  If you are replying to an email it&#8217;s a given that the person already has your email address.  If you use a mobile phone to send/receive that only allows one signature &#8211; including your email address is acceptable.</li>
<li>Phone Numbers: Where do I begin&#8230;I got an email the other day that had five different phone numbers in the signature.  My first thought is that this person has way too much time, not doing work presumably, to create this signature let alone manage five different phone numbers.  I think a signature should have at most &#8211; three.  A desk/office phone number, a mobile phone number and a fax machine number.  If you don&#8217;t have a fax then leave it off the signature and make the max two!</li>
<li>Instant Messaging Names: In today&#8217;s technology driven world I think it&#8217;s perfectly legitimate to place a <strong>single</strong> instant messaging address in your signature.  I do a lot of communicating through instant messaging and it&#8217;s a quick way for people to get in touch with me.  I&#8217;d leave it at one though &#8211; it makes sense that it be the name to the instant messaging client you use the most&#8230;but that&#8217;s obviously up to you.</li>
<li>Office Address: Unless you work in a job where clients visit your office on a regular occasion or you get a lot of mail sent to that address, I think it&#8217;s best to leave this address off your signature.  If people need it they can always ask for it.  More than likely the number of people that <strong>don&#8217;t</strong> need that address far outweigh the number of those that do.</li>
<li>Personal Websites: I think personal websites should be left off of your work email signature no matter what kind of personal website you run.  Maybe you just run a blog (similar to this one) but of course there are/will be views expressed that could ultimately upset one of your clients or co-workers and that&#8217;s a situation that no one wants to be involved in.  I think it&#8217;s fine to advertise your personal website on your personal email signature though &#8211; I do it!</li>
</ul>
</li>
<li><strong>Color:</strong> I&#8217;m pretty open to colors in email signatures &#8211; they make them unique and can call attention to certain pieces of information.  Mostly because most email editors these days will format your signature in HTML whether it needs to or not so whether you make your color bright pink (please spare me the pain) or a classic gray I don&#8217;t care either way (geek information: HTML color formats require the same amount of bytes for almost all colors).  As for how it looks &#8211; I vote you stick with a classic color such as black, dark blue, green, gray or some company color if there is one.  Personally, I would never look at your signature if it were bright pink, but that&#8217;s just me.</li>
<li><strong>Images:</strong> I don&#8217;t know how many times I have received an email with the company logo embedded in the signature but it drives me absolutely nuts.  First of all, it takes up space.  Normally it uses just a bit more space than formatted text but if you receive as many emails as me those extra bytes start to add up&#8230;quickly!  My personal thought is that <strong>an image should never be embedded in a signature</strong> unless your company mandates it.  By the way, if they do mandate an image I&#8217;d like to hear about it and whether they limit your email storage space.</li>
<li><strong>Mobile Note:</strong> If you send email from your mobile phone and have a signature set-up I think it&#8217;s a good idea to add a small note at the bottom of the signature that indicates that the email is being sent from your mobile phone.  It will take up a little space but your signature should be smaller on your phone anyways and a note like this can go a long way in explaining why sentences may be more direct or the occasional misspelled word appears.  Personally, I use &#8220;Note: This message was sent from my mobile phone.&#8221;.</li>
</ul>
<p>Well, those are just some of my thoughts on email signature etiquette.  In summary, keep it short and simple.  If you&#8217;re a sales person or someone who relies on getting your contact information seen acted upon you can still keep it short and classy and just use a different color or bolded word to get your phone number looked at.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/01/02/email-signature-etiquette/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>(Iceland + Greenland) &lt; Facebook?</title>
		<link>http://nathanhjones.com/2007/12/20/iceland-greenland-facebook/</link>
		<comments>http://nathanhjones.com/2007/12/20/iceland-greenland-facebook/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 14:54:11 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[valuations]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/2007/12/20/iceland-greenland-facebook/</guid>
		<description><![CDATA[While the post title may be somewhat misleading (and nerdy) I feel the need to discuss Facebook&#8217;s recent valuation (and here) &#8211; well the valuation it got few weeks ago. Now, I have nothing against Facebook, in fact I used to use it all the time. I don&#8217;t login nearly as much anymore but I [...]]]></description>
			<content:encoded><![CDATA[<p>While the post title may be somewhat misleading (and nerdy) I feel the need to discuss <a href="http://www.facebook.com/press/releases.php?p=8084">Facebook&#8217;s recent valuation</a> (and <a href="http://www.techcrunch.com/2007/10/24/facebook-takes-the-microsoft-money-and-runs/">here</a>) &#8211; well the valuation it got few weeks ago.  Now, I have nothing against Facebook, in fact I used to use it all the time.  I don&#8217;t login nearly as much anymore but I still maintain an account and think that it offers some very useful tools.  I&#8217;m still waiting for that hybrid LinkedIn + Facebook social network that I&#8217;m sure someone is working on but I&#8217;m ok with using them both right now.</p>
<p>Recent investments in Facebook by technology powerhouse Microsoft value the social network at a mere  $15 billion.  Microsoft invested $240 million for an estimated 1.6% stake in the company.  I know Microsoft has some extremely deep pockets and as the world moves to a more web-centric focus (online document processing, business management, personal productivity, etc) they needed to do something relatively drastic&#8230;but really?!?</p>
<p>I don&#8217;t know about you, but I consider investing in a company and ultimately giving it a valuation  greater than the combined GDP of <a href="https://www.cia.gov/library/publications/the-world-factbook/print/ic.html">Iceland</a> ($11.38 billion) and <a href="https://www.cia.gov/library/publications/the-world-factbook/print/gl.html">Greenland</a> ($1.1 billion) pretty drastic.  Of course the GDP is an annual number and Facebook doesn&#8217;t quite make $15 billion a year but the thought of it being valued that high blows my mind.  Part of that may be because I remember using the site in 2004 just after it expanded beyond just Harvard students and wasn&#8217;t anything overly impressive and &#8216;social networking&#8217; as we know it today was relatively young.</p>
<p>I understand that Facebook&#8217;s valuation still doesn&#8217;t place it in the company of the Google&#8217;s, Microsoft&#8217;s and Exxon&#8217;s of the world with market caps ranging from $210 billion to almost $500 billion, but I still think that it is just slightly over-valued.  To put things in perspective, the <a href="https://www.cia.gov/library/publications/the-world-factbook/print/gr.html">GDP of Greece</a> is $256 billion and the <a href="https://www.cia.gov/library/publications/the-world-factbook/print/sw.html">GDP of Sweden</a> is $290 billion.</p>
<p>Well that&#8217;s it for now, I just thought I&#8217;d share my thoughts.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2007/12/20/iceland-greenland-facebook/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

