<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Peter Friese</title>
	
	<link>http://www.peterfriese.de</link>
	<description>mobile / model-driven</description>
	<lastBuildDate>Sun, 26 Feb 2012 17:10:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/FormFollowsFunction" /><feedburner:info uri="formfollowsfunction" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>FormFollowsFunction</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>The Accounts and Twitter Framework on iOS 5</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/sqDykV_1QMY/</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>

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=sqDykV_1QMY:Lalo3gYVX5Q:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=sqDykV_1QMY:Lalo3gYVX5Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=sqDykV_1QMY:Lalo3gYVX5Q:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=sqDykV_1QMY:Lalo3gYVX5Q:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/sqDykV_1QMY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/</feedburner:origLink></item>
		<item>
		<title>Tired of Typing? Speak to Your Computer!</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/p19rNOF9tAk/</link>
		<comments>http://www.peterfriese.de/tired-of-typing-speak-to-your-computer/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 14:54:39 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=773</guid>
		<description><![CDATA[For some reason, humans have always dreamt of using natural language to communicate with computers. Quite a number of movies have been made that revolve around this theme, 2001: A Space Odyssey and I, Robot (named after the great collection of SF stories by Isaac Asimov) just being two of them. Well, we've come a [...]]]></description>
			<content:encoded><![CDATA[<p>For some reason, humans have always dreamt of using natural language to communicate with computers. Quite a number of movies have been made that revolve around this theme, <a href="http://en.wikipedia.org/wiki/2001:_A_Space_Odyssey">2001: A Space Odyssey</a> and <a href="http://en.wikipedia.org/wiki/I,_Robot_(film)">I, Robot</a> (named after the <a href="http://en.wikipedia.org/wiki/I_robot">great collection of SF stories</a> by <a href="http://en.wikipedia.org/wiki/Isaac_Asimov">Isaac Asimov</a>) just being two of them.<br />
<span id="more-773"></span><br />
Well, we've come a long way since then and computers are more powerful than ever before. I remember using one of the first versions of <a href="http://www.research.ibm.com/hlt/html/body_history.html">IBM ViaVoice</a> which would quite literally bog down my computer when I tried using it. The quality of speech recognition software has vastly improved and using a clever stack of technology, you can even use speech recognition on your iPhone (the <a href="http://www.tuaw.com/2009/12/08/dragon-dictation-comes-to-the-iphone-wow/">actual recognition is performed on a server</a>, but the effect is stunning nevertheless).</p>
<p>With all the hoopla around HTML 5, it would be quite a surprise if modern browsers didn't have something in store with regard to voice recognition. And sure enough, there is a W3C specification for a <a href="http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html">Speech Input API</a>. Looking at the list of authors might give us a hint as to which browser might support this API...</p>
<p>Using the speech input API is rather easy. All you have to do is to add the <code>x-webkit-speech</code> attribute to any <code>input</code> tag and you're done. If you're on a speech-enabled browsers (as of this writing, <a href="http://chrome.blogspot.com/2011/04/everybodys-talking-and-translating-with.html">only Chrome 11</a> supports this out of the box), you can check it out in the input field below. Just click on the microphone icon and start speaking:</p>
<input name="speechinput" size="40" placeholder="click the mic and start speaking" x-webkit-speech/>
<p>So, the other day I thought, "wouldn't it be cool if I could use voice recognition to look up my contacts on the social networks I am on?". Adding voice recognition support to a website you own is rather easy, as you only have to add the <code>x-webkit-speech</code> attribute to the respective input fields. Enhancing foreign sites, however, turns out to be a little bit more involved. Fortunately, Chrome can augment existing websites by way of so-called <a href="http://code.google.com/chrome/extensions/content_scripts.html">Content Scripts</a>, which are a part of the <a href="http://code.google.com/chrome/extensions/getstarted.html">Chrome Extensions API</a>.</p>
<p>Writing a Chrome Extension for speech-enabling existing text input fields on just about any website <a href="http://github.com/peterfriese/Speak2Search">was a matter of minutes</a>, thanks to the good documentation and some <a href="http://jquery.com/">jQuery</a> to walk the DOM. Putting on the finishing touches took me some more time, and I am proud to present you <a href="http://chrome.google.com/webstore/detail/peldinpdedgdcbdehomnpfndejpoibeb">Speak to Search</a> - a Chrome Extension that lets you talk with your browser. It works with virtually every website that uses regular HTML input fields. By making some smart assumptions, the extension will automatically submit the current form if the input field is a search field. If it is not, the focus will remain in the field and the form will not be submitted. That way, you can fill out e.g. an address form.</p>
<p>Here is a short video of me using Speak to Search to search for some people on Xing and LinkedIn. Please note that the extension is making sure the speech recognition engine is configured to recognize German names on Xing.</p>
<p><iframe width="610" height="347" src="http://www.youtube.com/embed/syMpQqMJcKU?hd=1" frameborder="0" allowfullscreen></iframe></p>
<p>Language makes us human - this is a quote from a <a href="http://www.pbs.org/wnet/humanspark/video/spark-blog-video-dr-steven-pinker-language-makes-us-human/212/">video</a> I found during the research for this blog post. I don't necessarily think voice recognition and speech synthesis will make computers more human, but both technologies certainly can help to create a more immersive experience. I am looking forward to seeing a broader use of the new audio capabilities of modern browsers. Feel free to <a href="http://github.com/peterfriese/Speak2Search">grab my code from Github</a> and create something new and exciting!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=p19rNOF9tAk:P0SmTjtW7tE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=p19rNOF9tAk:P0SmTjtW7tE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=p19rNOF9tAk:P0SmTjtW7tE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=p19rNOF9tAk:P0SmTjtW7tE:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/p19rNOF9tAk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/tired-of-typing-speak-to-your-computer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/tired-of-typing-speak-to-your-computer/</feedburner:origLink></item>
		<item>
		<title>Code Generation 2011 – Don’t miss out!</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/ZiWNZWiio9w/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ZiWNZWiio9w:zZpjAvbSRRQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ZiWNZWiio9w:zZpjAvbSRRQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ZiWNZWiio9w:zZpjAvbSRRQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ZiWNZWiio9w:zZpjAvbSRRQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/ZiWNZWiio9w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/code-generation-2011-dont-miss-out/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/code-generation-2011-dont-miss-out/</feedburner:origLink></item>
		<item>
		<title>Using NSPredicate to Filter Data</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/QsK8tSrufCo/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=QsK8tSrufCo:fZITiaoTXys:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=QsK8tSrufCo:fZITiaoTXys:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=QsK8tSrufCo:fZITiaoTXys:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=QsK8tSrufCo:fZITiaoTXys:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/QsK8tSrufCo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/using-nspredicate-to-filter-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/using-nspredicate-to-filter-data/</feedburner:origLink></item>
		<item>
		<title>Save a Tree, Put EclipseCon 2011 in Your Pocket</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/rnHbIRj1-RM/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=rnHbIRj1-RM:Quf4zh4pZaY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=rnHbIRj1-RM:Quf4zh4pZaY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=rnHbIRj1-RM:Quf4zh4pZaY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=rnHbIRj1-RM:Quf4zh4pZaY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/rnHbIRj1-RM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/save-a-tree-put-eclipsecon-2011-in-your-pocket/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/save-a-tree-put-eclipsecon-2011-in-your-pocket/</feedburner:origLink></item>
		<item>
		<title>Appropriate Use of MapKit</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/0hUhPirtGiQ/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=0hUhPirtGiQ:zBq613eVsN4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=0hUhPirtGiQ:zBq613eVsN4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=0hUhPirtGiQ:zBq613eVsN4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=0hUhPirtGiQ:zBq613eVsN4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/0hUhPirtGiQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/appropriate-use-of-mapkit/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/appropriate-use-of-mapkit/</feedburner:origLink></item>
		<item>
		<title>Three reasons why I think the HP TouchPad will rock the tablet market</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/7xrEP2jjNCs/</link>
		<comments>http://www.peterfriese.de/three-reasons-why-i-think-the-hp-touchpad-will-rock-the-tablet-market/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 08:38:26 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[HP]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[TouchPad]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=668</guid>
		<description><![CDATA[Yesterday, HP introduced the Touchpad, an iPad-like tablet device that is programmed with web technologies. While this certainly isn't the first attempt of a vendor to compete with Apple on the tablet market, I am convinced the TouchPad is a true challenger to the iPad. There are three reasons why the TouchPad might be a [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, <a href="http://www.engadget.com/2011/02/09/hp-posts-complete-think-beyond-event-video/">HP introduced</a> the <a href="http://www.palm.com/us/products/pads/touchpad/index.html">Touchpad</a>, an <del datetime="2011-02-10T23:30:52+00:00">iPad-like</del> tablet device that is programmed with web technologies. While this certainly isn't the first attempt of a vendor to compete with Apple on the tablet market, I am convinced the TouchPad is a true challenger to the iPad. There are three reasons why the TouchPad might be a real contender: the programming environment, the manufacturing process and security. <span id="more-668"></span>HP is definitely doing something right. Never before has one single Tablet thrilled the interwebs as much as the TouchPad - except for the iPad, of course. Even <a href="http://scobleizer.com/2011/02/09/hp-makes-google-look-even-more-creaky/">die-hard Apple</a> fans are thrilled.</p>
<p>Here's why I think HP's TouchPad will score a considerable market share:</p>
<ol>
<li>It's programmed with web technologies like HTML, CSS and JavaScript. Don't get me wrong - the iPad can also be programmed with web technologies: when the iPhone was first released and no one but Apple was allowed to write native apps, Steve himself told everyone that "mobile web applications are the future". And despite the fact Apple has opened it's SDK and we can now program the iPad / iPhone in Objective-C, many developers are more interested in writing apps with web technologies. Tools like PhoneGap and Appcelerator try to alleviate this situation, basically allowing you to wrap web code in more or less tiny wrapper apps so your web apps can be submitted to the App Store. However, most apps written using web technologies do not feel the same as real native apps on the iOS platform. So why do I think the situation will be better on the TouchPad? Well, because the TouchPad has been built for running web-based apps! It has been optimized for it. Web apps look stunningly great on the TouchPad. Now, every web developer can download the webOS SDK and get started writing apps for the TouchPad. It's a safe bet to assume there are more web developers out there than Objective-C developers, so it shouldn't take long until we've got a similar amount of apps for the TouchPad as we've got for the iPad.</li>
<li>The manufacturing process. HP has a very powerful production pipeline, capable of pumping out high volumes of devices. In <a href="http://www.itchannelplanet.com/trends/article.php/3920936/Gartner-Global-PC-Shipments-Total-351-Million-Units-in-2010-Gain-138-Percent-US-Q4-PC-Market-Slides-Nearly-7-Percent.htm">Q4/2010, they shipped 17.6</a> million PCs (<a href="http://www.apple.com/pr/library/2011/01/18results.html">Apple sold 7.33 million iPads</a> in the same quarter). So if they are serious about it, it should be easy for HP to both produce and distribute high volumes of TouchPads.</i>
<li>Security. When it comes to enterprise computing, security becomes a vital feature of your product. CIOs need to make sure to not compromise their company's security by introducing products and devices that have no proper support for security mechanisms. There have always been <a href="http://www.wired.com/gadgetlab/2009/07/iphone-encryption/">security concerns</a> with respect to the iOS platform: for a long time, there hasn't been a way to nuke a lost iOS device remotely. <a href="http://support.apple.com/kb/HT4175">It wasn't before iOS 4</a> that Apple introduced data protection APIs to secure data that apps store on the device. <a href="">WebOS has several security features built in</a> (not bolted on later) which make it rather attractive for enterprise computing right from the start.</li>
</ol>
<p>It's my firm belief that the release of the HP TouchPad is a milestone for the perception of personal computing in the long run. It looks great, we'll see tons of great apps for it in no time and HP as a major computer vendor has the power to push it to the market.</p>
<p>Good-bye, PC.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=7xrEP2jjNCs:t7HYhX1gy9I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=7xrEP2jjNCs:t7HYhX1gy9I:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=7xrEP2jjNCs:t7HYhX1gy9I:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=7xrEP2jjNCs:t7HYhX1gy9I:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/7xrEP2jjNCs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/three-reasons-why-i-think-the-hp-touchpad-will-rock-the-tablet-market/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/three-reasons-why-i-think-the-hp-touchpad-will-rock-the-tablet-market/</feedburner:origLink></item>
		<item>
		<title>What’s your number?</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/ikk2wR_t8xM/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ikk2wR_t8xM:AcIFKB3Qi5g:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ikk2wR_t8xM:AcIFKB3Qi5g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=ikk2wR_t8xM:AcIFKB3Qi5g:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=ikk2wR_t8xM:AcIFKB3Qi5g:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/ikk2wR_t8xM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/whats-your-number/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/whats-your-number/</feedburner:origLink></item>
		<item>
		<title>Your Windows IDE sucks? Replace it with Your Favorite Editor on the Mac!</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/6XMwKV_vUYM/</link>
		<comments>http://www.peterfriese.de/your-windows-ide-sucks-replace-it-with-your-favorite-editor-on-the-mac/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 22:11:11 +0000</pubDate>
		<dc:creator>Peter Friese</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Samsung]]></category>
		<category><![CDATA[symlink]]></category>
		<category><![CDATA[textmate]]></category>
		<category><![CDATA[TV]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.peterfriese.de/?p=643</guid>
		<description><![CDATA[For a current project, I need to use a Windows-based IDE that really sucks. So instead of letting the IDE degrade my productivity, I decided to use some combined Windows/Mac wizardry to solve the problem.The IDE in question is Samsung's TV App SDK. Basically, it's just a Windows-based Visual-Studio look-alike IDE with editor support for [...]]]></description>
			<content:encoded><![CDATA[<p>For a <a href="http://www.samsungsmarttvchallenge.eu/">current project</a>, I need to use a Windows-based IDE that really sucks. So instead of letting the IDE degrade my productivity, I decided to use some combined Windows/Mac wizardry to solve the problem.<span id="more-643"></span>The IDE in question is Samsung's TV App SDK. Basically, it's just a Windows-based Visual-Studio look-alike IDE with editor support for CSS, JavaScript and HTML and an Emulator for Samsung TV kits. Nothing too complicated, really. In fact, the editor is quite OK. </p>
<div id="attachment_647" class="wp-caption alignleft" style="width: 310px"><a class="lightbox"  title ="Samsung TV App SDK" href="http://www.peterfriese.de/wp-content/Samsung-TV-App-SDK.png"><img src="http://www.peterfriese.de/wp-content/Samsung-TV-App-SDK-300x208.png" alt="Samsung TV App SDK" title="Samsung TV App SDK" width="300" height="208" class="size-medium wp-image-647" /></a><p class="wp-caption-text">Samsung TV App SDK</p></div>
<p>The part about it that really sucks is the project management. How come tool vendors still think it's good style in 2010 to place the projects under <em>Program Files\Samsung TV Apps SDK\Apps</em>? There's no way to store your project files in a different location. The project open dialog just won't let you navigate to some other place:</p>
<div id="attachment_642" class="wp-caption alignleft" style="width: 310px"><a class="lightbox"  title ="Samsung TV App SDK Project Management Dialog" href="http://www.peterfriese.de/wp-content/Samsung_TV_App_SDK_ProjectManagement.png"><img src="http://www.peterfriese.de/wp-content/Samsung_TV_App_SDK_ProjectManagement-300x219.png" alt="Samsung TV App SDK Project Management Dialog" title="Samsung TV App SDK Project Management Dialog" width="300" height="219" class="size-medium wp-image-642" /></a><p class="wp-caption-text">Samsung TV App SDK Project Management Dialog</p></div>
<p>So I wanted to be able to edit my files on the Mac (using <a href="http://macromates.com/">TextMate</a>) while still using the good parts of the Samsung TV SDK (i.e., the Emulator).</p>
<p>I'm using VMware Fusion to run Windows 7 and the Samsung SDK (no, there is no version for the Mac). Most virtualization solutions offer a mechanism to share folders between the host and the guest OS. So I quickly set up folder sharing between my Mac and the guest OS, in this case Windows 7.</p>
<p>Now that I can see the project files both on the Mac and on the Windows machine, how can I make sure I can open the project in the Samsung TV SDK IDE? As I mentioned before, there's no way to tell the IDE to open projects form other locations than <em>Program Files\Samsung TV Apps SDK\Apps</em>!</p>
<p>After playing around with some more or less usable folder synchronization utilities, I came up with something most MacOS / Linux users should be familiar with: <a href="http://en.wikipedia.org/wiki/Symbolic_link">symbolic links</a>! While symlinks have been around in Unix-like OSes for ages, they have been rarely known to Windows users for most of the time. However, <a href="http://en.wikipedia.org/wiki/NTFS_symbolic_link">starting with Windows NT</a>, you can create symbolic links, hard links and junctions using a nifty little tool called <em><a href="http://www.howtogeek.com/howto/windows-vista/using-symlinks-in-windows-vista/">mklink</a></em>. Unfortunately, you're not allowed to run <em>mklink</em> if you're not an administrator. Using <em>runas</em> (which is Windows' equivalent of <em>sudo</em>), didn't help as the shared folders weren't visible to the admin user.</p>
<p>To cut a long story short, I found <a href="http://code.google.com/p/symlinker">Symlinker</a>, a UI tool that helps in creating symlinks on Windows. As it is a UI tool, you can run it with administrator privileges (by selecting Run as Admin from the context menu). Using a <a href="http://en.wikipedia.org/wiki/Path_(computing)">UNC</a> path, you can create a <a href="http://en.wikipedia.org/wiki/NTFS_symbolic_link">symlink</a> to a VMware shared folder and place this symlink in the location the Samsung IDE expects it to be.</p>
<p>Finally, I can edit my files on the Mac and run the app in Samsung's Emulator on my hosted Windows machine. And as the files on my Mac are mapped to the hosted Windows machine via a symlink, I do not suffer a synchronization lag - all files are updated instantaneously <img src='http://www.peterfriese.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=6XMwKV_vUYM:EdlAF2udzhc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=6XMwKV_vUYM:EdlAF2udzhc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=6XMwKV_vUYM:EdlAF2udzhc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=6XMwKV_vUYM:EdlAF2udzhc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/6XMwKV_vUYM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.peterfriese.de/your-windows-ide-sucks-replace-it-with-your-favorite-editor-on-the-mac/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.peterfriese.de/your-windows-ide-sucks-replace-it-with-your-favorite-editor-on-the-mac/</feedburner:origLink></item>
		<item>
		<title>How to Use the Gyroscope of Your iPhone in a Mobile Web App</title>
		<link>http://feedproxy.google.com/~r/FormFollowsFunction/~3/t3QhwdpSN6Q/</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>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=t3QhwdpSN6Q:-8X8FqtdPro:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=t3QhwdpSN6Q:-8X8FqtdPro:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?i=t3QhwdpSN6Q:-8X8FqtdPro:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:6stttfHX83w"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=6stttfHX83w" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FormFollowsFunction?a=t3QhwdpSN6Q:-8X8FqtdPro:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/FormFollowsFunction?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FormFollowsFunction/~4/t3QhwdpSN6Q" height="1" width="1"/>]]></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>
		<feedburner:origLink>http://www.peterfriese.de/how-to-use-the-gyroscope-of-your-iphone-in-a-mobile-web-app/</feedburner:origLink></item>
	</channel>
</rss>

