<?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</title>
	<atom:link href="http://nathanhjones.com/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>Getting Started with JSON in iOS5</title>
		<link>http://nathanhjones.com/2011/11/03/getting-started-with-json-in-ios/</link>
		<comments>http://nathanhjones.com/2011/11/03/getting-started-with-json-in-ios/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 03:30:20 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[ios5]]></category>
		<category><![CDATA[iphone sdk]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=315</guid>
		<description><![CDATA[Update: This post has been cross-posted on my employers blog. JSON has taken the data-interchange world by storm with its&#8217; lightweight, easy to understand format. The explosion of mobile apps, and their consumption of network based data, helped fuel JSON&#8217;s growth. CapTech&#8217;s (my employer) recommended approach for web services utilizes JSON as the interchange format. [...]]]></description>
			<content:encoded><![CDATA[<p>
<span style="font-weight:bold">Update:</span> This post has been cross-posted on my employers <a href="http://blogs.captechconsulting.com/blog/nathan-jones/getting-started-json-ios5">blog</a>.
</p>
<p><a href="http://www.json.org/">JSON</a> has taken the data-interchange world by storm with its&#8217; lightweight, easy to understand format. The explosion of mobile apps, and their consumption of network based data, helped fuel JSON&#8217;s growth. <a href="http://blogs.captechconsulting.com/blog/jack-cox/soap-vs-rest-mobile-services" target="_blank">CapTech&#8217;s (my employer) recommended approach for web services</a> utilizes JSON as the interchange format.</p>
<p>While JSON has been around for several years &#8211; <a href="http://tools.ietf.org/html/rfc4627" target="_blank">RFC4627</a> was published in July of 2006 &#8211; working with JSON in an iOS project required that you download one of the many frameworks and integrate it into your project. My personal choice has been SBJSON &#8211; <a href="https://github.com/stig/json-framework">https://github.com/stig/json-framework</a>.</p>
<p>However, with the release of iOS5, Apple has finally included native support for reading and writing JSON with the class <a href="http://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html" target="_blank"><span style="font-weight: bold;">NSJSONSerialization</span></a>.</p>
<p>Why might you consider using the native JSON API? First and foremost, Apple delivered, Apple supported. While support for most third-party libraries is good, you can&#8217;t beat updated, built-in, backwards compatible support (for future versions of the OS) on day one of a new SDK.</p>
<p>One unfortunate con, use of NSJSONSerialization is limited to devices running iOS5. While iOS5 adoption is moving at a great pace, this still vastly limits your install base. In the case of some enterprises with field devices deployed with previous versions of the OS, this may not be an option for quite some time.</p>
<p>It&#8217;s important to note, calling any of the NSJSONSerialization methods on a device running an older version of iOS will not cause the application to crash. It simply won&#8217;t work and will continue on as if the call was never made. Obviously, there are other impacts of this, but this may fit some needs.</p>
<p>Now, let&#8217;s cover implementing the 4 read/write methods that Apple has exposed. As you can see below, using NSJSONSerialization in your projects is incredibly easy, typically requiring just a few lines of code. NSJSONSerialization supports the reading and writing of JSON data via static data or an instance of NS*Stream. The NS*Stream examples below are rudimentary, but they convey what is needed in order for NSJSONSerialization to do its&#8217; job.</p>
<h3>Parsing JSON Data</h3>
<div>
<p>The parsing methods accept an options parameter which allow you to pass different instructions to manipulate what type of foundation object you get back.</p>
<ul>
<li>NSJSONReadingAllowFragments: instructs the parser to allow top-level objects that are neither an NSArray nor NSDictionary</li>
<li>NSJSONReadingMutableContainers: instructs the parser to generate NSMutableArray and NSMutableDictionary objects</li>
<li>NSJSONReadingMutableLeaves: instructs the parser to generate NSMutableString objects</li>
</ul>
</div>
<div>
<h4>Method: JSONObjectWithData</h4>
<p>This method allows us to create a JSON object from an instance of NSData.  In this example, we&#8217;ll assume that an authentication request was successful (see below).  The first portion of the code will be to generate the mock-JSON response we received from the service.  The code will parse that response and create a foundation object.  From there, we&#8217;ll check if the object is an NSDictionary (there are a couple ways of doing this) and, if so, log the returned message and my token.</p>

<div class="wp_codebox"><table><tr id="p31519"><td class="code" id="p315code19"><pre class="objc" style="font-family:monospace;">    <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Authentication Successful&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;auth_response&quot;</span>,<span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;abc123&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;auth_token&quot;</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>writeError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>jsonData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization dataWithJSONObject<span style="color: #002200;">:</span>data options<span style="color: #002200;">:</span>NSJSONWritingPrettyPrinted error<span style="color: #002200;">:&amp;</span>amp;writeError<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// parse the JSON data into what is ultimately an NSDictionary</span>
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>parseError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #a61390;">id</span> jsonObject <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization JSONObjectWithData<span style="color: #002200;">:</span>jsonData options<span style="color: #002200;">:</span>NSJSONReadingAllowFragments error<span style="color: #002200;">:&amp;</span>amp;parseError<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// test that the object we parsed is a dictionary - perhaps you would test for something different</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>jsonObject respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>objectForKey<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><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;Response: %@&quot;</span>, <span style="color: #002200;">&#91;</span>jsonObject objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;auth_response&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Token: %@&quot;</span>, <span style="color: #002200;">&#91;</span>jsonObject objectForKey<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;">&#41;</span>;
    <span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<h4>Method: JSONObjectWithStream</h4>
<p>This method allows us to create a JSON object from an input stream. When and why to use NSInputStream is out of scope for this post. However, if you have a large chunk of JSON data you want to parse, it may be one option to explore.</p>
<p>In this example, we create an instance of NSData that contains JSON formatted tweet information. While not the recommended network communication approach, this allows us to quickly generate an NSData object for our stream.  Once the stream is up, we&#8217;ll create a foundation object from the JSON data, test that it is an NSDictionary (which we expect given the source data we&#8217;re retrieving), and then log the tweet to the console.</p>
<p>It&#8217;s important to note that an <strong>NS*Stream must be created AND configured in order for NSJSONSerialization to work properly</strong>. Once parsed, we simply log each of the tweets to the console.</p>

<div class="wp_codebox"><table><tr id="p31520"><td class="code" id="p315code20"><pre class="objc" style="font-family:monospace;">    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>tweets <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfURL<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;http://www.search.twitter.com/search.json?q=from:nathanhjones&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSInputStream</span> <span style="color: #002200;">*</span>twitterStream <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSInputStream</span> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>tweets<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>twitterStream open<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>twitterStream<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>parseError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
        <span style="color: #a61390;">id</span> jsonObject <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization JSONObjectWithStream<span style="color: #002200;">:</span>twitterStream options<span style="color: #002200;">:</span>NSJSONReadingAllowFragments error<span style="color: #002200;">:&amp;</span>amp;parseError<span style="color: #002200;">&#93;</span>;        
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>jsonObject respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>objectForKey<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>tweet <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span>jsonObject objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;results&quot;</span><span style="color: #002200;">&#93;</span><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;Tweet: %@&quot;</span>, <span style="color: #002200;">&#91;</span>tweet objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;text&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
            <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#125;</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;Failed to open stream.&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

</div>
<h3>Writing JSON Data</h3>
<div>The JSON writing methods also have an options parameter, but it&#8217;s currently limited to a single option.</p>
<ul>
<li>NSJSONWritingPrettyPrinted: instructs the writer to generate JSON with whitespace designed to make output more readable. If this option is not used, the most compact JSON possible will be generated.</li>
</ul>
<h4>Method: dataWithJSONObject</h4>
<p>This method allows us to create a JSON formatted NSData object from a foundation object &#8211; typically NSDictionary or NSArray.</p>
<p>In this example, we&#8217;ll build a dictionary of authentication credentials and then convert that to JSON as if we were posting it to an authentication service.</p>

<div class="wp_codebox"><table><tr id="p31521"><td class="code" id="p315code21"><pre class="objc" style="font-family:monospace;">    <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;test@test.com&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;user&quot;</span>,<span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;mypass&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;pass&quot;</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>jsonData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization dataWithJSONObject<span style="color: #002200;">:</span>data options<span style="color: #002200;">:</span>NSJSONWritingPrettyPrinted error<span style="color: #002200;">:&amp;</span>amp;writeError<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>jsonString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>jsonData encoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
    NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;JSON Output: %@&quot;</span>, jsonString<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<h4>Method: writeJSONObject:toStream</h4>
<p>This method allows us to write our JSON directly to an output steam. Again, when to use NSOutputStream is out of scope for this post, but it is an option. For this example, we&#8217;ll build an array of all tweet details for my last 3 tweets. We&#8217;ll then scrub that data down to 3 key pieces of information for each tweet, which we will then write to an output stream. In this case, we&#8217;ll simply write the contents to a local file.</p>

<div class="wp_codebox"><table><tr id="p31522"><td class="code" id="p315code22"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// get tweet data and convert to foundation object</span>
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>tweetData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfURL<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;http://www.search.twitter.com/search.json?q=from:nathanhjones&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>parseError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #a61390;">id</span> jsonObject <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization JSONObjectWithData<span style="color: #002200;">:</span>tweetData options<span style="color: #002200;">:</span>NSJSONReadingAllowFragments error<span style="color: #002200;">:&amp;</span>amp;parseError<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// initialize an array to hold our reformatted tweets</span>
    <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>tweets <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// check that we received a dictionary - there are 'header' objects sent by twitter</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>jsonObject respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>objectForKey<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><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;">// loop through all the actual tweets</span>
        <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>tweet <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span>jsonObject objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;results&quot;</span><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;">// create a dictionary of minimal tweet data and add to output</span>
            <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>scrubbedTweet <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
                                           <span style="color: #002200;">&#91;</span>tweet objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;id&quot;</span><span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;id&quot;</span>,
                                           <span style="color: #002200;">&#91;</span>tweet objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;created_at&quot;</span><span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;created_at&quot;</span>,
                                           <span style="color: #002200;">&#91;</span>tweet objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;text&quot;</span><span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;text&quot;</span>,
                                           <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
            <span style="color: #002200;">&#91;</span>tweets addObject<span style="color: #002200;">:</span>scrubbedTweet<span style="color: #002200;">&#93;</span>;        
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// initialize and open the stream</span>
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>documents <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span> objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@/tweets.json&quot;</span>, documents<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSOutputStream</span> <span style="color: #002200;">*</span>stream <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSOutputStream</span> alloc<span style="color: #002200;">&#93;</span> initToFileAtPath<span style="color: #002200;">:</span>path append<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>stream open<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// write JSON representation of our tweet array to file</span>
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>writeError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    NSInteger bytesWritten <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization writeJSONObject<span style="color: #002200;">:</span>tweets toStream<span style="color: #002200;">:</span>stream options<span style="color: #002200;">:</span>NSJSONWritingPrettyPrinted error<span style="color: #002200;">:&amp;</span>amp;writeError<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>bytesWritten &lt;<span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span><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;Error writing JSON Data&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>One additional method I find particularly interesting, <strong>isValidJSONObject</strong>.  An easy way to validate that the object you’ve created can be converted to JSON data.  I could be wrong, but I don’t recall any of the third-party libraries I’ve used having such a method.</p>
<p>If you’ve got questions, I’m @nathanhjones.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2011/11/03/getting-started-with-json-in-ios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Reusable UIViews with a Drop Shadow [Tutorial]</title>
		<link>http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/</link>
		<comments>http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 02:57:33 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Drop Shadow]]></category>
		<category><![CDATA[UIView]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=282</guid>
		<description><![CDATA[Update: I&#8217;ve updated the post to reflect what code requires iOS 4.0 and later.  Basically, the layer properties for the drop shadow. I&#8217;m working on an internal iPhone application for my employer.  It&#8217;s data-centric, as I&#8217;m sure most enterprise grade apps are, and as such consists mostly of UITableViews so users can view and drill [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> I&#8217;ve updated the post to reflect what code requires iOS 4.0 and later.  Basically, the layer properties for the drop shadow.</p>
<p>I&#8217;m working on an internal iPhone application for my employer.  It&#8217;s data-centric, as I&#8217;m sure most enterprise grade apps are, and as such consists mostly of UITableViews so users can view and drill into each subsequent level of detail.</p>
<p>One requirement was to have summary data points from previous screens on each view.  Nothing mind blowing that a tableHeaderView couldn&#8217;t solve.  However, a couple of these summary views would be reused and had several data points.  To complicate things, I needed a drop shadow to distinguish the header from the table (they are the same color in this particular case).</p>
<p>I decided to subclass UIView and do the layout in IB.  This kept the code clean and was a BREEZE to lay out (and change layouts as we&#8217;ve now done several times).  Unfortunately, it wasn&#8217;t as straight-forward as I originally thought.  However, with a little help from <a href="http://www.raywenderlich.com/" target="_blank">Ray Wenderlich</a>, I was able to get it implemented.  This is a quick tutorial for those out there that may be struggling with something similar.  <strong><em>The technique outlined below is only available for apps targeting iOS devices running at least 4.0.</em></strong></p>
<h3>Create the project</h3>
<p>To get started, create a view based application &#8211; I named mine <strong>ReusableTableHeaders</strong>.  Within <strong>ReusableTableHeadersViewController.h</strong>, change the parent class from UIViewController to UITableViewController and define two instance variables &#8211; <strong>tblData</strong> (UITableView) and <strong>data</strong> (NSArray).  <strong>tblData</strong> will be our table view (so remember to add IBOutlet) and <strong>data</strong> will be a simple array of information to display.  Before leaving R<strong>eusableTableHeadersViewController.h</strong>, add UITableViewDelegate and UITableViewDataSource to the interface definition.</p>
<p>Pop over to the implementation file.  The first thing I always do is synthesize and update dealloc accordingly.  This tends to save me from myself later.  Within the <strong>viewDidLoad</strong> method, fill <strong>data</strong> with some values.  I went with the oh-so-clever &#8216;Value 1&#8242;, &#8216;Value 2&#8242;, and &#8216;Value 3&#8242;.  Once complete, open up IB and we&#8217;ll set the table view up before we build and run to make sure we&#8217;re ok.</p>
<p>Within IB, delete the UIView that&#8217;s currently there and replace it with a UITableView.  Connect that to both <strong>tblData</strong> and <strong>view</strong> within the File Owner.  You&#8217;ll also want to set the File Owner as the data source and delegate.  I changed my table view style to grouped and added a background.  That&#8217;s totally your call.</p>
<p>Here&#8217;s a quick shot of what IB looks like:</p>
<p style="text-align: center;"><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-2.37.33-PM.png"><img class="aligncenter size-full wp-image-285" title="IB Connections" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-2.37.33-PM.png" alt="" width="298" height="208" /></a></p>
<p>Build and Run to make sure we&#8217;re on the same page thus far.  Here&#8217;s a quick shot of what I get.</p>
<p style="text-align: center;"><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-2.36.52-PM.png"><img class="aligncenter size-full wp-image-286" title="Build and Run - Progress so far" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-2.36.52-PM.png" alt="" width="274" height="470" /></a></p>
<h3>Subclassing UIView</h3>
<p>Now that we have the foundation in place, let&#8217;s get started on the header view.  Add a new Objective-C class to your project.  When prompted to choose your type, you&#8217;ll also want to set the subclass option to UIView.  I named my class <strong>HeaderView</strong>. We&#8217;re going to go ahead and add a nib as well.  Add a new view based nib to your project &#8211; I named mine <strong>HeaderView.xib</strong>.</p>
<p>Once your class files and nib are created, define a UILabel instance variable within the .h (mine is titled <strong>lblTitle</strong>) and set it as an outlet.  Now, hop over to the implementation file, synthesize, and update the dealloc method.  Also, be sure to include <strong>&lt;QuartzCore/QuartzCore.h&gt;</strong>.  Within the <strong>initWithFrame</strong> method, add the following code:</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.43.55-PM.png"><img class="aligncenter size-full wp-image-295" title="initWithFrame" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.43.55-PM.png" alt="" width="484" height="248" /></a></p>
<p>The code is pretty straight-forward.  The first block loads the HeaderView nib file and sets this itself equal to the loaded nib.  The second block of code handles setting the drop shadow (<strong>note: the <em>layer.shadow*</em> related code only works in iOS 4.0 and above</strong>).  Manipulating the shadow color can produce some pretty cool effects but we&#8217;ll stick with the generic black for now.  With that done, it&#8217;s time to set our nib up in IB.</p>
<h3>Setting up the view in IB</h3>
<p>Unfortunately, and I&#8217;m not sure why, you can&#8217;t alter the height of the default view when creating a view based nib.  My solution, delete the existing view and add a new one.  Set your desired dimensions &#8211; for this tutorial we go with 320 by 60.  You&#8217;ll also want to drag another UIView and UILabel into the nib as subviews.  I actually added two UILabels &#8211; a &#8216;title&#8217; label and the label I&#8217;ll update programmatically.</p>
<p>Select the top level view and open Inspector.  Set the class to your custom class &#8211; <strong>HeaderView</strong>.  While in the Inspector, set the background color clear.</p>
<p>Now select the UIView subview and change the height dimension to just slightly less than our &#8216;parent&#8217; view.  For this tutorial, I went with a difference of 5 points &#8211; 320 by 55 &#8211; and then aligned the two UIViews at the top.  Change the background color to whatever you&#8217;d like your header to be.</p>
<p>Link up one of the UILabel&#8217;s to <strong>lblTitle</strong> you defined in <strong>HeaderView.h</strong> and you should be all set.</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-9.33.58-PM.png"><img class="aligncenter size-full wp-image-306" title="IB Setup" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-9.33.58-PM.png" alt="" width="432" height="474" /></a></p>
<h3>Using the view</h3>
<p>First things first, import your custom class within <strong>ReusableTableHeadersViewController</strong>.  From here, you have several options about where to implement your custom view.  The requirement I needed to satisfy required that I use the viewWillAppear method as information could be updated as views pushed and popped.  I wanted to ensure I had the most up-to-date information presented.  For this tutorial, we&#8217;ll load it within viewDidLoad.</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.53.14-PM.png"><img class="aligncenter size-full wp-image-297" title="Using our custom view" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.53.14-PM.png" alt="" width="503" height="213" /></a></p>
<p>Walking through what we just did; we instantiate the view, set the title label, and then load it into our table view as the header.</p>
<h3>Wrapping Up</h3>
<p>And we&#8217;re done! Build and run and you should have something that resembles the screenshot below!</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.55.40-PM.png"><img class="aligncenter size-full wp-image-299" title="End result" src="http://nathanhjones.com/wp-content/uploads/2011/02/Screen-shot-2011-02-20-at-8.55.40-PM.png" alt="" width="426" height="331" /></a></p>
<p>Here&#8217;s the project files: <a href="http://nathanhjones.com/wp-content/uploads/2011/02/ReusableTableHeaders.zip" target="_blank">ReusableTableHeaders.zip</a>.</p>
<p>Well, that&#8217;s my first iOS tutorial.  Hope it helps and be sure to let me know what works and what doesn&#8217;t work in the comments.  I hope to have several more over the course of the year.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2011/02/20/creating-reusable-uiviews-with-a-drop-shadow-tutorial/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Google AdWords gets partial HTML5 makeover</title>
		<link>http://nathanhjones.com/2010/09/15/google-adwords-gets-partial-html5-makeover/</link>
		<comments>http://nathanhjones.com/2010/09/15/google-adwords-gets-partial-html5-makeover/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 03:48:55 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[adwords]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[local storage]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=279</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve posted but I saw something this evening that I thought was worth posting.  I&#8217;ve been spending a lot of my free time lately developing and promoting an iPhone app.  I&#8217;ve got a second in process so this whole process has been a great learning experience.  Part of my mobile [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve posted but I saw something this evening that I thought was worth posting.  I&#8217;ve been spending a lot of my free time lately developing and promoting an <a href="http://apptory.com" target="_self">iPhone app</a>.  I&#8217;ve got a second in process so this whole process has been a great learning experience.  Part of my mobile obsession extends to browser based apps (i.e. not App Store downloads) that utilize some of the advancements in the <a href="http://dev.w3.org/html5/spec/Overview.html">HTML5 specification </a>(I use the word &#8216;specification&#8217; loosely as I&#8217;ll include local storage, geolocation, etc under the same umbrella on this site).</p>
<p>HTML5 has it&#8217;s pro&#8217;s and con&#8217;s that each developer needs to weigh (we won&#8217;t get into that here) but <a href="http://dev.w3.org/html5/webstorage/">web storage</a> and <a href="http://dev.w3.org/html5/webdatabase/">web database</a> are great advances.  The packaged modern mobile browsers (Safari, Android browser, etc) all support the specification which allows applications to store information from within their application that persists from session to session.  It can be very powerful&#8230;but it is definitely open for exploitation.  A common example is Gmail which utilizes the storage feature (along with App Cache) to allow you to work within the Gmail web-app while you are not connected to a network.  It also speeds up the entire user experience.</p>
<p>All that being said, I logged into AdWords this evening to begin preparing my campaign for this weekend and noticed they&#8217;ve begun utilizing local storage.  The great thing about it is that they request your approval rather than doing it behind the scenes.  Given that any website can create a &#8216;database&#8217; on your local machine for storing information, I think that all user-agents (think Safari, Firefox, Chrome, etc) should force the user to authorize each use of local storage &#8211; i.e. one approval for gmail.com).</p>
<p>In short, it&#8217;s really cool that more and more sites are beginning to implement these features as browsers roll-out support but I&#8217;m more impressed that AdWords asks for permission.  I think more web-apps should follow the AdWords lead!</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2010/09/Screen-shot-2010-09-15-at-11.28.09-PM.png"><img class="aligncenter size-full wp-image-280" title="AdWords Implements HTML5 database feature" src="http://nathanhjones.com/wp-content/uploads/2010/09/Screen-shot-2010-09-15-at-11.28.09-PM.png" alt="" width="521" height="212" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2010/09/15/google-adwords-gets-partial-html5-makeover/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gone Mobile with WPtouch</title>
		<link>http://nathanhjones.com/2010/01/14/gone-mobile-with-wptouch/</link>
		<comments>http://nathanhjones.com/2010/01/14/gone-mobile-with-wptouch/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 04:06:45 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[nathanhjones.com]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wptouch]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=259</guid>
		<description><![CDATA[The other day I read Justin Levy&#8217;s post on going mobile with WPtouch and just had to experiment.  I haven&#8217;t previously had a mobile specific version so it&#8217;s definitely an exciting move. Here&#8217;s a quick round up of my experience. Installation Installation was a breeze.  WPtouch is a WordPress plugin, all it took was downloading the files, [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I read <a href="http://justinrlevy.com/2010/01/05/gone-mobile/">Justin Levy&#8217;s post on going mobile</a> with <a href="http://www.bravenewcode.com/wptouch/">WPtouch</a> and just had to experiment.  I haven&#8217;t previously had a mobile specific version so it&#8217;s definitely an exciting move. Here&#8217;s a quick round up of my experience.</p>
<h3>Installation</h3>
<p>Installation was a breeze.  WPtouch is a WordPress plugin, all it took was downloading the files, uploading it to my server and activating it from the dashboard.  Once activated we were up-and-running with the vanilla install.  Now on to customizing&#8230;</p>
<h3>Setup</h3>
<p>WPtouch offers a wide array of customizing (sorry, this is a word I&#8217;ve gotten way too used to in the SAP world) options from enabling AJAX comment posting to custom CSS/Javascript inclusion.  I kept my install fairly simple but there were a couple things I changed.</p>
<ol>
<li>I call myself a developer so I went with a snazzy App Store icon as my mobile banner image (see end of the post). WPtouch has a pretty good selection of images although they&#8217;re mostly centered around the iPhone.  If nothing meets your needs you&#8217;re more than welcome to upload a custom file.<a href="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-banner-icons.png"><img title="WPtouch-banner-icons" src="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-banner-icons.png" alt="" width="508" height="290" /></a></li>
<li>Linking of my AdSense and Analytics accounts.  Must haves&#8230;AdSense to collect those occasional pennys and Analytics to obviously to continue to understand how people flow through the site.  Adding both was EXTREMELY easy to do with a custom section for each.<a href="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-adsense-and-analytics.png"><img title="WPtouch-adsense-and-analytics" src="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-adsense-and-analytics.png" alt="" width="542" height="149" /></a></li>
</ol>
<p>WPtouch gives you the option to display a &#8216;desktop&#8217; (i.e. non-mobile) version of your website to users on their first visit and include the ability to toggle mobile vs. desktop in your theme footer.  I get the potential draw but if you&#8217;re going to go mobile, I&#8217;m not sure why you wouldn&#8217;t always default mobile and allow them to switch back if they want.</p>
<p>Anyways, you can also change what icon is used for each post and how much information about the post is shown (e.g. just the title, title and a teaser, tags, categories, etc).  I played with the settings a bit but I think that&#8217;s really more of a personal choice&#8230;at least until I get time to test and study analytic data.</p>
<h3>Additions and Suggestions</h3>
<p>For a donation supported plugin I can&#8217;t really complain.  It&#8217;s easy and relatively robust but there are still a couple things I would like to see enhanced:</p>
<ol>
<li>I understand it&#8217;s a mobile device and landscape is limited but a second &#8216;title&#8217; (under NathanHJones.com below) would be ideal.  Obviously, each blog owner would need to be smart about how it was used.</li>
<li>Better AdSense rendering.  This may be slightly out of the WPtouch developers hands but I noticed that AdSense ads show up very boxy compared to the smooth WPtouch design.  I don&#8217;t know if that&#8217;s anything they can fix or perhaps me just being new to AdSense mobile but it didn&#8217;t exactly flow together.</li>
</ol>
<p><a href="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-adsense-rendering.jpg"><img title="WPtouch-adsense-rendering" src="http://nathanhjones.com/wp-content/uploads/2010/01/WPtouch-adsense-rendering.jpg" alt="" width="230" height="133" /></a></p>
<p>If you&#8217;re mobile version is powered by WPtouch leave a comment and let me know what you think!  Finally, here&#8217;s a fullscreen shot of NathanHJones.com&#8230;the mobile version&#8230;from my iPhone.</p>
<p><a href="http://nathanhjones.com/wp-content/uploads/2010/01/nathanhjones.com-mobile.jpg"><img title="nathanhjones.com-mobile" src="http://nathanhjones.com/wp-content/uploads/2010/01/nathanhjones.com-mobile.jpg" alt="" width="224" height="336" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2010/01/14/gone-mobile-with-wptouch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Resolutions for 2010</title>
		<link>http://nathanhjones.com/2010/01/03/my-resolutions-for-2010/</link>
		<comments>http://nathanhjones.com/2010/01/03/my-resolutions-for-2010/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 23:35:10 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[communication]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[2010]]></category>
		<category><![CDATA[resolutions]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=245</guid>
		<description><![CDATA[I&#8217;ve been kicking around the idea of publishing my personal resolutions for 2010 for a couple weeks and just decided to pull the trigger.  My thoughts, what better way of pushing myself to follow through than to publish them on the web for all to see.  I&#8217;ll try to take a couple checkpoints throughout the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been kicking around the idea of publishing my personal resolutions for 2010 for a couple weeks and just decided to pull the trigger.  My thoughts, what better way of pushing myself to follow through than to publish them on the web for all to see.  I&#8217;ll try to take a couple checkpoints throughout the year to let you know how I&#8217;m progressing.</p>
<p>So, without further ado, here are my resolutions for 2010:</p>
<ol>
<li>Develop and iPhone app.  I have a few ideas but I won&#8217;t reveal those just yet.  Look out for the announcement when the app is ready though <img src='http://nathanhjones.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Blog more &#8211; 3-4 times per month is my target.  I plan on blogging about my iPhone development experience as well as about some topics I&#8217;ve been hoarding from my day job on implementing SAP SRM 7.0.</li>
<li>Clean up my resume and create a web-ready version (linked on this blog obviously).</li>
<li>Develop a new website &#8211; I suspect this will likely be to complement the iPhone app but I would like to build a custom WordPress theme for <a href="http://nathanhjones.com">nathanhjones.com</a>.</li>
<li>Reach 500 followers and 1,500 tweets on <a href="http://twitter.com/nathanhjones" target="_blank">Twitter</a>.  I hover between 140 and 150 followers and just hit 600 tweets today.</li>
<li>Exercise more &#8211; 4-5 times per week.  Throughout the last couple years I have been working out 2-4 times a week but I would like to raise the bar a bit at 4 to 5 times to help get in better shape and shed a few pounds.</li>
<li>Lower my golf score.  Notice I didn&#8217;t say handicap there <img src='http://nathanhjones.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  Over the last few years I&#8217;ve only been able to play a couple times a year because work has consumed so much of my time.  My goal for 2010 is to play more and get my average score consistently in the 90&#8242;s (high 90&#8242;s is ok by me for this year).</li>
</ol>
<p>I wanted to list 10 (for some reason that sounded like such a nice, even number) but this is all I could muster today.  If I manage to achieve all of this with time to spare in 2010 (unlikely, unless you find me a new job)&#8230;I&#8217;ll add a couple more.</p>
<p>By the way, how does everyone feel about the fact that years will now almost always be prefaced with &#8216;twenty&#8217; instead of &#8216;two-thousand&#8217;?!?</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2010/01/03/my-resolutions-for-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2009 by the Numbers</title>
		<link>http://nathanhjones.com/2010/01/03/2009-by-the-numbers/</link>
		<comments>http://nathanhjones.com/2010/01/03/2009-by-the-numbers/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 22:35:53 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[travel]]></category>
		<category><![CDATA[airplanes]]></category>
		<category><![CDATA[hotels]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=239</guid>
		<description><![CDATA[Well, 2009 has come to an end.  With that, I&#8217;m publishing my third annual &#8216;by the Numbers&#8217; (here is 2007 and 2008) post that chronicles my travels.  Most travel is for business but there were a couple personal trips that made the list. So, in 2009 I… Flew 7,482 miles (I&#8217;m happy to say I didn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Well, 2009 has come to an end.  With that, I&#8217;m publishing my third annual &#8216;by the Numbers&#8217; (here is <a href="http://nathanhjones.com/2008/01/03/2007-by-the-numbers/">2007</a> and <a href="http://nathanhjones.com/2009/02/01/2008-by-the-numbers/">2008</a>) post that chronicles my travels.  Most travel is for business but there were a couple personal trips that made the list.</p>
<p>So, in 2009 I…</p>
<ul>
<li>Flew 7,482 miles (I&#8217;m happy to say I didn&#8217;t have many bad airport experiences this year!)</li>
<li>Traveled through 5 airports (RIC, IAD, PHL, ORD, AUA) &#8211; PHL is still a nightmare</li>
<li>Stayed 133 nights in hotels</li>
<li>Stayed 3 nights in a corporate apartment</li>
<li>Rented 1 car &#8211; Hertz still has a questionable selection</li>
<li>Drove 8,505 miles &#8211; DC and back&#8230;a lot</li>
<li>Visited 3 states (NC, IL, PA) other than VA. Oh, and one island &#8211; Aruba!!</li>
</ul>
<p>It looks like my travel for at least the first half of 2010 will be on par with 2009.  We&#8217;ll see what the new year brings though!!</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2010/01/03/2009-by-the-numbers/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>2008 by the Numbers</title>
		<link>http://nathanhjones.com/2009/02/01/2008-by-the-numbers/</link>
		<comments>http://nathanhjones.com/2009/02/01/2008-by-the-numbers/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 17:48:11 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[travel]]></category>
		<category><![CDATA[2008 numbers]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=70</guid>
		<description><![CDATA[Well, we&#8217;ve wrapped on another year and in keeping with what I started last year I&#8217;d like to do a rundown of all the travel I got to do &#8211; mostly work but some pleasure. So, in 2008 I&#8230; Flew 70,000 miles (let&#8217;s not discuss how many canceled/delayed flights) Traveled through 10 airports (RIC, CLT, [...]]]></description>
			<content:encoded><![CDATA[<p>Well, we&#8217;ve wrapped on another year and in <a href="http://nathanhjones.com/2008/01/03/2007-by-the-numbers/">keeping with what I started last year</a> I&#8217;d like to do a rundown of all the travel I got to do &#8211; mostly work but some pleasure.</p>
<p>So, in 2008 I&#8230;</p>
<ul>
<li>Flew 70,000 miles (let&#8217;s not discuss how many canceled/delayed flights)</li>
<li>Traveled through 10 airports (RIC, CLT, IAD, PHL, ORD, SEA, BDL, SFO, BOS, DFW)</li>
<li>Stayed 123 nights in hotels</li>
<li>Rented 38 cars (comment still holds true about Aveo &#8211; I like the Mazda 6)</li>
<li>Visited 8 states (WA, NC, MA, CT, CA, IL, TX, PA) other than VA</li>
<li>I also stayed in a corporate apartment for 15 nights of 2008</li>
</ul>
<p>It looks like my travel for 2009 will be quite a bit less.  I&#8217;ve taken a project that will have me only a couple hours drive from home.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2009/02/01/2008-by-the-numbers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GrandCentral Forgot to Renew Their Certificate</title>
		<link>http://nathanhjones.com/2009/01/26/grandcentral-forgot-to-renew-their-certificate/</link>
		<comments>http://nathanhjones.com/2009/01/26/grandcentral-forgot-to-renew-their-certificate/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 15:52:45 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[grandcentral]]></category>
		<category><![CDATA[security certificates]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=204</guid>
		<description><![CDATA[It seems GrandCentral, the Google owned phone number consolidation service, has failed to renew their security certificate.  According to the Firefox connection message displayed when I tried to login, the certificate expired yesterday afternoon.  Maybe they renewed it but the configuration hasn&#8217;t hit the server yet?!? January appears to be a rough month for the [...]]]></description>
			<content:encoded><![CDATA[<p>It seems GrandCentral, the Google owned phone number consolidation service, has failed to renew their security certificate.  According to the Firefox connection message displayed when I tried to login, the certificate expired yesterday afternoon.  Maybe they renewed it but the configuration hasn&#8217;t hit the server yet?!?</p>
<div id="attachment_205" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2009/01/grand-central-certificate-expiration.png"><img class="size-full wp-image-205" title="grand-central-certificate-expiration" src="http://nathanhjones.com/wp-content/uploads/2009/01/grand-central-certificate-expiration.png" alt="GrandCentral Certificate Expires" width="500" height="270" /></a><p class="wp-caption-text">GrandCentral Certificate Expires</p></div>
<p>January appears to be a rough month for the internet behemoth.  Last January, around the same time (January 23rd actually), someone at <a href="http://www.techcrunch.com/2007/01/23/google-forgets-to-renew-googlede-site-goes-down/">Google failed to renew the Google.de domain</a> which brought it down for several hours after someone else registered it.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2009/01/26/grandcentral-forgot-to-renew-their-certificate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guaranteed Money</title>
		<link>http://nathanhjones.com/2009/01/24/guaranteed-money/</link>
		<comments>http://nathanhjones.com/2009/01/24/guaranteed-money/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 19:53:42 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[personal finance]]></category>
		<category><![CDATA[annuity]]></category>
		<category><![CDATA[certificate of deposit]]></category>
		<category><![CDATA[index fund]]></category>
		<category><![CDATA[investments]]></category>
		<category><![CDATA[money magazine]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=196</guid>
		<description><![CDATA[Ok, so the title may be a little misleading but let me explain.  I was reading February&#8217;s issue of Money magazine and it has a great article by The Mole titled &#8220;A Guarantee, Without High Fees&#8221; that essentially outlines how to create your own equity-indexed-ish annuity (ish meaning like).  Of course, this method doesn&#8217;t come [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, so the title may be a little misleading but let me explain.  I was reading February&#8217;s issue of Money magazine and it has a great article by The Mole titled &#8220;A Guarantee, Without High Fees&#8221; that essentially outlines how to create your own equity-indexed-<em>ish</em> annuity (<em>ish</em> meaning like).  Of course, this method doesn&#8217;t come with the annuity&#8217;s annual fees or surrender charges if you pull out early.  However, you should know that you will face some penalties for the CD portion of your investment if you withdraw it early.</p>
<p>Not sure what an Equity-Indexed Annuity is?  Check out this <a id="q1sp" title="description from the Securities and Exchange Commission" href="http://www.sec.gov/investor/pubs/equityidxannuity.htm">description from the Securities and Exchange Commission</a>:</p>
<p style="margin-left: 40px;"><span style="font-size: x-small; font-family: Verdana,Arial,Helvetica;">An equity-indexed annuity is a special type of contract between you and an insurance company. During the accumulation period – when you make either a lump sum payment or a series of payments – the insurance company credits you with a return that is based on changes in an equity <a href="http://www.sec.gov/answers/indices.htm">index</a>, such as the S&amp;P 500 Composite Stock Price Index. The insurance company typically guarantees a minimum return. Guaranteed minimum return rates vary. After the accumulation period, the insurance company will make periodic payments to you under the terms of your contract, unless you choose to receive your contract value in a lump sum. </span></p>
<p>Now that we&#8217;ve got that taken care of let&#8217;s get into things.  We&#8217;re going to be splitting our investment dollars between a Certificate of Deposit (CD) and a stock market index fund.  I&#8217;ll leave the fund decision up to you but you want to make sure it&#8217;s low cost.  Keep in mind that purchasing through your IRA gives you the benefit of a tax break.</p>
<p>For all three scenarios, we&#8217;ll assume that we have a 10-year investment timeline with an initial investment amount of $10,000.</p>
<p>After some searching around the internet I found a 10-year Capital One CD that was yielding 4.25%.  Not a bad rate given the current economic climate but see my note below &#8211; toward the end of the post.  For the index fund portion of our investment we&#8217;re going to assume an annual 6% return.  I know last years tremendous losses may have you laughing at that assumption but keep in mind we&#8217;re investing long-term and investors typically make back the <a id="ras." title="bulk of their bear market losses in the first year" href="http://www.kiplinger.com/columns/picks/archive/2008/pick1216.htm">bulk of their bear market losses in the first year</a> of a bull market.  I&#8217;m no economist, but I don&#8217;t see the current financial crisis lasting through our 10-year example.</p>
<p><strong>Scenario 1:</strong></p>
<p><strong></strong> We&#8217;re risk averse and want to insure that we have, at the very least, our initial $10,000 when we&#8217;re done.  For those of you that are reading along at home, this is the same scenario that Money walks through.  I&#8217;m just using more recent yields and including a couple additional scenarios.</p>
<p>Here&#8217;s our game plan &#8211; invest $6,600 in the CD and $3,400 in our index fund.  To determine how much we need to invest in our CD today to guarantee our target minimum is met we run a present-value calculation.  Money recommends the calculators at moneychimp.com which I hadn&#8217;t used before today but they&#8217;re actually pretty good (here&#8217;s a <a id="sykx" title="direct link" href="http://moneychimp.com/calculator/present_value_calculator.htm">direct link</a> &#8211; bypass homepage).</p>
<p>In 10 years, provided the index fund we chose hasn&#8217;t lost 100% we&#8217;ll have somewhere north of the $10,000 we started with.  If the fund doesn&#8217;t increase or decrease at all we&#8217;ll have roughly $13,400 (CD + initial index fund value) and if it achieves the 6% annual return we assumed we&#8217;ll have about $16,000.  It doesn&#8217;t make us the next Warren Buffett but not bad for minimizing our potential loss.</p>
<p><strong>Scenario 2:</strong></p>
<p>In this scenario we&#8217;re going to continue with the risk averse theme but make sure we earn something for our time.  We want a guaranteed payout of <strong>$12,000</strong>.  We have to have some growth otherwise it&#8217;s just not worth the effort.</p>
<p>The higher guarantee means that we have to put more in our CD which means less in our index fund.  Less money at a higher yield (6% versus 4.25%) means lower potential on the upside.  I think you may be surprised how little the difference is though.  Here are the numbers&#8230;</p>
<p>Stash $7,950 in our CD and toss the remaining $2,050 into the index fund.</p>
<p>If our fund loses everything we still walk away with $12,000 in 10 years.  If the fund doesn&#8217;t do anything we&#8217;re going to get $14,050 back which is a few hundred more bucks than in the previous scenario.  However, as I said earlier, we&#8217;ve got less money earning a potentially higher yield.  This means our potential take away if our 6% annual return is met is $15,650&#8230;a few hundred bucks <strong>less</strong> than in the Scenario 1.</p>
<p><strong>Scenario 3:</strong></p>
<p>Last one, I promise!</p>
<p>We&#8217;re young, we know it and we&#8217;ve got plenty of time to make up some losses so we&#8217;re more willing to take on some risk.  Let&#8217;s say we&#8217;re willing to take a potential loss of $2,000 in search of a higher payday.</p>
<p>In order to guarantee our $8,000 we throw $5,300 in our CD and $4,700 in our index fund.</p>
<p>We now have $8,000 guaranteed but we&#8217;re in an index fund so the chance of it losing 100% is slim.  If our fund doesn&#8217;t do jack over the next 10 years we&#8217;ll come clean with around $12,700.  But, if our index fund returns 6% like we&#8217;re hoping, we take $16,400 straight to the bank (read: to another investment opportunity).</p>
<p>It&#8217;s only a few hundred bucks more than our previous examples so is it worth the added risk?  Well, that&#8217;s up to you and your personal investment style.  Investments by nature are risky but they&#8217;re a necessary evil if you want to build that nest-egg.  You should sit down with your financial advisor and decide what works best for your situation.  On a somewhat related rant, I&#8217;m against all financial advisor&#8217;s unless they charge a flat fee &#8211; typically hourly.  I think advisor&#8217;s that make commission on sales is a recipe for disaster.</p>
<p>One thing to keep in mind is that the CDs I discuss in this post are fixed yields which means if interest rates go up, you&#8217;re stuck earning a 4.25% yield until maturity.  There are techniques you can employ such as staggering CD purchases but they carry risks of their own.  For example, rates could go down which means future CD purchases could drop you below your target guaranteed minimum.  They do have some benefits though, if interest rates go up you could achieve a higher guaranteed minimum and it also allows you to maintain a certain threshold of liquidity.</p>
<p>I couldn&#8217;t find the article on <a id="wut_" title="Money's website" href="http://money.cnn.com/">Money&#8217;s website</a> but I&#8217;ll try to keep my eyes peeled so that I can link to it.  If you happen to have the February issue on hand&#8230;it&#8217;s on page 35.  It really was a very interesting article.</p>
<p><span style="font-size: xx-small;"><strong>Disclaimer:</strong> I am not a financial advisor and offer no warranty &#8211; implicit or explicit &#8211; to the investment approaches or thoughts outlined in this, or any other post on NathanHJones.com.  I am simply expanding on thoughts, experimenting with numbers and generally thinking outloud.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2009/01/24/guaranteed-money/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using GMail filters to make company email addresses intelligent [Google Apps]</title>
		<link>http://nathanhjones.com/2008/10/16/using-gmail-filters-to-make-company-email-addresses-intelligent-google-apps/</link>
		<comments>http://nathanhjones.com/2008/10/16/using-gmail-filters-to-make-company-email-addresses-intelligent-google-apps/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 02:33:50 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[community email address]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google apps]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=168</guid>
		<description><![CDATA[Many online businesses provide generic email addresses on their &#8216;contact us&#8217; page for their customers to use &#8211; sales@, admin@, press@, etc.  While they may be easy to set up they can become difficult to manage which is why including a little business logic may help ease the pain.  If you&#8217;re using Google Apps to [...]]]></description>
			<content:encoded><![CDATA[<p>Many online businesses provide generic email addresses on their &#8216;contact us&#8217; page for their customers to use &#8211; sales@, admin@, press@, etc.  While they may be easy to set up they can become difficult to manage which is why including a little business logic may help ease the pain.  If you&#8217;re using Google Apps to run your back-end office operations you&#8217;re in luck.  We&#8217;re profiling how to set up those generic email addresses with a little workflow to make those in to dollar producing assets.</p>
<h3>The Setup:</h3>
<p>For the purposes of this post, I&#8217;ve created a generic &#8216;sales&#8217; address and an address for a fake employee &#8211; Johnny.  Johnny is so good, I want my big-dollar product leads going straight to him for quick conversion.  Every sales organization is structured differently, but we&#8217;re working under the assumption that our sales reps are product and territory based.  Our high-dollar product lines are the XY9500 and the YZ9900.  Johnny handles sales for MD, DC, VA, TN, NC, SC and GA.</p>
<h3>The Approach:</h3>
<p>GMail has a very <a href="https://mail.google.com/support/bin/answer.py?answer=7190">advanced set of search operators</a> built-in that happen to work with filters when included in the &#8216;Has The Words:&#8217; text box during filter creation.  We&#8217;re going to create a set of filters in the &#8216;sales&#8217; inbox that will forward matching emails to the appropriate sales rep, label the message as &#8216;forwarded&#8217; and then archive it.  Labeling and archiving the email keeps the inbox clean so that the generic address &#8216;manager&#8217; only has to review and react to those messages that our logic doesn&#8217;t recognize.</p>
<h3>The Execution:</h3>
<p>Here is an email from a potential customer that found us on the web.  They&#8217;re interested in setting up a contract to purchase 100 of our XY9500 products.</p>
<blockquote><p>Dear Sales Team:</p>
<p>My name is Phil and I&#8217;m the purchaser for Acme Associates based in Washington, DC.  We are in the market for 100 of your XY9500 products and would like to speak with a sales associate to obtain some additional information.</p>
<p>The best way to get in touch with me is via email or at 123-123-1234.</p>
<p>Thank you,</p>
<p>Phil</p>
<p>Acme Associates</p>
<p>Washington, DC 12345</p></blockquote>
<p>For the state determination we&#8217;re relying on the fact that people use a full signature with the address.  You could also include area/zip code in an &#8216;or&#8217; condition.  You can create another filter for just products that goes to an individual to distribute accordingly or to a distribution list of all the reps that handle that product.  Google Apps allows you to easily create distribution lists.</p>
<p>Within the &#8216;sales&#8217; email account enter the &#8216;settings&#8217; and create a new filter.  We&#8217;re going to leave everything but the &#8216;Has the words:&#8217; field blank.  If you&#8217;re using a web form to capture the data you may be able to use the &#8216;subject&#8217; field but I think it&#8217;s a little more robust and easier to maintain if it&#8217;s all in one field.  One of the more important aspects of the operators to understand is that parenthesis &#8220;( )&#8221; equate to &#8216;AND&#8217; and brackets &#8220;{ }&#8221; equate to &#8216;OR&#8217;.</p>
<p>The filter rule we&#8217;re going to use is: &#8220;({XY9500 YZ9900} {MD DC VA TN NC SC GA})&#8221;  This means that the email has to <strong>contain both</strong> a product of XY9500 or YZ9900 <strong>and</strong> a state of MD, DC, VA, TN, NC, SC or GA.  If it passes our filter, we&#8217;ll send it to Johnny, mark it as &#8216;forwarded&#8217; and archive the email.  You could expand the list of states to include area codes since most people include at least one phone number in their signature.</p>
<div id="attachment_183" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filter-create-step-1.jpg"><img class="size-full wp-image-183" title="google-apps-filter-create-step-1" src="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filter-create-step-1.jpg" alt="Step 1" width="500" height="202" /></a><p class="wp-caption-text">Step 1</p></div>
<div id="attachment_184" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filter-create-step-2.jpg"><img class="size-full wp-image-184" title="google-apps-filter-create-step-2" src="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filter-create-step-2.jpg" alt="Step 2" width="500" height="208" /></a><p class="wp-caption-text">Step 2</p></div>
<p>Once you come up with a filter you want to use, test it by emailing yourself a few emails and entering the filter in the search field.  You know your customers best and if the email is caught (either included or excluded) as you expected then you should be good to go.  Here are a couple screenshots of the search &#8211; one note, the search feature will highlight pieces of the email that fit your criteria.</p>
<div id="attachment_188" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filters-search-results-1.jpg"><img class="size-full wp-image-188" title="google-apps-filters-search-results-1" src="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filters-search-results-1.jpg" alt="Search results from Sales inbox" width="500" height="130" /></a><p class="wp-caption-text">Search results from Sales inbox</p></div>
<div id="attachment_189" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filters-search-results-2.jpg"><img class="size-full wp-image-189" title="google-apps-filters-search-results-2" src="http://nathanhjones.com/wp-content/uploads/2008/10/google-apps-filters-search-results-2.jpg" alt="Email with highlighted search results" width="500" height="187" /></a><p class="wp-caption-text">Email with highlighted search results</p></div>
<p><strong>The Debrief:</strong></p>
<p>While this is in no way an exhaustive list of the advanced search operators, I think it is a good introduction and should get you started.  From a maintenance perspective, it would be best to create one filter per employee (sales person, PR agent, etc) so that in the unlikely event that they leave, you only need to adjust the forwarding email in one label to the interim employee.</p>
<p>If your website uses a contact form that potential customers fill out you have a little more opportunity for drilling into the data.  If you know how the data will be formatted when it hits your inbox that allows you to create more advanced filters and get things to exactly the right employee.  Maybe, your contact form has a &#8216;budget&#8217; field with preset amounts and anything over a certain dollar figure gets sent to an urgent-response team.  There are so many applications for the search operators that spending some time to familiarize yourself with them will pay off in the long run.</p>
<p>One thing to experiment with is the &#8216;exclusion&#8217; operator.  If you include the &#8220;-&#8221; symbol before one of your clauses it excludes items that meet that statement.  For example, if your filter criteria was &#8220;({XY9500 YZ9900} -{MD DC VA TN NC SC GA})&#8221; and you used the email above, your search results would return 0 results because it contains &#8216;DC&#8217;.</p>
<p>Don&#8217;t forget to have the office manager login and check those inboxes and forward those leads to the appropriate person.</p>
<p>If you have some other ideas that you use to make things easier, let me know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/10/16/using-gmail-filters-to-make-company-email-addresses-intelligent-google-apps/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>No Built-in XML support for Google Chrome</title>
		<link>http://nathanhjones.com/2008/10/15/no-built-in-xml-support-for-google-chrome/</link>
		<comments>http://nathanhjones.com/2008/10/15/no-built-in-xml-support-for-google-chrome/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 13:11:36 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[FF]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[google chrome]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[internet explorer]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=160</guid>
		<description><![CDATA[For anyone that reads this regularly, you know I&#8217;m a pretty big fan of Google products.  So, when they announced the launch of Chrome, their web browser, I was quick to install and start browsing with it.  It has since become my default browser (other than when testing webpage rendering) on both my personal and [...]]]></description>
			<content:encoded><![CDATA[<p>For anyone that reads this regularly, you know I&#8217;m a pretty big fan of Google products.  So, when they announced the <a href="http://www.google.com/chrome/intl/en/features.html">launch of Chrome</a>, their web browser, I was quick to install and start browsing with it.  It has since become my default browser (other than when testing webpage rendering) on both my personal and business computers.</p>
<p>Chrome got rid of the &#8216;fat&#8217; around the browser giving me the tools/options I use the most and increasing my viewing area.  Another great feature is the fact that each tab runs independently so if one crashes it doesn&#8217;t destroy your entire browser session.  Just that one tab!  One thing I do wish they had though, ALT+F+C/X to close a tab.  However, that&#8217;s a discussion for another day.</p>
<p>Anyways, I&#8217;ve been using Chrome extensively the last few weeks and was disappointed when I discovered that there doesn&#8217;t appear to be any built-in XML/RSS rendering support.  I already use Google Reader so I&#8217;m not looking for an IE approach (feed in the browser &#8211; I don&#8217;t even use the browser), but something similar to Firefox would be nice if I happen to land on a page that is XML/RSS.  Not only does it not offer a way for me to subscribe to the document, it just displays raw text.  Here are some screenshots for comparison.</p>
<p>I&#8217;m disappointed but I&#8217;ll continue use Chrome.  It just makes it more difficult to subscribe to things than it was with Firefox.</p>
<div id="attachment_162" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/google-chrome-native-rss.jpg"><img class="size-full wp-image-162" title="google-chrome-native-rss" src="http://nathanhjones.com/wp-content/uploads/2008/10/google-chrome-native-rss.jpg" alt="RSS feed in Google Chrome" width="500" height="198" /></a><p class="wp-caption-text">RSS feed in Google Chrome</p></div>
<div id="attachment_163" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/ff-native-rss-support.jpg"><img class="size-full wp-image-163" title="ff-native-rss-support" src="http://nathanhjones.com/wp-content/uploads/2008/10/ff-native-rss-support.jpg" alt="RSS feed in Firefox" width="500" height="229" /></a><p class="wp-caption-text">RSS feed in Firefox</p></div>
<div id="attachment_164" class="wp-caption aligncenter" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/ie7-native-rss-support.jpg"><img class="size-full wp-image-164" title="ie7-native-rss-support" src="http://nathanhjones.com/wp-content/uploads/2008/10/ie7-native-rss-support.jpg" alt="RSS feed in IE7" width="500" height="251" /></a><p class="wp-caption-text">RSS feed in IE7</p></div>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/10/15/no-built-in-xml-support-for-google-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ThemeForest Disables Deposit Hack</title>
		<link>http://nathanhjones.com/2008/10/14/themeforest-disables-deposit-hack/</link>
		<comments>http://nathanhjones.com/2008/10/14/themeforest-disables-deposit-hack/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 12:14:05 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[Theme Forest]]></category>

		<guid isPermaLink="false">http://nathanhjones.com/?p=154</guid>
		<description><![CDATA[A couple weeks ago I wrote a post about how to deposit a specific amount into your ThemeForest account so you didn&#8217;t forfeit monies that weren&#8217;t spent.  An Envato employee and I exchanged a couple comments and it appears that they&#8217;ve disabled the hack. I must give them credit for at least modifying the pre-set [...]]]></description>
			<content:encoded><![CDATA[<p>A couple weeks ago I wrote a post about <a href="http://nathanhjones.com/2008/10/04/themeforestnet-review-custom-deposit-amount-hack/">how to deposit a specific amount into your ThemeForest account</a> so you didn&#8217;t forfeit monies that weren&#8217;t spent.  An Envato employee and I exchanged a couple comments and it appears that they&#8217;ve disabled the hack.</p>
<div id="attachment_156" class="wp-caption alignnone" style="width: 510px"><a href="http://nathanhjones.com/wp-content/uploads/2008/10/themeforest-disables-deposit-hack.jpg"><img class="size-full wp-image-156" title="themeforest-disables-deposit-hack" src="http://nathanhjones.com/wp-content/uploads/2008/10/themeforest-disables-deposit-hack.jpg" alt="ThemeForest Deposit Hack Shutdown" width="500" height="244" /></a><p class="wp-caption-text">ThemeForest Deposit Hack Shutdown</p></div>
<p>I must give them credit for at least modifying the pre-set amounts on the deposit page &#8211; now they&#8217;re in increments of $10 instead of $20.  Sadly, the lowest amount still starts at $20 and doesn&#8217;t really keep you from wasting, say, $8 on that $12 theme you want to purchase.  Keep in mind though, allegedly, if you email customer service they&#8217;ll extend your forfeit period beyond the stated one year.</p>
<p>I ran through the hack for a several different amounts but it appears everything is down.  Looks like a little validations before submitting to PayPal goes a long way.</p>
<p>In my comments I noted that I&#8217;d probably be back when I need another theme&#8230;I&#8217;m going to go ahead and retract that until this process is fixed.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathanhjones.com/2008/10/14/themeforest-disables-deposit-hack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

