<?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>Peter Friese &#187; iPhone</title>
	<atom:link href="http://www.peterfriese.de/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.peterfriese.de</link>
	<description>mobile / model-driven</description>
	<lastBuildDate>Mon, 14 Nov 2011 16:14:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>The Accounts and Twitter Framework on iOS 5</title>
		<link>http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/</link>
		<comments>http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 21:30:46 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ios5]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=850</guid>
		<description><![CDATA[Adding Twitter support is something that makes quite a lot of sense for a number of applications. If you're in a news reader application you might want to let your followers know about an interesting article you just read. If you're in a conference schedule app, you not only want to let your followers know [...]]]></description>
			<content:encoded><![CDATA[<p>Adding Twitter support is something that makes quite a lot of sense for a number of applications. If you're in a news reader application you might want to let your followers know about an interesting article you just read. If you're in a conference schedule app, you not only want to let your followers know about the awesome talks you're listening to but you also might want to know which other talks other conference attendees are tweeting about to decide whether they are actually even more awesome than that talk you're stuck in...<br />
<span id="more-850"></span><br />
Starting with iOS 5, Apple has introduced an <a href="http://developer.apple.com/library/ios/#documentation/Twitter/Reference/TwitterFrameworkReference/_index.html">official API for accessing Twitter from your iOS</a> applications. Before iOS 5, integrating Twitter in your apps was a rather cumbersome experience which required us developers to jump through many hoops.</p>
<p>In this post I want to outline the most important features of the iOS Twitter and Accounts APIs and explain how to use them to write a decent Twitter client for your next app in very few lines of code. The <a href="http://github.com/peterfriese/TwitterClient">full source code</a> is available on Github for your convenience.</p>
<p>The Accounts and Twitter frameworks perform much of the heavy lifting required when talking to Twitter, such as</p>
<ul>
<li>Providing a secure local storage for user accounts, including their credentials</li>
<li>Providing an easy way to sign API requests you send to Twitter. You no longer have to include code to handle <a href="https://dev.twitter.com/docs/auth/oauth/faq">OAuth</a> or <a href="https://dev.twitter.com/docs/oauth/xauth">xAuth</a> in your app - this has all been done by Apple for you</li>
<li>Providing a basic UI for composing tweets, including switching the user account you tweet from, uploading images in a tweet and including your current location</li>
</ul>
<p>Lots of free stuff, so let's have a look at how much (or little) code we actually need to write to tap this source of awesomeness.</p>
<h2>Using the Accounts Framework to fetch the list of accounts</h2>
<p>The <a href="http://developer.apple.com/library/ios/#documentation/Accounts/Reference/AccountsFrameworkRef/_index.html">Accounts Framework</a> provides access to all Twitter accounts the user has added to their iPhone using the settings app. Currently, the Accounts Framework only supports Twitter accounts, but you'll soon realize it has been build so that it basically can be used to access any other kind of account in future releases. Maybe the next version of iOS will easy access to Google+ and Facebook accounts -  we'll see.</p>
<p>To use the Accounts and Twitter frameworks, we need to add them to the project:</p>
<div id="attachment_878" class="wp-caption aligncenter" style="width: 510px"><a class="lightbox"  title ="Add Accounts and Twitter frameworks to the project" href="http://www.peterfriese.de/wp-content/AddTwitterAccounts.png"><img src="http://www.peterfriese.de/wp-content/AddTwitterAccounts.png" alt="Add Accounts and Twitter frameworks to the project" title="Add Accounts and Twitter frameworks to the project" width="500" height="203" class="size-full wp-image-878" /></a><p class="wp-caption-text">Add Accounts and Twitter frameworks to the project</p></div>
<p>Once that's done, we can use the Accounts framework to fetch the list of Twitter accounts on the device.</p>
<pre class="objc">- <span style="color: #002200;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #002200;">&#41;</span>fetchData
<span style="color: #002200;">&#123;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #002200;">&#40;</span>_accounts == <span style="color: #0000ff;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #002200;">&#40;</span>_accountStore == <span style="color: #0000ff;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      self.accountStore = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ACAccountStore alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
    ACAccountType *accountTypeTwitter =
      <span style="color: #002200;">&#91;</span>self.accountStore
        accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>self.accountStore requestAccessToAccountsWithType:accountTypeTwitter
      withCompletionHandler:^<span style="color: #002200;">&#40;</span><span style="color: #0000ff;">BOOL</span> granted, <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSError.html"><span style="color: #0000ff;">NSError</span></a> *error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #0000ff;">if</span><span style="color: #002200;">&#40;</span>granted<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        dispatch_sync<span style="color: #002200;">&#40;</span>dispatch_get_main_queue<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, ^<span style="color: #002200;">&#123;</span>
          self.accounts = <span style="color: #002200;">&#91;</span>self.accountStore
            accountsWithAccountType:accountTypeTwitter<span style="color: #002200;">&#93;</span>;
          <span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
      <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
<p>As many other new APIs that perform potentially blocking I/O, the Accounts framework uses blocks to execute your code as soon as the data you requested is available. When querying the accounts database, we can specify the kind of accounts we're interested in - <code>ACAccountTypeIdentifierTwitter</code> in our case. If we're granted access to the accounts database, we fetch the list of accounts using <code>accountsWithAccountType:</code>. As soon as we've got this list, we want to save it in a ivar / property and update the UI. Since there is no guarantee we're on the UI thread when our completion handler is run, we use <code>dispatch_sync</code> to ensure assigning the list of accounts and updating the UI is run on the UI thread (<code>dispatch_get_main_queue()</code> returns the GCD queue of the UI thread). For more information on blocks and Grand Central Dispatch (GCD) check out <a href="http://www.mikeash.com/pyblog/friday-qa-2009-08-28-intro-to-grand-central-dispatch-part-i-basics-and-dispatch-queues.html">this excellent blog post</a>. </p>
<p>Displaying the accounts in a <code>UITableViewController</code> is straightforward:</p>
<pre class="objc">- <span style="color: #002200;">&#40;</span>UITableViewCell *<span style="color: #002200;">&#41;</span>tableView:<span style="color: #002200;">&#40;</span>UITableView *<span style="color: #002200;">&#41;</span>tableView
                          cellForRowAtIndexPath:<span style="color: #002200;">&#40;</span>NSIndexPath *<span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
  <span style="color: #0000ff;">static</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSString.html"><span style="color: #0000ff;">NSString</span></a> *CellIdent = @<span style="color: #666666;">&quot;Cell&quot;</span>;
&nbsp;
  UITableViewCell *cell = <span style="color: #002200;">&#91;</span>tableView dequeueReusableCellWithIdentifier:CellIdent<span style="color: #002200;">&#93;</span>;
  <span style="color: #0000ff;">if</span> <span style="color: #002200;">&#40;</span>cell == <span style="color: #0000ff;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    cell = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITableViewCell alloc<span style="color: #002200;">&#93;</span>
      initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdent<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #ff0000;">// Configure the cell...</span>
  ACAccount *account = <span style="color: #002200;">&#91;</span>self.accounts objectAtIndex:<span style="color: #002200;">&#91;</span>indexPath row<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  cell.textLabel.text = account.username;
  cell.detailTextLabel.text = account.accountDescription;
  cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  <span style="color: #0000ff;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre>
<h2>Displaying the public timeline of the selected user</h2>
<p>When the user selects one of the accounts, we want to display a list of recent tweets for this selected account. We'll use <code>TWRequest</code> to fetch the list of recent tweets. </p>
<p><code>TWRequest</code> is the centerpiece of the iOS Twitter Framework and relieves us of the burden of having to perform OAuth authentication and request signing on our own. In order for it to do this, we need to provide a reference to the account whose timeline we want to read. We also need to provide the URL of the Twitter API endpoint we want to access. While this might seem a little bit cumbersome at first, this allows us to access not only current API calls but also any new APIs Twitter might come up with in the future without requiring Apple to update the API. Pretty nifty.</p>
<pre class="objc">- <span style="color: #002200;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #002200;">&#41;</span>fetchData
<span style="color: #002200;">&#123;</span>
  TWRequest *postRequest = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>TWRequest alloc<span style="color: #002200;">&#93;</span>
    initWithURL:
      <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSURL.html"><span style="color: #0000ff;">NSURL</span></a> URLWithString:@<span style="color: #666666;">&quot;https://api.twitter.com/1/statuses/home_timeline.json&quot;</span><span style="color: #002200;">&#93;</span>
    parameters:<span style="color: #0000ff;">nil</span>
    requestMethod:TWRequestMethodGET<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>postRequest setAccount:self.account<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>postRequest performRequestWithHandler:^<span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSData.html"><span style="color: #0000ff;">NSData</span></a> *responseData,
                                           <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSHTTPURLResponse.html"><span style="color: #0000ff;">NSHTTPURLResponse</span></a> *urlResponse,
                                           <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSError.html"><span style="color: #0000ff;">NSError</span></a> *error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>urlResponse statusCode<span style="color: #002200;">&#93;</span> == <span style="color: #0000dd;">200</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSError.html"><span style="color: #0000ff;">NSError</span></a> *jsonError = <span style="color: #0000ff;">nil</span>;
      self.timeline = <span style="color: #002200;">&#91;</span>NSJSONSerialization JSONObjectWithData:responseData
                                                      options:<span style="color: #0000dd;">0</span>
                                                        error:&amp;jsonError<span style="color: #002200;">&#93;</span>;
      dispatch_sync<span style="color: #002200;">&#40;</span>dispatch_get_main_queue<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, ^<span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
      <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre>
<p>Again, we need to provide a completion handler which will be invoked as soon as the call to Twitter returns. As you can also see, we're using the same approach as before to make sure we update the UI from the UI thread. It's also interesting to see Apple provides us with their own JSON parsing framework - no longer do we need to integrate third party libraries to serialize / deserialize JSON data.</p>
<h2>Sending Tweets</h2>
<p>So far, we can choose a Twitter account from the list of Twitter accounts on our iPhone and display the home timeline of this particular user. But how about sending a tweet?</p>
<p>Sending tweets is really easy: you just have to instantiate a new <code>TWTweetComposeViewController</code> and display it - iOS will take care of the rest:</p>
<pre class="objc">- <span style="color: #002200;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #002200;">&#41;</span>composeTweet
<span style="color: #002200;">&#123;</span>
  TWTweetComposeViewController *tweetComposeViewController =
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>TWTweetComposeViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>tweetComposeViewController setCompletionHandler:
    ^<span style="color: #002200;">&#40;</span>TWTweetComposeViewControllerResult result<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>self dismissModalViewControllerAnimated:YES<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self presentModalViewController:tweetComposeViewController animated:YES<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre>
<p>The completion handler is merely needed to dismiss the tweet composition view after the tweet has been sent.</p>
<h2>Conclusion</h2>
<p>Integrating Twitter in your own apps has never been easier. With just a few lines of code, we implemented a basic version of a Twitter client that you can use to display a user's home timeline and send tweets. Elaborating this code base is left as an exercise to you - feel free to <a href="http://github.com/peterfriese/TwitterClient">fork the code on Github</a> and send me pull requests as you add interesting features!</p>
<p>Here's an impression of the current state of the application:</p>

<a href='http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/twitterclient1/' title='Twitter Client: list of local accounts'><img width="150" height="150" src="http://www.peterfriese.de/wp-content/TwitterClient1-150x150.png" class="attachment-thumbnail" alt="Twitter Client: list of local accounts" title="Twitter Client: list of local accounts" /></a>
<a href='http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/twitterclient2/' title='Twitter Client: home timeline for a user'><img width="150" height="150" src="http://www.peterfriese.de/wp-content/TwitterClient2-150x150.png" class="attachment-thumbnail" alt="Twitter Client: home timeline for a user" title="Twitter Client: home timeline for a user" /></a>
<a href='http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/twitterclient3/' title='Twitter Client: composing a tweet'><img width="150" height="150" src="http://www.peterfriese.de/wp-content/TwitterClient3-150x150.png" class="attachment-thumbnail" alt="Twitter Client: composing a tweet" title="Twitter Client: composing a tweet" /></a>

]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Code Generation 2011 &#8211; Don&#8217;t miss out!</title>
		<link>http://www.peterfriese.de/code-generation-2011-dont-miss-out/</link>
		<comments>http://www.peterfriese.de/code-generation-2011-dont-miss-out/#comments</comments>
		<pubDate>Sat, 21 May 2011 08:09:11 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MDSD]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Domain Specific Languages]]></category>
		<category><![CDATA[DSLs]]></category>
		<category><![CDATA[Language Workbench]]></category>
		<category><![CDATA[LOP]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=758</guid>
		<description><![CDATA[Code Generation 2011 is just around the corner and if you haven't booked yet, you should hurry up - a few places are still available! Quite a number of my colleagues at itemis have been busy preparing for this conference in the past few weeks. Besides working hard to hit the Eclipse Release Train milestone [...]]]></description>
			<content:encoded><![CDATA[<p>Code Generation 2011 is <a href="http://www.codegeneration.net/cg2011/index.php">just around the corner</a> and if you haven't booked yet, <a href="http://evbk.software-acumen.com/makebooking.php?event=CG2011">you should hurry up</a> - a few places are still available!</p>
<p>Quite a number of my colleagues at itemis have been busy preparing for this conference in the past few weeks. Besides working hard to hit the <a href="http://wiki.eclipse.org/Indigo/Simultaneous_Release_Plan">Eclipse Release Train milestone for Indigo on June 22nd</a>, the Xtext team brushed up their hands-on sessions "<a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=17">Xtext Take I: Creating Code Generators with Xtend2</a>" and "<a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=16">Xtext Take II: Crafting Domain Specific Languages with Xtext and Xbase</a>". If you've been using Xtext, you're well aware of the power you have at your disposal with this tool. Xbase and Xtend2, however, take this experience to a whole new level. So make sure to mark your calendar for these two sessions!<br />
<span id="more-758"></span><br />
But not only the Xtext team will share their expertise at CG2011 - Markus and Karsten will be also be in town to give hands-on tutorials and report from their experience:</p>
<ul>
<li><a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=22">Type Systems for DSLs (Markus Völter)</a></li>
<li><a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=8">Graphiti + Xtext: mixing graphical and textual DSLs for sprayers/designers (Karsten Thoms / Bernhard Merkle)</a></li>
<li><a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=5">Introduction to JetBrains Meta Programming System (MPS) (Markus Völter)</a></li>
</ul>
<p>The finale of the conference will be a panel discussion hosted by Markus on the topic of "<a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=20">Models, DSLs, Transformations: The Next 5 years</a>" - this should be a very interesting and lively discussion!</p>
<p><a href="http://lanyrd.com/people/hbehrens/">Heiko</a> <a href="http://lanyrd.com/people/peterfriese/">and I</a> will present "<a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=28">Cross-Platform Mobile Development with DSLs</a>" - a <a href="http://lanyrd.com/2011/cg2011/sdpgm/">fast-paced and fun mixture of slides, live coding (or modeling, if you will), videos and audience interaction</a>. Yes, that's right - the audience will be part of the show. Make sure to bring your web-enabled mobile phone and get the chance to win a price!</p>
<p>To keep track of the conference program(me), we at <a href="http://mobile.itemis.com">itemis mobile</a> have been busy to create a conference planner for your iOS and Android powered mobile phones. Here are the download links:</p>
<ul>
<li>Apple App Store: <a href="http://itunes.apple.com/us/app/code-generation-2011/id436689925?mt=8">Code Generation 2011</a></li>
<li>Android Market Place: <a href="https://market.android.com/details?id=de.itemis.mobile.android.cg2011&feature=search_result">Code Generation 2011</a></li>
</ul>
<div id="attachment_764" class="wp-caption aligncenter" style="width: 510px"><a class="lightbox"  title ="Code Generation 2011 Apps for iPhone and Android. Image courtesy of Heiko Behrens' impossible image skewing service" href="http://www.peterfriese.de/wp-content/cg2011.png"><img src="http://www.peterfriese.de/wp-content/cg2011-e1305966137679.png" alt="Code Generation 2011 Apps for iPhone and Android" title="Code Generation 2011 Apps for iPhone and Android" width="500" height="542" class="size-full wp-image-764" /></a><p class="wp-caption-text">Code Generation 2011 Apps for iPhone and Android</p></div>
<p>If you like the apps, please use the feedback feature of the respective store. Got comments or suggestions for improvement? <a href="mailto:mobile@itemis.de">Drop us a note</a> or track us down at the conference (best chance to see us: <a href="http://www.codegeneration.net/cg2011/sessioninfo.php?session=28">come to our talk</a> <img src='http://www.peterfriese.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/code-generation-2011-dont-miss-out/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using NSPredicate to Filter Data</title>
		<link>http://www.peterfriese.de/using-nspredicate-to-filter-data/</link>
		<comments>http://www.peterfriese.de/using-nspredicate-to-filter-data/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 20:15:36 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[nsarray]]></category>
		<category><![CDATA[nspredicate]]></category>
		<category><![CDATA[predicate]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=725</guid>
		<description><![CDATA[Filtering data is one of the essential tasks in computing. With all the data available today, we need to apply certain limits and constraints to actually make it usable. What use is it to be able to scroll down a list of literally thousands of list items when you really care about one or two [...]]]></description>
			<content:encoded><![CDATA[<p>Filtering data is one of the essential tasks in computing. With all the data available today, we need to apply certain limits and constraints to actually make it usable. What use is it to be able to scroll down a list of literally thousands of list items when you really care about one or two of them? Filtering and searching information make up a significant part of our work day - each time you use Google, you're applying a filter to the huge set of data we call the internet.<br />
<span id="more-725"></span><br />
Even on your local computer, you use services like Spotlight or the search field in your mail application all the time. Apps that lack decent searching and filtering capabilities sometimes are really hard to use, so as developers we should spend some time on thinking how to allow users to filter the data they're dealing with.</p>
<p>In this post, I am going to focus on ways to filter data. We won't be looking at the UI side of things - this is something I'll do in a subsequent blog post.</p>
<h2>Old-skool filtering</h2>
<p>If you look at an arbitrary code base, chances are you'll sooner or later run into a piece of code similar to this one:</p>
<pre class="objc"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSMutableArray.html"><span style="color: #0000ff;">NSMutableArray</span></a> *oldSkoolFiltered = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSMutableArray.html"><span style="color: #0000ff;">NSMutableArray</span></a> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
<span style="color: #0000ff;">for</span> <span style="color: #002200;">&#40;</span>Book *book in bookshelf<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>book.publisher isEqualToString:@<span style="color: #666666;">&quot;Apress&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>oldSkoolFiltered addObject:book<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
<p>It's a straight-forward approach to filtering an array of items (in this case, we're talking about books) using a rather simple <code>if</code>-statement. Nothing wrong with this, but despite the fact we're using a fairly simple expression here, the code is rather verbose. We can easily imagine what will happen in case we need to use more complicated selection criteria or a combination of filtering criteria.</p>
<h2>Simple filtering with NSPredicate</h2>
<p>Thanks to Cocoa, we can simplify the code by using <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html">NSPredicate</a>. <code>NSPredicate</code> is the object representation of an if-statement, or, more formally, a predicate.</p>
<p>Predicates are <a href="http://en.wikipedia.org/wiki/Predicate_(mathematical_logic)">expressions that evaluate to a truth value</a>, i.e. <code>true</code> or <code>false</code>. We can use them to perform validation and filtering. In Cocoa, we can use <code>NSPredicate</code> to evaluate single objects, filter arrays and perform queries against Core Data data sets.</p>
<p>Let's have a look at how our example looks like when using <code>NSPredicate</code>:</p>
<pre class="objc">NSPredicate *predicate =
  <span style="color: #002200;">&#91;</span>NSPredicate predicateWithFormat:@<span style="color: #666666;">&quot;publisher == %@&quot;</span>, @<span style="color: #666666;">&quot;Apress&quot;</span> <span style="color: #002200;">&#93;</span>;
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSArray.html"><span style="color: #0000ff;">NSArray</span></a> *filtered  = <span style="color: #002200;">&#91;</span>bookshelf filteredArrayUsingPredicate:predicate<span style="color: #002200;">&#93;</span>;</pre>
<p>Much shorter and better readable!</p>
<h2>Filtering with Regular Expressions</h2>
<p>Regular Expressions can be used to <a href="http://xkcd.com/208/">solve almost any problem <img src='http://www.peterfriese.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </a> so it's good to know you can use them in <code>NSPredicate</code>s as well. To use regular expressions in your <code>NSPredicate</code>, you need to use the <code>MATCHES</code> operator.</p>
<p>Let's filter all books that are about iPad or iPhone programming:</p>
<pre>
predicate = [NSPredicate predicateWithFormat:@"title MATCHES '.*(iPhone|iPad).*'"];
filtered = [bookshelf filteredArrayUsingPredicate:predicate];
dumpBookshelf(@"Books that contain 'iPad' or 'iPhone' in their title", filtered);
</pre>
<p>You need to obey some rules when using regular expressions in <code>NSPredicate</code>: most importantly, <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-SW9">you cannot use regular expression metacharacters inside a pattern set</a>.</p>
<h2>Filtering using set operations</h2>
<p>Let's for a moment assume you want to filter all books that have been published by your favorite publishers. Using the <code>IN</code> operator, this is rather simple: first, we need to set up a set containing the publishers we're interested in. Then, we can create the predicate and finally perform the filtering operation:</p>
<pre>NSArray *favoritePublishers = [NSArray arrayWithObjects:@"Apress", @"O'Reilly", nil];
predicate = [NSPredicate predicateWithFormat:@"publisher IN %@", favoritePublishers];
filtered  = [bookshelf filteredArrayUsingPredicate:predicate];
dumpBookshelf(@"Books published by my favorite publishers", filtered);</pre>
<h2>Advanced filtering thanks to KVC goodness</h2>
<p><code>NSPredicate</code> relies on <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html">key-value coding</a> to achieve its magic. On one hand this means your classes need to be <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/Compliant.html#//apple_ref/doc/uid/20002172-BAJEAIEE">KVC compliant</a> in order to be queried using <code>NSPredicate</code> (at least the attributes you want to query). On the other hand, this allows us to perform some very interesting things with very little lines of code.</p>
<p>Let's for example retrieve a list of books written by authors with the name "Mark":</p>
<pre class="objc">predicate =
  <span style="color: #002200;">&#91;</span>NSPredicate predicateWithFormat:@<span style="color: #666666;">&quot;authors.lastName CONTAINS %@&quot;</span>, @<span style="color: #666666;">&quot;Mark&quot;</span> <span style="color: #002200;">&#93;</span>;
filtered  = <span style="color: #002200;">&#91;</span>bookshelf filteredArrayUsingPredicate:predicate<span style="color: #002200;">&#93;</span>;</pre>
<p>In case we'd want to return the value of one of the aggregate functions, we don't need to use NSPredicate itself, but instead use KVC directly. Let's retrieve the average price of all books on our shelf:</p>
<pre class="objc"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSNumber.html"><span style="color: #0000ff;">NSNumber</span></a> *average = <span style="color: #002200;">&#91;</span>bookshelf valueForKeyPath:@<span style="color: #666666;">&quot;@avg.price&quot;</span><span style="color: #002200;">&#93;</span>;</pre>
<h2>Conclusion</h2>
<p>The Cocoa libraries provide some very powerful abstractions which can make your life and that of the people reading your code much easier. It pays off to know about them, so go ahead and browse the Cocoa documentation and hunt for those gems!</p>
<p>Apple's <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/predicates.html">NSPredicate programming guide</a> provides an in-depth documentation for <code>NSPredicate</code> containing all the things I didn't cover in this post.</p>
<p><code>NSPredicate</code> also plays an important role when querying data in Core Data, something we will need to have a look at in one of the next blog posts. Stay tuned!</p>
<h2>Code</h2>
<p>The code for this post is available on my github page: <a href="http://github.com/peterfriese/NSPredicateDemo">get forking</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/using-nspredicate-to-filter-data/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Save a Tree, Put EclipseCon 2011 in Your Pocket</title>
		<link>http://www.peterfriese.de/save-a-tree-put-eclipsecon-2011-in-your-pocket/</link>
		<comments>http://www.peterfriese.de/save-a-tree-put-eclipsecon-2011-in-your-pocket/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 20:15:57 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=709</guid>
		<description><![CDATA[After the huge success of the mobile apps for Eclipse Summit Europe, we decided to provide mobile apps for EclipseCon 2011, too. So instead of using a printed copy of the conference program, you can browse the schedule on your smart phone - wherever you are! This year, we're providing a rather impressive lineup of [...]]]></description>
			<content:encoded><![CDATA[<p>After the huge success of the mobile apps for Eclipse Summit Europe, we decided to provide mobile apps for EclipseCon 2011, too. So instead of using a printed copy of the conference program, you can browse the schedule on your smart phone - wherever you are! <span id="more-709"></span>This year, we're providing a rather impressive lineup of mobile apps for iPhone, iPod Touch, iPad (thanks to <a href="http://www.compeople.eu/blog/?p=786">Christian Campo who created a stand-alone iPad app</a>), BlackBerry (<a href="http://ekkes-apps.org/">Ekke is working on a updated version, AFAIK</a>), and all other smart phones that feature a browser.</p>
<p>All apps allow you to browse the program, select your favorite talks and get to know the speakers (with headshots so you recognise them in the hallways). We also have included maps of the convention center as well as Santa Clara.</p>
<p>For a first glimpse, watch our video:</p>
<p><iframe src="http://player.vimeo.com/video/20377509?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=1&amp;loop=1" width="501" height="313" frameborder="0" style="display:block; margin-left:auto; margin-right:auto;"></iframe></p>
<p>As of today, both iPhone and Android users can download the apps from the Apple App Store respectively the Android Marketplace. Here are the links:</p>
<ol>
<li><a href="http://bit.ly/econ2011iphone">EclipseCon 2011 iPhone App</a></li>
<li><a href="http://bit.ly/econ2011android">EclipseCon 2011 Android App</a></li>
</ol>
<p>If you don't own an iPhone or Android, you can always use the HTML-only version of the conference program available at <a href="http://bit.ly/econ2011html">http://bit.ly/econ2011html</a>.</p>
<p>The iPad and BlackBerry apps will be available soon, so stay tuned!</p>
<p>By the way, if <strong>you</strong> run a conference and are interested in having an app like this, <a href="http://mobile.itemis.com">get in touch with us</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/save-a-tree-put-eclipsecon-2011-in-your-pocket/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Appropriate Use of MapKit</title>
		<link>http://www.peterfriese.de/appropriate-use-of-mapkit/</link>
		<comments>http://www.peterfriese.de/appropriate-use-of-mapkit/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 08:48:38 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MapKit]]></category>
		<category><![CDATA[googlemaps]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[terms of service]]></category>
		<category><![CDATA[TOS]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=689</guid>
		<description><![CDATA[I just had an app rejected because of violation of the Google Maps terms of service. While it certainly is kind of funny Apple rejects an app because you're violating Google's terms of service, I was wondering what in particular was wrong. At first sight, everything looked OK. Have a look at the following screenshot. [...]]]></description>
			<content:encoded><![CDATA[<p>I just had an app rejected because of violation of the Google Maps terms of service. While it certainly is kind of funny Apple rejects an app because you're violating Google's terms of service, I was wondering what in particular was wrong. <span id="more-689"></span>At first sight, everything looked OK. Have a look at the following screenshot. It clearly violates <a href="http://code.google.com/apis/maps/terms.html">Google's terms of service for Maps</a>, but can you spot what is wrong?</p>
<div id="attachment_687" class="wp-caption aligncenter" style="width: 182px"><a class="lightbox"  title ="Google Maps in your app" href="http://www.peterfriese.de/wp-content/maps_without_google_logo.png"><img src="http://www.peterfriese.de/wp-content/maps_without_google_logo-172x300.png" alt="Google Maps in your app - without Google Logo: you&#039;re doing it wrong!" title="No logo? You're doing it wrong!" width="172" height="300" class="size-medium wp-image-687" /></a><p class="wp-caption-text">What's wrong with this map?</p></div>
<p>Maybe you can better see what's wrong when I show you another screenshot, this time obeying the TOS:</p>
<div id="attachment_688" class="wp-caption aligncenter" style="width: 179px"><a class="lightbox"  title ="Google Maps in your app" href="http://www.peterfriese.de/wp-content/maps_with_google_logo.png"><img src="http://www.peterfriese.de/wp-content/maps_with_google_logo-169x300.png" alt="Google Maps with logo: well done!" title="Google Maps with logo" width="169" height="300" class="size-medium wp-image-688" /></a><p class="wp-caption-text">With logo: well done!</p></div>
<p>Can you spot the difference? It's the Google logo!</p>
<p>The reason why it is not shown in the first screenshot is that the bounds for the map are not set correctly. In the offending version of my app, I used a piece of code similar to this one:</p>
<pre class="objc">&nbsp;
- <span style="color: #002200;">&#40;</span><span style="color: #0000ff;">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>;
  mapView = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MKMapView alloc<span style="color: #002200;">&#93;</span> initWithFrame:self.view.bounds<span style="color: #002200;">&#93;</span>;
&nbsp;
  mapView.showsUserLocation=<span style="color: #0000ff;">TRUE</span>;
  mapView.mapType=MKMapTypeStandard;
  <span style="color: #002200;">&#91;</span>self.view addSubview:mapView<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;</pre>
<p>Nothing wrong with it, but it lacks one essential line:</p>
<pre class="objc">&nbsp;
- <span style="color: #002200;">&#40;</span><span style="color: #0000ff;">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>;
  mapView = <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MKMapView alloc<span style="color: #002200;">&#93;</span> initWithFrame:self.view.bounds<span style="color: #002200;">&#93;</span>;
&nbsp;
  mapView.autoresizingMask =
    <span style="color: #002200;">&#40;</span>UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight<span style="color: #002200;">&#41;</span>;	
&nbsp;
  mapView.showsUserLocation=<span style="color: #0000ff;">TRUE</span>;
  mapView.mapType=MKMapTypeStandard;
  <span style="color: #002200;">&#91;</span>self.view addSubview:mapView<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;</pre>
<p>So, next time you write an app that contains Google Maps, make sure the Google logo is visible. You can get the full source code for this example <a href="http://github.com/peterfriese/MapKitSample">on my GitHub page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/appropriate-use-of-mapkit/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>What&#8217;s your number?</title>
		<link>http://www.peterfriese.de/whats-your-number/</link>
		<comments>http://www.peterfriese.de/whats-your-number/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 23:00:47 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[adhoc]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[provisioning]]></category>
		<category><![CDATA[UDID]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=656</guid>
		<description><![CDATA[If you take part in a beta test for an iPhone app, the app developer will likely ask you to send him the UDID of your iPhone. If you've been asking yourself "what's this number, and where do I find it?", read on! The Unique Device IDentifier is a 40-digit number that uniquely identifies your [...]]]></description>
			<content:encoded><![CDATA[<p>If you take part in a beta test for an iPhone app, the app developer will likely ask you to send him the UDID of your iPhone. If you've been asking yourself "what's this number, and where do I find it?", read on!</p>
<p><span id="more-656"></span>The Unique Device IDentifier is a 40-digit number that uniquely identifies your iPhone or iPad. It's tied to your device, not to a SIM card you might (or might not, depending on the type of device) have inserted.</p>
<p>Here's how you can find this number and send it to your developer:</p>
<ol>
<li>Connect your iPhone / iPad to your computer using the white USB connection cable.</li>
<li>Wait for iTunes to start up. If it doesn't start automatically, start it manually (Windows users will find it in the depths of the Start Menu, Mac users can use Spotlight to search for it).</li>
<li>Click on the name of your iPhone / iPad on the left-hand side of the iTunes Window: <a href="http://www.flickr.com/photos/81029262@N00/5391569342" title="View 'Finding your iPhone's UDID, step 1' on Flickr.com"><img height="188" border="0" src="http://farm6.static.flickr.com/5180/5391569342_79b2d97180.jpg" alt="Finding your iPhone's UDID, step 1" title="Finding your iPhone's UDID, step 1" width="500"/></a></li>
<li>Details about your device will be displayed in the main area of the iTunes window.</li>
<li>Find the label titled <b>Serial Number</b>. The serial number IS NOT the UDID!</li>
<li>Holding down the CMD (on the Mac) or the CTRL (on Windows) key, click on the label <b>Serial Number</b></li>
<li>The label's title will change to <b>Identifier (UDID</b>:<a href="http://www.flickr.com/photos/81029262@N00/5391652500" title="View 'Finding your iPhone's UDID, step 2' on Flickr.com"><img height="161" title="Finding your iPhone's UDID, step 2" alt="Finding your iPhone's UDID, step 2" border="0" src="http://farm6.static.flickr.com/5291/5391652500_1c2dbaf918.jpg" width="500"/></a></li>
<li>Press CMD+C (on Mac) or CTRL+C (on Windows) to copy the UDID to your clipboard</li>
<li>Open a new mail, insert the UDID and a friendly message and send it to your developer.</li>
</ol>
<p>Easy, isn't it?</p>
<p>Oh, and please do NOT send a screenshot of the UDID. You should know better now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/whats-your-number/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How to Use the Gyroscope of Your iPhone in a Mobile Web App</title>
		<link>http://www.peterfriese.de/how-to-use-the-gyroscope-of-your-iphone-in-a-mobile-web-app/</link>
		<comments>http://www.peterfriese.de/how-to-use-the-gyroscope-of-your-iphone-in-a-mobile-web-app/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 10:00:43 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[gyrosope]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=633</guid>
		<description><![CDATA[This week's release of iOS 4.2 for iPad and iPhone comes with some nice little features most people will not immediately become aware of as they're neither directly visible in the iOS UI nor are they mentioned in Apple's official release notes. You have to dig a little deeper to find them. One of them [...]]]></description>
			<content:encoded><![CDATA[<p>This week's release of iOS 4.2 for iPad and iPhone comes with some nice little features most people will not immediately become aware of as they're neither directly visible in the iOS UI nor are they mentioned in Apple's official release notes. You have to dig a little deeper to find them. One of them is a JavaScript API for the iPhone's gyroscope. Read on to see it in action and learn how to use it.<span id="more-633"></span>Your iPhone has a number of sensors, some of which are rather essential for the phone's operation (such as the microphone). While the accelerometer and the gyroscope might not be the most essential sensors for a phone, they're certainly the most exciting ones. While accelerometer measures the acceleration you induce on the phone, the gyroscope gives a rather precise feedback on the orientation of the phone.</p>
<p>Until now, web developers didn't have access to the accelerometer sensor and the gyroscope sensor. With this week's release of iOS 4.2, this has changed and we can now use <a href="https://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/DeviceMotionEventClassRef/DeviceMotionEvent/DeviceMotionEvent.html">DeviceMotionEvent</a> and <a href="https://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/DeviceOrientationEventClassRef/DeviceOrientationEvent/DeviceOrientationEvent.html">DeviceOrientationEvent</a> to determine the acceleration and orientation data of the phone.</p>
<p>Let's first determine whether the current browser supports device orientation sensing:</p>
<pre>
if (window.DeviceMotionEvent==undefined) {
}
</pre>
<p>We can then read the sensor data by registering the respective callbacks. Here's how you read the accelerometer's data:</p>
<pre>
window.ondevicemotion = function(event) {
  ax = event.accelerationIncludingGravity.x
  ay = event.accelerationIncludingGravity.y
  az = event.accelerationIncludingGravity.z
  rotation = event.rotationRate;
  if (rotation != null) {
    arAlpha = Math.round(rotation.alpha);
    arBeta = Math.round(rotation.beta);
    arGamma = Math.round(rotation.gamma);
  }
}
</pre>
<p>The gyroscope's data can be read like this:</p>
<pre>
window.ondeviceorientation = function(event) {
  alpha = Math.round(event.alpha);
  beta = Math.round(event.beta);
  gamma = Math.round(event.gamma);
}
</pre>
<p>I've put together a little demo that uses the sensor data to color some boxes on the phone's screen. Here's a short video showing it in action:</p>
<p><iframe border="0" style="display:block; margin-left:auto; margin-right:auto;" src="http://player.vimeo.com/video/17182364?title=0&amp;byline=0&amp;portrait=0" width="500" height="370" frameborder="0"></iframe></p>
<p>If you want to take it for a spin, open this URL in mobile safari on your phone: <a href="http://demos.peterfriese.de/gyro/gyro.html">http://demos.peterfriese.de/gyro/gyro.html</a>.</p>
<p><small>(image of Gyroscope by stop that pigeon! taken from http://www.flickr.com/photos/25312309@N05/2651042796/)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/how-to-use-the-gyroscope-of-your-iphone-in-a-mobile-web-app/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Apple’s Updated Developer License – This Changes Everything. Again.</title>
		<link>http://www.peterfriese.de/apples-updated-developer-license-this-changes-everything-again/</link>
		<comments>http://www.peterfriese.de/apples-updated-developer-license-this-changes-everything-again/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 18:15:30 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[DSLs]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Xtext]]></category>
		<category><![CDATA[331]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[section331]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=585</guid>
		<description><![CDATA[A few days ago, Apple made some small, but very important changes to the iOS Developer Program Agreement - a document which you must agree to before you can download the iOS SDK and start developing software for the iOS platform. These changes will drastically change the way we will build software for the iPhone, [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, Apple made some small, but very important changes to the iOS Developer Program Agreement - a document which you must agree to before you can download the iOS SDK and start developing software for the iOS platform. These changes will drastically change the way we will build software for the iPhone, iPad and iPod and any other device that runs iOS.</p>
<p><span id="more-585"></span>In April 2010, together with the release of iOS 4, Apple changed the terms of the iOS Developer Program License in a way which basically prohibited creating software for iOS using languages other than Objective-C, C, C++ or JavaScript:</p>
<blockquote><p>3.3.1 — Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).</p></blockquote>
<p>Back then, pretty much everyone was sure this update to section 3.3.1 of the license really was just one strike in <a href="http://www.apple.com/hotnews/thoughts-on-flash/">Apple's crusade against Flash</a>. Adobe had been working on a tool called <a href="http://labs.adobe.com/technologies/packagerforiphone/">Flash Packager</a>, which allows Flash designers to cross-compile their applications for the iPhone. While this must have been bad news for Adobe (they effectively needed to write off development costs for the entire development team working on Flash Packager), it posed a serious threat to companies whose business model relied upon creating iPhone apps using tools and languages other than Xcode and Objective-C. The future for Novell's <a href="http://monotouch.net/">Mono Touch</a>, <a href="http://www.appcelerator.com/">Appcelerator Titanium</a>, <a href="http://www.phonegap.com/">PhoneGap</a> and <a href="http://www.xmlvm.org/iphone/">XMLVM/iPhone</a> didn't look very bright.</p>
<p>No need to say there was quite an uproar and people came up with all sorts of creative interpretations of the terms stated in section 3.3.1 to avoid being rejected from the App Store.</p>
<p>Of course, if a monopolist starts endangering other, dependent companies, this soon will call the Federal Trade Commission to action. It doesn't come that much of a surprise Apple published a new, very relaxed version of the iOS Developer Program Agreement just a few days ago. The new version (which is publicly available at <a href="http://developer.apple.com/programs/terms/ios/standard/ios_standard_agreement_20100909.pdf">http://developer.apple.com/programs/terms/ios/standard/ios_standard_agreement_20100909.pdf</a> does not limit the programming languages you may use to create applications for the iOS platform any more. In particular, section 3.3.1 now reads:</p>
<blockquote><p>3.3.1	Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs.</p></blockquote>
<p>You might think that a small paragraph in a license agreement doesn't mean that much, but I think the new section will fundamentally change the way we write software for the iPhone in the next few years. Let me explain:</p>
<p>The new section 3.3.1 means you may write iOS software using any language you like. Yes, ANY language - there is no if and when. This means you will not only be able to write iOS software in Objective-C (which is a great language as soon as you come to grips with it), but you will be able to use language like Java, Scala, Haskell, Ruby, etc. Some people are <a href="http://twitter.com/mattgemmell/status/24014145904">even dreaming of using REALBasic</a> for iOS apps.</p>
<p>Vendors of tools such as Mono Touch, Titanium and PhoneGap will be glad, as their business models now have a solid foundation (well, Apple may of course change the license again but I doubt they'll ever restrict the usage of other languages again). Given the <a href="http://labs.adobe.com/technologies/packagerforiphone/">announcement on Adobe Labs</a>, I guess we will very soon see Adobe release their highly acclaimed Flash Packager for iPhone (I don't think people will seriously use this tool to create data-driven applications, but it's probably a great tool to develop games. If you're a Flash designer / developer, that is).</p>
<p>For the development community at large, this is great news: freedom to choose the language that fits your needs best has always been a cornerstone of successfully creating great software. People have expressed their desire to use languages such as Haskell and Ruby to build iPhone apps. Rumor has it Apple engineers have even been working on a version of MacRuby for iPhone - there you go.</p>
<p>At <a href="http://www.itemis.com">itemis</a>, we're very much into programming languages. We're even building our own language development toolkit to support development of programming languages - <a href="http://www.xtext.org">Xtext</a>. With this toolkit, it is very easy to create your own domain specific programming languages (DSLs). In the past, we've mainly been using it to create languages for enterprise and web applications. We're also helping others to (re-)build languages such as SQL. Of course, Xtext is being used to build itself - isn't that nice?  About one year ago, we started implementing a programming language tailored towards creating data-driven mobile applications for the iOS platform. We're not aiming at creating a language you can use to build arbitrary iOS applications. Instead, we're focussing on data-driven applications with a drill-down metaphor. Something you can find in many applications such as FaceBook, LinkedIn, Kayak and the like. Watch the following video to see it in action:</p>
<div style="text-align:center;">
<iframe src="http://player.vimeo.com/video/15018235?title=0&amp;byline=0&amp;portrait=0" width="400" height="280" frameborder="0"></iframe>
</div>
<p>If you're interested in learning more about APPlause, get in touch with us by mail [heiko.behrens|peter.friese]@itemis.de, subscribe to <a href="http://www.heikobehrens.net">our</a> <a href="http://www.peterfriese.de">blogs</a> and follow us on Twitter (<a href="http://www.twitter.com/peterfriese">@peterfriese</a>, <a href="http://www.twitter.com/HBehrens">@HBehrens</a>, <a href="http://www.twitter.com/applausedsl">@APPlauseDSL</a>).</p>
<p>In a few years, I guess, Objective-C will be just one language among many others you can choose from if you want to build iOS applications.</p>
<p>But why would you want to write iOS applications in languages other than Objective-C? There are many reasons:</p>
<ul>
<li>Use the language you feel most comfortable with. Maybe Objective-C's square brackets look scary to you?</li>
<li>Use the language you have most experience with. Maybe you're a company and have a tight schedule. Writing your application using the language your developers have the most skills in helps you to meet your deadline. In fact, a friend just recently told me they used Appcelerator "because we've got JavaScript and HTML knowledge in-house, but none of our developers had experience with Objective-C"!</li>
<li>use the language you use for developing your backend system. So you've got this huge backend system written C#, running on the .NT platform. Why not write all the front-end code in C# as well?</li>
<li>Maybe you're a start-up in the social media realm and your website is written all in Ruby and Ruby on Rails. So why not write the iPhone app in Ruby as well?</li>
</ul>
<p>It all boils down to being more productive and ensuring better sustainability. Using the right tool for the job helps you to achieve a faster time to market. If you're able to use the same language on the frontend and the backend, this will help you to secure your investment in this technology.</p>
<p>Please note that I'm not saying you should by all means write your frontend and your backend using the same technology and language. The first and foremost question you need to answer is, "what's the right tool for this job". Being able to make a real choice will help you to give a better answer to this question.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/apples-updated-developer-license-this-changes-everything-again/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Why Your Next App Should be Open Sourced</title>
		<link>http://www.peterfriese.de/why-your-next-app-should-be-open-sourced/</link>
		<comments>http://www.peterfriese.de/why-your-next-app-should-be-open-sourced/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 11:15:17 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[OSS]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[license]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=575</guid>
		<description><![CDATA[I've been doing all sorts of software development over the past few years, from closed-source in-house software for companies to closed-source product development to open-source frameworks and tools development to close-source app development. Looking back on my experience with the various drawbacks and benefits of each of those development modes, I hereby recommend your next [...]]]></description>
			<content:encoded><![CDATA[<p>I've been doing all sorts of software development over the past few years, from closed-source in-house software for companies to closed-source product development to open-source frameworks and tools development to close-source app development. </p>
<p>Looking back on my experience with the various drawbacks and benefits of each of those development modes, I hereby recommend your next app be open sourced.<br />
<span id="more-575"></span>Here is why:</p>
<h3>Reasons pro Open Source</h3>
<p>We all heard it before, "Open Source will make the world a better place" - but why? Well, let me give you a few reasons:</p>
<p>
<strong>First</strong>, by open sourcing your code, your code will become better. If everybody can see what your code looks like, you will do your best to make sure it's clean code. Jeff LaMarche calls this "<a href="http://iphonedevelopment.blogspot.com/2010/06/code-as-if.html">coding as if everybody is watching</a>". Clean code has less errors than quick-and-dirty code, so that's a good thing.
</p>
<p>
<strong>Enabling others to contribute</strong> will further improve your code. Should you decide to invite other developers to your project, you'll want to add some documentation to make it easier for them to get a jump start. Writing documentation will force you to think through your code and its overall structure. You might find you want to perform some refactorings before you actually let other developers work on your code. This will improve the quality of your code even more.
</p>
<p>
<strong>Enabling others to participate will make your app more attractive</strong>. Didn't you experience this before: the app you just downloaded is almost perfect - if it only had this one missing feature. For example, I really love <a href="http://www.tweetdeck.com/iphone/">TweetDeck for iPhone</a>, but I'm dearly missing an <a href="http://www.instapaper.com/">Instapaper</a> integration. If TweetDeck was open source, I would've added Instapaper integration to the code and submitted a patch to the creators of TweetDeck for the benefit of the entire user base. But unfortunately, TweetDeck is not open source - what a pity.
</p>
<p>
By <strong>building a team of skilled people</strong>, you'll be able to deliver more features in a shorter amount of time than you can ever hope to achieve if you work alone. Successful open source projects are made up of a bunch of gifted individuals with diverse skills. This is even more important for mobile applications, as you not only have to develop the code that makes your app work. You also have to create a great looking UI, so might need a great designer. If you want to promote your app on a website, you might also consider teaming up with a web designer.
</p>
<p>
<strong>Speaking of contributions</strong>, you might be a bit hesitant to let other people work on your code. That's alright. Usually, contributors do not get commit rights right away. Instead, you ask them to contribute to the project by submitting patches via your bug tracker (you do use a bug tracker, don't you?). This enables you to review their code before actually committing it to the code base. If you're not satisfied, let them know (in a friendly way) what you would like them to improve. If a contributor delivers a number of great patches in a row, you can consider to promote him/her to be a committer.
</p>
<h3>Reasons against Open Source</h3>
<p>There are a few reasons why your next app maybe should not be open sourced:</p>
<p>
<strong>Others might steal your ideas!</strong> I keep hearing this argument over and over again. Yes, if you open source your app, other developers might check out the code, re-brand it and sell it on the app store as their invention. Well, they can steal your ideas anyway - just by looking at your app and building an app that looks and feels the same. Granted, re-writing an app consumes considerably more time than re-branding an existing code base. But I doubt anybody dares to submit a blatant 1:1 copy of an app to the app store. At the very least, you should choose a suitable license for your code. There are a number of great open source licenses you might consider check out the <a href="http://www.opensource.org/licenses>OSI website for a list of open source licenses</a>. <a href="http://blog.robrhyne.com/">Rob Rhyne</a> even had his <a href="http://jdrhyne.tumblr.com/">brother</a> (who is a lawyer) create a <a href="http://github.com/capttaco/Briefs/blob/master/LICENSE">new app-store compatible license</a> for his app, <a href="http://giveabrief.com/">Briefs</a>. Read his blog post "<a href="http://blog.robrhyne.com/post/1043407467/selling-open-source">Selling Open Source</a>" for the rationale behind this step.
</p>
<p>
Even if other people don't copy your entire app, <strong>they still might copy some cool UI tricks</strong> you do. Maybe you've gone to great lengths to create some really cool frameworks that make your life easier or make your app behave in a very cool and new way. You might not want other apps to look as cool as your app does. Well, it's your right. In my opinion, the app store contains way too many badly designed apps. You would do the world a favour by releasing your great library to the public. Really.
</p>
<p>And finally, you might not be able to open source your next app because your client or the <strong>company you're working for is against open source</strong>. Maybe they have good reasons for it, maybe they just don't know enough about open source. If the latter is the case, let them read this blog post or drop me a line - I'm available for consulting.
</p>
<h3>Business Models for Open Source Apps</h3>
<p>You might have a different point of view (and if you do, please leave a comment - I'm eager to hear your thoughts), but in my opinion open source is not a threat but a chance for your app. If we take this for granted, the question remains, how can you make money with an open sourced app? Here are some suggestions:</p>
<p>
<strong>Sell it on the App Store</strong>. Yes, this might sound a little strange after all my raving about open source. If something is open source, how can you sell it? Well, it turns out selling apps on the App Store is a great idea, especially for open source apps. The app store is the only way how your clients can get hold of your application. Of course - they might check out your code, compile it and upload it to their iPhone. But to do so, they'd need to be registered iPhone developers, meaning they'd need to buy an iPhone developer certificate. Don't you think it is cheaper to just buy your app than shelling out 99 USD for the developer certificate?
</p>
<p>If you're developing a library or framework, you might consider getting <strong>funding on <a href="http://www.kickstarter.com/">Kickstarter</a></strong>. Kickstarter is a great way to get funding for your project: you define the deliverable and how much funds you want to raise and people can back your project by pledging a variable amount of money. This way, <a href="http://www.penandthink.com/">John Wain</a> of <a href="http://glyphish.com/">Glyphish</a> fame <a href="http://www.kickstarter.com/projects/jpwain/great-icons-for-iphone-4-apps">managed to raise more than 27.000 USD</a> for developing an iPhone 4 compatible version of his great Glyphish icon set. His original goal was to raise 2.000 USD, by the way.
</p>
<p>
I hope I could encourage you to try open source as a strategy for your next application or framework. If I did, let me know! Chances are I might want to submit a patch to add that tiny little feature I think your app is lacking <img src='http://www.peterfriese.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/why-your-next-app-should-be-open-sourced/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Watching DVDs on your iPad</title>
		<link>http://www.peterfriese.de/watching-dvds-on-your-ipad/</link>
		<comments>http://www.peterfriese.de/watching-dvds-on-your-ipad/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 20:22:10 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[dvd]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=541</guid>
		<description><![CDATA[I've been wanting to watch DVDs on my iPad since I had it. As the iPad doesn't have an optical drive, you need to jump through several loopholes to get the trick done, but in the very moment you watch your first DVD on your iPad, something magical happens... At first, I came up with [...]]]></description>
			<content:encoded><![CDATA[<p>I've been wanting to watch DVDs on my iPad since I had it. As the iPad doesn't have an optical drive, you need to jump through several loopholes to get the trick done, but in the very moment you watch your first DVD on your iPad, something magical happens...</p>
<p><span id="more-541"></span>At first, I came up with a solution that would allow me to watch DVDs without re-encoding them - I just streamed them from my Mac. Actually, this is very easy with the help of some great open source tools, some of which are already installed on your Mac. But I guess this is a story for another blog post.</p>
<p>If you want to take your DVDs with you on your iPad, streaming them from your Mac isn't an option. So I browsed the web to see if I could find an affordable ripper. If you google for "<a href="http://www.google.com/search?q=dvd+ipad">dvd ipad</a>", you'll be given an enormous list of hits linking to commercial tools - obviously encoding DVDs for the iPad isn't that simple, so companies can make a good business with selling tools. But I didn't want to buy any of those tools, so I looked for a solution involving freely available open source tools.</p>
<p>So, if you want to encode your DVDs for your iPad, here are the steps you need to take. It's very simple and doesn't cost you a single dime:</p>
<ol>
<li><a href="http://handbrake.fr/downloads.php">Download</a> and install Handbrake.</li>
<li>In order to encode for the iPad, you need to use an adjusted profile: <a href="http://www.peterfriese.de/wp-content/downloads/handbrake/iPad.plist">iPad.plist</a>.</li>
<li>Install this profile into Handbrake (<em>Preset -> Import...</em> on the main menu)</li>
<li>Insert a DVD into your optical drive</li>
<li>Click the <em>Source</em> button in Handbrake and select your DVD</li>
<li>Handbrake will now scan the DVD for what it thinks is the main feature - you might need to verif this.</li>
<li>Select one of the profiles in the profile selection dialog (on the Mac, press the <em>Toggle Presets</em> button on the toolbar). <em>iPad full</em> worked fine for me.</li>
<li>You can now fine-tune the settings. For example, the <em>audio</em> tab allows you to add multiple audio tracks to your video</li>
<li>Once you're done, press <em>Start</em></li>
<li>Now it's time to go for a walk or having a chat with your friends - ripping the DVD will take some time, depending on your computer</li>
<li>When Handbrake is done encoding the video, just double-click the resulting <em>.m4v</em> file to import it to iTunes.</li>
<li>As soon as the video shows up in iTunes, you can sync it to your iPad (the iPhone plays the video fine, too)</li>
</ol>
<p>Most DVDs do not take up more than 1GB after encoding for the iPad, so you can load quite a number of films even onto small iPads.</p>
<p>Enjoy! Oh, and should I have made your life easier, feel free to <a href="http://flattr.com/thing/2943/Peter-Frieses-Blog">flattr</a> me!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/watching-dvds-on-your-ipad/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

