<?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/" version="2.0">

<channel>
	<title>Cocoa Is My Girlfriend</title>
	
	<link>http://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Mon, 20 May 2013 17:52:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/CocoaIsMyGirlfriend" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="cocoaismygirlfriend" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Creating A Happy Appy Song</title>
		<link>http://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/</link>
		<comments>http://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/#comments</comments>
		<pubDate>Mon, 20 May 2013 17:52:43 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[Promotion]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2193</guid>
		<description><![CDATA[<p>App developers need ways to promote their apps and audio and video provide a way to do that. At a recent iOS developer camp in Colorado I gave a talk in which I demonstrated some ways developers can create their own creative content like audio and video in-house. In one segment I demonstrated a technique [...]</p><p>The post <a href="http://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/">Creating A Happy Appy Song</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>App developers need ways to promote their apps and audio and video provide a way to do that. At a recent iOS developer camp in Colorado I gave a talk in which I demonstrated some ways developers can create their own creative content like audio and video in-house. In one segment I demonstrated a technique that I refer to as creating a Happy Appy Song. What is it, you ask. You&#8217;ve heard it. It&#8217;s a happy sounding fanciful tune that plays in the background as some narrator describes the wonders and benefits of an app (or other product for that matter). The basic premise of the happy appy song is that, first of all, it&#8217;s easy to create, but second there&#8217;s a simple formula. Here is all you need:</p>

<ol>
<li>A happy chord progression in a major key</li>
<li>A simple drumbeat</li>
<li>A glockenspiel sound</li>
</ol>

<p>And now I present to you, Creating a Happy Appy Song</p>

<iframe src="http://player.vimeo.com/video/66576979?byline=0&portrait=0" width="600" height="400" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen class=""></iframe>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/">Creating A Happy Appy Song</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/05/20/creating-a-happy-appy-song/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS Crash Logs On iCloud Synced Devices</title>
		<link>http://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/</link>
		<comments>http://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/#comments</comments>
		<pubDate>Fri, 26 Apr 2013 18:54:44 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2181</guid>
		<description><![CDATA[<p>I tweeted a call for help today to figure out how to get crash logs from a device that syncs with iCloud rather than with iTunes and a cable. The issue is that you can only sync with one and not both and switching between them willy nilly can be perilous unless you enjoy losing [...]</p><p>The post <a href="http://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/">iOS Crash Logs On iCloud Synced Devices</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>I tweeted a call for help today to figure out how to get crash logs from a device that syncs with iCloud rather than with iTunes and a cable. The issue is that you can only sync with one and not both and switching between them willy nilly can be perilous unless you enjoy losing your data just for the fun of it.</p>

<p>Several responses suggested taking things into my own hands by rolling my own logging mechanism when building an app I intend to ship. I think this is likely the approach I will take in the future, however, it doesn&#8217;t help my immediate problem. How do I get crash logs from an app I already shipped that is running on client&#8217;s device not physically located near me? Here&#8217;s a summary of what people suggested. Drill down in the settings app and copy the contents of the crash log like this (click/tap to enlarge):</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2013/04/CrashLogsDrillDown-300x76.png" alt="Crash Logs Drilldown" width="300" height="76" class="alignleft size-medium wp-image-2183" /></a></p>

<p>Then, paste that into an email:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2013/04/PasteInEmail-300x266.png" alt="Paste In Email" width="300" height="266" class="alignleft size-medium wp-image-2182" /></a></p>

<p>Then you can send the crash log to any email address you specify.</p>

<p>It certainly is not a pretty approach, but it will get the job done.</p>

<p>Thanks to the folks who responded to my call for help, <a href="https://twitter.com/davidiom">@davidiom</a>, <a href="https://twitter.com/therealkerni">@therealkerni</a>, <a href="https://twitter.com/thenighttrader">@thenighttrader</a>, and <a href="https://twitter.com/rckoenes">@rckoenes</a>. I appreciate it!</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/">iOS Crash Logs On iCloud Synced Devices</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/04/26/ios-crash-logs-on-icloud-synced-devices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>StackOverflow Reputation As A Hiring Metric</title>
		<link>http://www.cimgf.com/2013/04/03/stackoverflow-reputation-as-a-hiring-metric/</link>
		<comments>http://www.cimgf.com/2013/04/03/stackoverflow-reputation-as-a-hiring-metric/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 19:44:16 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2150</guid>
		<description><![CDATA[<p>I&#8217;ve been using StackOverflow nearly since it started back in 2008. I remember when it first started there didn&#8217;t seem to be much going on and so I forgot about it for a time. Then, one day, while searching the interwebs for an answer to a programming question, SO was the first hit in my [...]</p><p>The post <a href="http://www.cimgf.com/2013/04/03/stackoverflow-reputation-as-a-hiring-metric/">StackOverflow Reputation As A Hiring Metric</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been using StackOverflow nearly since it started back in 2008. I remember when it first started there didn&#8217;t seem to be much going on and so I forgot about it for a time. Then, one day, while searching the interwebs for an answer to a programming question, SO was the first hit in my search results. At that point I went back and started using it regularly&#8211;not only to find answers, but to offer my own experiences and expertise to help others. It&#8217;s a great site and I have nothing but high praise for its founders, <a href="http://en.wikipedia.org/wiki/Jeff_Atwood" title="Jeff Atwood Wikipedia Entry">Jeff Atwood</a> and <a href="http://en.wikipedia.org/wiki/Joel_Spolsky" title="Joel Spolsky Wikipedia Entry">Joel Spolsky</a>. The entire StackExchange network is an impressive engineering achievement.<span id="more-2150"></span></p>

<p>Since that time, I have racked up a few reputation points and I spend a decent amount of time on the site nearly every day trying to make a difference. What difference, you might ask. Well, I think participating in our community should inspire everyone to learn and to share. StackOverflow is one of the best places to do that. Sure blog posts and the like are helpful too, however, the nature of StackOverflow is to provide helpful and concise answers to questions. It makes it a perfect place to make a true contribution without having to go to a lot of effort. I find the best answers to be the ones that cut right to the chase either citing another reference or providing a snippet of code that gives you exactly what you need. Of course, copying and pasting from SO means I have to strip out those damn dots all the time, but I digress. (Yes, I realize that ship has sailed. Please don&#8217;t start a dot vs no-dot war in the comments. Use dots if you want. I don&#8217;t care. Just don&#8217;t insist that I do the same.)</p>

<h2>Self Maintaining</h2>

<p>As anyone who has spent any time at all on the site will notice, the higher your reputation, the more privileges you obtain. Eventually you become a moderator. You can edit other&#8217;s posts. You can close poor questions. You can delete poor answers. The community ensures that you are abiding by all of the rules&#8211;and, frankly, there are many of them. Take a look at the meta site if you think I&#8217;m joking. Don&#8217;t worry if you don&#8217;t know them all, though. If you mess up, the community will correct you. You can count on that like clockwork. I know that sounds a bit sarcastic and it probably is. I&#8217;ve been moderated before and I didn&#8217;t like it. However, in the end, you can&#8217;t argue with the results you get with StackOverflow and the people who moderated me were right. They were enforcing the rules&#8211;which is, as it turns out, good for everyone. With programming related questions, SO is nearly always the first hit in a Google search. And when you get to the site, how often does it contain the exact answer you were looking for? I would say for me personally, that metric is probably in the 80 to 90 percentile. The StackOverflow philosophy works and you can&#8217;t legitimately dispute that.</p>

<h2>So Why Should I Care?</h2>

<p>If you think that going out and getting the highest reputation out there is a worthy goal, I will go ahead and deflate that notion by pointing you to the site&#8217;s über contributor, <a href="http://stackoverflow.com/users/22656/jon-skeet" title="Jon Skeet">Jon Skeet</a>. His reputation is up over half a million at the time of this writing and it just keeps going. You couldn&#8217;t catch him now if you tried. Jon has behind him a ton of momentum because he has made so many contributions. His reputation increases in large quantities every day. Even if he stopped contributing right this minute, his reputation would continue to grow on indefinitely as long as the site was still going. It&#8217;s like compounding interest at this point. If you figure that he started (according to his profile) 4.5 years ago (sometime around the site&#8217;s beginning) and his reputation is almost 550K, he would be averaging about 335 reputation points PER DAY! That astonishing! I&#8217;m lucky to achieve that in a month. Now, you can&#8217;t break that down into how many responses he&#8217;s providing per day, but you can be sure it&#8217;s a lot. As I said, Jon is the über contributor.</p>

<p>On the other side of the equation, though, for some people lurking on StackOverflow is sufficient for their needs. They just take what they need and then they&#8217;re gone. That&#8217;s great for them, but I submit to you that participating in the community means you need to get an account and start responding instead of just consuming. No, you&#8217;re not likely to achieve Jon Skeet&#8217;s reputation. Of course setting Jon as the standard is not right. There&#8217;s even a meta question about Jon Skeet that elicits comments about Jon in a <em>Chuck Norris Facts</em> format (Excerpt: &#8220;Jon Skeet can divide by zero.&#8221;, &#8220;Jon Skeet coded his last project entirely in Microsoft Paint, just for the challenge.&#8221;, etc.). It&#8217;s hilarious and you should <a href="http://meta.stackoverflow.com/questions/9134/jon-skeet-facts" title="Jon Skeet Facts">take a look</a>. But that&#8217;s beside the point. While reputation is the metric&#8211;the currency of StackOverflow, if you will, it&#8217;s a currency that is only accepted in the community. Nobody will offer directly to pay you more money if you achieve a higher reputation, however, indirectly it may.</p>

<h2>What Does It Mean to Use StackOverflow Reputation As A Hiring Metric?</h2>

<p>Currently in our industry there seems to be plenty of work going around. Finding help on programming projects&#8211;and I don&#8217;t mean just iOS projects; any programming projects&#8211;is a bit of a challenge. Developers are more scarce than ever. These days though, when you&#8217;re vetting someone to work on your team you still have to consider carefully whether that person will be a good fit with your philosophy. Because of this, the traditional resume has lost value when presented by itself. It doesn&#8217;t tell the whole story. The question to your potential employee or contractor has become, what have you done? How would I know your work? Can you <strong>show</strong> me? If they don&#8217;t have a publicly accessible answer along with the resume, the answer becomes suspect. If, instead, they point you toward community contributions, you have a tangible sense of their value. Community contributions matter immensely.</p>

<p>I can hear some of you now, though. You&#8217;re saying, yes, but isn&#8217;t it true that <em>those who can&#8217;t do, teach? Isn&#8217;t that what people on StackOverflow are doing&#8211;just teaching?</em> My answer is a resounding <strong>NO!</strong> Look at the contributor&#8217;s answers. You can tell the difference between pre-cooked (or half-baked?) responses and ones that come from experience. It&#8217;s very plain and if the responses are bad, they get mod&#8217;ed down. And if you pay close enough attention, you&#8217;ll see that some of the contributors are major players. I&#8217;ve personally learned a ton from contributors who are actually seasoned Apple Engineers&#8211;people who know the internals inside and out&#8211;not because they read about it or heard it might work some way, but rather because they actually wrote the code behind the technology.</p>

<p>In the end, I think a person&#8217;s StackOverflow reputation is directly correlated to their philosophy about community and the notion that we should all pitch in and contribute. I want to work with the people who believe that helping others out of the overflow of their own experience is important. Keeping it all to yourself isn&#8217;t beneficial to anyone.</p>

<h2>Conclusion</h2>

<p>Just as in life, the reputation you build matters. I suggest that if you are spending your time just consuming the great resource that StackOverflow is, you should consider a new view of things. Consider how you might contribute and use your own experience to help others in this great community of ours. And keep in mind that if I need your help with a project, I&#8217;m checking your StackOverflow profile to see how you&#8217;re contributing to the community. I think it is a positive thing to consider StackOverflow reputation as a hiring metric. You don&#8217;t have to have to be Jon Skeet, but the difference between no or little contributions and a noticeable effort will make a difference in my mind. It should make a difference in yours as well. Until next time.</p>

<h2>Postscript</h2>

<p>You may also find StackOverflow Careers an interesting site for posting your experience or listing a req you&#8217;re trying to fill. They do a good job at vetting both sides of the hiring equation. Take a look at <a href="http://careers.stackoverflow.com/" title="StackOverflow Careers">http://careers.stackoverflow.com/</a>. <del datetime="2013-04-06T14:50:47+00:00">If you don&#8217;t have an account and want one, email me at matt at cimgf dot com. I have one invitation remaining at this time. (I&#8217;ll remove this remark once it&#8217;s claimed.)</del></p>

<p><strong>Disclaimer</strong>: The thoughts and opinions expressed in this post are mine alone. I have no affiliation whatsoever (other than being a regular contributor) to StackOverflow, any Stack Exchange sites, or StackOverflow Careers.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/04/03/stackoverflow-reputation-as-a-hiring-metric/">StackOverflow Reputation As A Hiring Metric</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/04/03/stackoverflow-reputation-as-a-hiring-metric/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Anonymous Image File Upload in iOS With Imgur</title>
		<link>http://www.cimgf.com/2013/03/18/anonymous-image-file-upload-in-ios-with-imgur/</link>
		<comments>http://www.cimgf.com/2013/03/18/anonymous-image-file-upload-in-ios-with-imgur/#comments</comments>
		<pubDate>Mon, 18 Mar 2013 18:03:27 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2128</guid>
		<description><![CDATA[<p>It seems like a pretty useful feature, anonymous image file upload in iOS with imgur. If you need to upload images and don&#8217;t want to fool with some authentication mess like OAuth this technique is perfect. There are libraries that have simplified the OAuth process, however, it&#8217;s nice to be able to just initiate an [...]</p><p>The post <a href="http://www.cimgf.com/2013/03/18/anonymous-image-file-upload-in-ios-with-imgur/">Anonymous Image File Upload in iOS With Imgur</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>It seems like a pretty useful feature, anonymous image file upload in iOS with imgur. If you need to upload images and don&#8217;t want to fool with some authentication mess like OAuth this technique is perfect. There are libraries that have simplified the OAuth process, however, it&#8217;s nice to be able to just initiate an upload, get a result URL back and be on your way. No fuss, no muss. That&#8217;s what I was looking for, so I wrote a little app that demonstrates how to do exactly that.
<span id="more-2128"></span></p>

<h2>Imgur and You</h2>

<p>There are numerous image upload services out there, but imgur seems to be the simplest to implement. Now, that being said, it&#8217;s pretty difficult to find any sample code out there that is up to date and works with their v3 API. I found a library that is several years old and only works with the v2 API, but that seemed odd to me considering how long their v3 API has been around. This means either developers don&#8217;t have a need for this kind of service or that getting it to work is too obscure and/or difficult. The bottom line for me was realizing that the API is expecting a multi-part form with properly formatted data parameters. Once I figured that out, it was pretty straight forward. I wrote a little demo app you can <a href="https://github.com/perlmunger/IMGURUploader" title="IMGUR Uploader">get on github</a> that shows how to do it.</p>

<p>The first thing you need to do, though, is head over to <a href=" https://api.imgur.com/oauth2/addclient" title="IMGUR Add Client Link">https://api.imgur.com/oauth2/addclient</a> and register your app. A client ID will be generated and emailed to you. You can then plug it in and start posting images.</p>

<h2>The Basic Implementation</h2>

<p>All you need to do is call a class method on my <code>MLIMGURUploader</code> class and initiate your upload with an <code>NSData</code> object and your client ID.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>didTapUploadButton<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>clientID <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;YOUR_CLIENT_ID_HERE&quot;</span>;
&nbsp;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>title <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self titleTextField<span style="color: #002200;">&#93;</span> text<span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>description <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self descriptionTextField<span style="color: #002200;">&#93;</span> text<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  __weak MLViewController <span style="color: #002200;">*</span>weakSelf <span style="color: #002200;">=</span> self;
  <span style="color: #11740a; font-style: italic;">// Load the image data up in the background so we don't block the UI</span>
  dispatch_async<span style="color: #002200;">&#40;</span>dispatch_get_global_queue<span style="color: #002200;">&#40;</span>DISPATCH_QUEUE_PRIORITY_DEFAULT, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>, <span style="color: #002200;">^</span><span style="color: #002200;">&#123;</span>
    UIImage <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage imageNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;balloons.jpg&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>imageData <span style="color: #002200;">=</span> UIImageJPEGRepresentation<span style="color: #002200;">&#40;</span>image, 1.0f<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>MLIMGURUploader uploadPhoto<span style="color: #002200;">:</span>imageData 
                           title<span style="color: #002200;">:</span>title 
                     description<span style="color: #002200;">:</span>description 
                   imgurClientID<span style="color: #002200;">:</span>clientID completionBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>result<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      dispatch_async<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;">^</span><span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>weakSelf linkTextView<span style="color: #002200;">&#93;</span> setText<span style="color: #002200;">:</span>result<span style="color: #002200;">&#93;</span>;
      <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span> failureBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSURLResponse</span> <span style="color: #002200;">*</span>response, <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error, NSInteger status<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      dispatch_async<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;">^</span><span style="color: #002200;">&#123;</span>
      <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
      <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIAlertView alloc<span style="color: #002200;">&#93;</span> initWithTitle<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Upload Failed&quot;</span>
                                  message<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@ (Status code %d)&quot;</span>, 
                                                   <span style="color: #002200;">&#91;</span>error localizedDescription<span style="color: #002200;">&#93;</span>, status<span style="color: #002200;">&#93;</span>
                                 delegate<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                        cancelButtonTitle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                        otherButtonTitles<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;OK&quot;</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span> show<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;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>This demo app just takes an <code>NSData</code> containing the image that we just added to the project (retrieved with a call to <code>[UIImage imageNamed:]</code>), a title, and a description and passes them on to the uploader.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2013/03/imguruploader.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2013/03/imguruploader.png" alt="Anonymous Image File Upload in iOS With Imgur:IMGUR Uploader" width="392" height="519" class="alignleft size-full wp-image-2131" /></a></p>

<p>When the request returns, you receive back an <code>NSString</code> containing the URL to the newly created image.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>MLIMGURUploader uploadPhoto<span style="color: #002200;">:</span>imageData 
                       title<span style="color: #002200;">:</span>title 
                 description<span style="color: #002200;">:</span>description 
               imgurClientID<span style="color: #002200;">:</span>clientID completionBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>result<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// The variable &quot;result&quot; contains the URL pointing to the raw image</span>
&nbsp;
<span style="color: #002200;">&#125;</span> failureBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSURLResponse</span> <span style="color: #002200;">*</span>response, <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error, NSInteger status<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Analyze the error. Something went wrong.</span>
&nbsp;
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<h2>Code Purity</h2>

<p>It&#8217;s often difficult to achieve code purity where you&#8217;re only using built in libraries to develop your apps, but over the years I&#8217;ve become much more of a purist and try to eliminate the need for libraries as much as possible. I haven&#8217;t always been that way. Shortcuts seem like a good idea when you&#8217;re in a hurry to get something done, but in the end they often just end up biting you.</p>

<p>With this code purity idea in mind, here is the result for the imgur uploader&#8211;all in a single class method that only uses built in foundation libraries:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>uploadPhoto<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSData</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>imageData
              title<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>title
        description<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>description
      imgurClientID<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>clientID
    completionBlock<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span> result<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>completion
       failureBlock<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSURLResponse</span> <span style="color: #002200;">*</span>response, <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error, NSInteger status<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>failureBlock
<span style="color: #002200;">&#123;</span>
  NSAssert<span style="color: #002200;">&#40;</span>imageData, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Image data is required&quot;</span><span style="color: #002200;">&#41;</span>;
  NSAssert<span style="color: #002200;">&#40;</span>clientID, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Client ID is required&quot;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>urlString <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;https://api.imgur.com/3/upload.json&quot;</span>;
  <span style="color: #400080;">NSMutableURLRequest</span> <span style="color: #002200;">*</span>request <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableURLRequest</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> ;
  <span style="color: #002200;">&#91;</span>request setURL<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span>urlString<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>request setHTTPMethod<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;POST&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSMutableData</span> <span style="color: #002200;">*</span>requestBody <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableData</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>boundary <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;---------------------------0983745982375409872438752038475287&quot;</span>;
&nbsp;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>contentType <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;multipart/form-data; boundary=%@&quot;</span>, boundary<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>request addValue<span style="color: #002200;">:</span>contentType forHTTPHeaderField<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Content-Type&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Add client ID as authrorization header</span>
  <span style="color: #002200;">&#91;</span>request addValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Client-ID %@&quot;</span>, clientID<span style="color: #002200;">&#93;</span> forHTTPHeaderField<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Authorization&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Image File Data</span>
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;--%@<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span>, boundary<span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Content-Disposition: attachment; name=<span style="color: #2400d9;">\&quot;</span>image<span style="color: #2400d9;">\&quot;</span>; filename=<span style="color: #2400d9;">\&quot;</span>.tiff<span style="color: #2400d9;">\&quot;</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Content-Type: application/octet-stream<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithData<span style="color: #002200;">:</span>imageData<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Title parameter</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>title<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;--%@<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span>, boundary<span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Content-Disposition: form-data; name=<span style="color: #2400d9;">\&quot;</span>title<span style="color: #2400d9;">\&quot;</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span><span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>title dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Description parameter</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>description<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;--%@<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span>, boundary<span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Content-Disposition: form-data; name=<span style="color: #2400d9;">\&quot;</span>description<span style="color: #2400d9;">\&quot;</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span><span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span><span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>description dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #002200;">&#91;</span>requestBody appendData<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;--%@--<span style="color: #2400d9;">\r</span><span style="color: #2400d9;">\n</span>&quot;</span>, boundary<span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>request setHTTPBody<span style="color: #002200;">:</span>requestBody<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURLConnection</span> sendAsynchronousRequest<span style="color: #002200;">:</span>request 
                                     queue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSOperationQueue</span> mainQueue<span style="color: #002200;">&#93;</span> 
                         completionHandler<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSURLResponse</span> <span style="color: #002200;">*</span>response, <span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data, <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>responseDictionary <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization JSONObjectWithData<span style="color: #002200;">:</span>data 
                                                                       options<span style="color: #002200;">:</span>NSJSONReadingMutableContainers 
                                                                         error<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>responseDictionary valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;data.error&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>failureBlock<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
          <span style="color: #11740a; font-style: italic;">// If no error has been provided, create one based on the response received from the server</span>
          error <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSError</span> errorWithDomain<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;imguruploader&quot;</span> 
                                      code<span style="color: #002200;">:</span><span style="color: #2400d9;">10000</span> 
                                  userInfo<span style="color: #002200;">:</span>@<span style="color: #002200;">&#123;</span>NSLocalizedFailureReasonErrorKey <span style="color: #002200;">:</span> 
                                                 <span style="color: #002200;">&#91;</span>responseDictionary valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;data.error&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
        failureBlock<span style="color: #002200;">&#40;</span>response, error, <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>responseDictionary valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;status&quot;</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
      <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>completion<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        completion<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>responseDictionary valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;data.link&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
      <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<h2>Request Results</h2>

<p>A successful request will provide a URL that points to the raw image you uploaded to the service. If you would prefer to access the imgur link that displays their site chrome and the title and description your provided in the upload, simply remove the file extension. So, for example, the url <a href="http://i.imgur.com/bQzUcIp.jpg">http://i.imgur.com/bQzUcIp.jpg</a> will provide the raw image, the link <a href="http://i.imgur.com/bQzUcIp">http://i.imgur.com/bQzUcIp</a> provides the imgur site wrapped version.</p>

<h2>Conclusion</h2>

<p>I&#8217;m glad that in the end this process of anonymously uploading an image file was pretty trivial. Though you never know with some of these services these days&#8211;they could change the way it works at any time. Until then, though, I hope it will help you as well. Until next time.</p>

<p><a href="https://github.com/perlmunger/IMGURUploader" title="IMGUR Uploader">Get the project on GitHub</a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/03/18/anonymous-image-file-upload-in-ios-with-imgur/">Anonymous Image File Upload in iOS With Imgur</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/03/18/anonymous-image-file-upload-in-ios-with-imgur/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Querying Objective-C Data Collections</title>
		<link>http://www.cimgf.com/2013/02/05/querying-objective-c-data-collections/</link>
		<comments>http://www.cimgf.com/2013/02/05/querying-objective-c-data-collections/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 22:18:51 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[KVO/KVC]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2052</guid>
		<description><![CDATA[<p>In my Xcode LLDB Tutorial, I mention using the debugger to interrogate data collections. Well, I wanted to elaborate on that idea a little because there are some techniques you can use for querying objective-c data collections that are very powerful. If you develop apps for clients, you my be one of the lucky ones&#8211;the [...]</p><p>The post <a href="http://www.cimgf.com/2013/02/05/querying-objective-c-data-collections/">Querying Objective-C Data Collections</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>In my <a href="http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/" title="Xcode LLDB Tutorial">Xcode LLDB Tutorial</a>, I mention using the debugger to interrogate data collections. Well, I wanted to elaborate on that idea a little because there are some techniques you can use for querying objective-c data collections that are very powerful.</p>

<p>If you develop apps for clients, you my be one of the lucky ones&#8211;the ones who actually get to model your data and use Core Data to store and access it. But I&#8217;m betting there are many of you who aren&#8217;t the lucky ones&#8211;or at least not on all of your projects. From time to time you have to deal with data in whatever format your client gives it to you. Maybe you&#8217;ve even suggested taking the CSVs or Plists (or whatever other formats clients have come up with to ruin your life) and actually loading those into Core Data. But they don&#8217;t get Core Data and they shoot down the idea. Well, you may want to just walk away from the gig. However, if you&#8217;re like me, you&#8217;ve got bills to pay and clients (the good ones at least) tend to help you accomplish that. Well, fortunately for us, Objective-C makes dealing with this kind of data manageable using a little technique known as KVC, Key-Value-Coding, with array filtering and sorting.</p>

<p>This is not an advanced topic, so if you&#8217;re already familiar with how KVC and array filtering and sorting works, this post may not help you as much. But for those of you who are fairly new to iOS development, you need to know about this magical feature of the language as all the senior iOS developers use it and you should too.<span id="more-2052"></span></p>

<h2>Querying Objective-C Data Collections Is As Easy As a Where Clause</h2>

<p>I&#8217;m going to assume that you have some experience with relational databases. In a regular SQL query, when you want to filter a list of records based on some criteria, you use a where clause to ensure that you only get back the records you want from the database. Say, for example you wanted to query a list of hospitals by county. Your query might look something like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> hospitals <span style="color: #993333; font-weight: bold;">WHERE</span> county <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CLARKE'</span></pre></td></tr></table></div>


<p>The record set you get back after this query should only be the hospitals found in Clarke county.</p>

<p>Let&#8217;s consider an array of dictionary objects&#8211;each one of which has a set of keys and values representing each of fields in a hospital record. You&#8217;ve loaded this data into an NSArray from a property list that&#8217;s been embedded in your app. Say each hospital record in the array is declared as a dictionary and looks something like this when printed out in the debugger:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#123;</span>
    Address <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;220 Hospital Drive&quot;</span>;
    City <span style="color: #002200;">=</span> Jackson;
    County <span style="color: #002200;">=</span> CLARKE;
    Hospital <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;JACKSON MEDICAL CENTER--010128&quot;</span>;
    State <span style="color: #002200;">=</span> AL;
    Zip <span style="color: #002200;">=</span> <span style="color: #2400d9;">36545</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>There are thousands of these in your array, so how do you get only the ones where the county is Clarke, for example?</p>

<p>Well, it&#8217;s simple and similar to our SQL query:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>filteredItems <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>hospitals filteredArrayUsingPredicate<span style="color: #002200;">:</span>
                                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County == %@&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Clarke&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>Now <code>filteredItems</code> contains only the hospital records where the county is Clarke.</p>

<p>Let&#8217;s say that now you only want to get a list of the hospital names in the array. You can simply specify the name of that field as a key path, which will result in another array. Here&#8217;s what I mean</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>hospitalNamesInClarke <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>filteredItems valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Hospital&quot;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>The array, <code>hospitalNamesInClarke</code> now contains a list of strings for all of the hospitals in Clarke county Alabama.</p>

<h2>Delving Deeper</h2>

<p>Just for discussion sake, let&#8217;s think about what programmers often do when they first learn object-oriented programming. They often build complex object hierarchies to model all of the data they have to work with. Don&#8217;t get me wrong, when using Core Data, I take advantage of <a href="http://rentzsch.github.com/mogenerator/" title="mogenerator">mogenerator</a> to generate my managed objects so that I can add some smart methods to my model objects for convenience and clarity. However, when I get a data stream back from, for example, a JSON payload, it doesn&#8217;t make sense to create a separate model class to hold my data until I can parse them into Core Data. It makes much more sense to leave them as dictionaries and just query them directly using key value coding. Consider a single record stored in memory as a dictionary. It might look something like this:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2013/01/singlerecord.png" alt="Single Hospital Record" width="336" height="238" class="alignleft size-full wp-image-2060" /></p>

<p>If you were to take this dictionary and rotate it clockwise, making the keys actually a header&#8211;something like this:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2013/01/singlerecordhoriz.png" alt="Querying Objective-C Data Collections: Single Record Table" width="604" height="101" class="alignleft size-full wp-image-2059" /></p>

<p>Then consider a bunch of records in rows like this:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2013/01/multiplerowstable.png" alt="Querying Objective-C Data Collections: Multiple Records" width="602" height="196" class="alignleft size-full wp-image-2064" /></p>

<p>It&#8217;s starting to look familiar isn&#8217;t it? The database table analogy makes a lot more sense when you look at it this way. An array of dictionaries can be thought of as an array of records you can run queries on.</p>

<h2>Sorting, Filtering, and Aggregating</h2>

<p>Yep. It&#8217;s all possible. We&#8217;ve already talked about filtering. Remember this code from earlier:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>filteredItems <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>hospitals filteredArrayUsingPredicate<span style="color: #002200;">:</span>
                                <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County == %@&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CLARKE&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>Well, sorting is just as easy:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>sortedItems <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>hospitals sortedArrayUsingDescriptors<span style="color: #002200;">:</span>@<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSortDescriptor</span> 
                                               sortDescriptorWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County&quot;</span> ascending<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>Or you could have multiple sort descriptors:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>sortedItems <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>hospitals sortedArrayUsingDescriptors<span style="color: #002200;">:</span>@<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSortDescriptor</span> 
                                               sortDescriptorWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;State&quot;</span> ascending<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>,
                                                                   <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSortDescriptor</span> 
                                               sortDescriptorWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County&quot;</span> ascending<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>This sort will sort on State first and then County.</p>

<p>Aggregating your data is also really powerful. Say you have added another &#8220;column&#8221; to your dictionary record called <code>AnnualERVisitors</code>. If you wanted to get a sum of all the ER visitors for all hospitals in a certain county, you could do a filter first, and then perform a sum on the results. Something like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>filteredItems <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>hospitals filteredArrayUsingPredicate<span style="color: #002200;">:</span>
                                <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County == %@&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CLARKE&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #400080;">NSNumber</span> <span style="color: #002200;">*</span>totalERVisitors <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>filteredItems valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;@sum.AnnualERVisitors&quot;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>The variable <code>totalERVisitors</code> now contains the sum of all of the <code>AnnualERVisitors</code> values in Clarke county. This special operator, @sum, provides the ability to automatically sum all of the values in the <code>AnnualERVisitors</code> field. You can now manipulate that <code>NSNumber</code> any way you like by getting its primitive value, for example:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">NSInteger totalVisitorsCount <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>totalERVisitors integerValue<span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">// Do a little math. Make a little love. Get down tonight.</span></pre></td></tr></table></div>


<p>So you&#8217;re probably curious about what else you could do. First, let&#8217;s consider the list of operators we have at our disposal. Here are the list of operators according to the <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html" title="KVC Collection Operators">Key-Value Programming Guide</a>:</p>

<h3>Collection Operators</h3>

<ul>
<li>@sum</li>
<li>@avg</li>
<li>@count</li>
<li>@max</li>
<li>@min</li>
</ul>

<h3>Object Operators</h3>

<ul>
<li>@distinctUnionOfObjects</li>
<li>@unionOfObjects</li>
</ul>

<h3>Array and Set Operators</h3>

<ul>
<li>@distinctUnionOfArrays</li>
<li>@unionOfArrays</li>
<li>@distinctUnionOfSets</li>
</ul>

<p>If you want detailed descriptions of each of these operators, follow the link above to the Apple website.</p>

<p>In my <a href="http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/" title="Xcode LLDB Tutorial">Xcode LLDB Tutorial</a> I cover using the debug terminal to analyze/interrogate your data structures. In the <a href="https://github.com/perlmunger/CollectionSearch" title="Querying Objective-C Data Collections: Collection Search Sample Project">sample project</a> I&#8217;ve included with this post, you can use the same techniques from that tutorial to debug and set a breakpoint at the end of the <code>viewDidLoad:</code> method. It should look something like this:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2013/01/hospitalsdictionary.png" alt="Querying Objective-C Data Collections: Code for viewDidLoad:" width="663" height="558" class="alignleft size-full wp-image-2079" /></p>

<p>When it breaks, enter this line into the debug terminal:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSNumber</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>_hospitals filteredArrayUsingPredicate<span style="color: #002200;">:</span>
                                       <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSPredicate</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County == %@&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Clarke&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> 
                                                                           valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;@sum.AnnualERVisitors&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>This will produce the following output:</p>

<p><pre>
(lldb) po (NSNumber<em>)[(NSArray</em>)[_hospitals filteredArrayUsingPredicate:(NSPredicate*)[NSPredicate predicateWithFormat:@"County == %@", @"Clarke"]] valueForKeyPath:@"@sum.AnnualERVisitors"]
$1 = 0x080688a0 9744
(lldb)
</pre></p>

<p>This has taken all of the values in the <code>AnnualERVisitors</code> &#8220;column&#8221; and added them together giving us a result of 9,744 annual visitors in Clarke county. Say we wanted to get the average of all visitors in the hospitals in our list. Try this command in the debug console:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span>_hospitals valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;@avg.AnnualERVisitors&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>And this will produce the following output:</p>

<p><pre>
(lldb) po [_hospitals valueForKeyPath:@"@avg.AnnualERVisitors"]
$2 = 0x08068a00 4575.25
(lldb)
</pre></p>

<p>The <code>@avg</code> operator has returned the average ER visitors of all of the hospitals in our collection, 4,575.25.</p>

<h2>Distinct Values</h2>

<p>There are instances where you want to grab all of the values for a particular property in your collection, but you only want distinct/unique values. In our same sample code, run to the breakpoint I mentioned earlier and then run this command in the debug console:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span>_hospitals valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;County&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>This will produce the following output:</p>

<p><pre>
(lldb) po [<em>hospitals valueForKeyPath:@"County"]
$3 = 0x08157290 &lt;</em>_NSArrayI 0x8157290>(
Clarke,
Clarke,
PASCO,
COOK
)
</pre></p>

<p>Notice that Clarke has shown up twice. This is because two of our records represent hospitals in the same county. In order to get a list of distinct values, we can use this command instead:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span>_hospitals valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;@distinctUnionOfObjects.County&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>And the output of this command is:
<pre>
(lldb) po [<em>hospitals valueForKeyPath:@"@distinctUnionOfObjects.County"]
$4 = 0x07555c80 &lt;</em>_NSArrayI 0x7555c80>(
PASCO,
Clarke,
COOK
)
</pre></p>

<p>Notice <em>Clarke</em> only displays once now. The <code>@distinctUnionOfObjects</code> operator has returned only unique values. This is what we were looking for.</p>

<h2>Conclusion</h2>

<p>So, while we&#8217;ve been using debugger commands in the examples here, you can instead use the commands in your code. Just remove the &#8216;po&#8217; and set a variable with the result of the <code>valueForKeypath:</code> calls in your code and you can manipulate the results in any way you like. Querying your collections is a very powerful coding technique you should master. It often provides a great way to reduce the amount of code you need to use to get the values you want. That being said, there are times when these types of data collection queries are just too expensive. If that&#8217;s the case, you&#8217;ll have to optimize. Just like everything else in programming, there are tradeoffs. These techniques won&#8217;t work in all situations, but they often will and are worth exploring to solve the problem of obtaining just the values you need. Until next time.</p>

<p><a href="https://github.com/perlmunger/CollectionSearch" title="Querying Objective-C Data Collections: Collection Search Sample Project">Download The Sample Project, CollectionSearch</a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/02/05/querying-objective-c-data-collections/">Querying Objective-C Data Collections</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/02/05/querying-objective-c-data-collections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Down with Magic Strings!</title>
		<link>http://www.cimgf.com/2013/01/29/down-with-magic-strings/</link>
		<comments>http://www.cimgf.com/2013/01/29/down-with-magic-strings/#comments</comments>
		<pubDate>Tue, 29 Jan 2013 18:46:28 +0000</pubDate>
		<dc:creator>Patrick Hughes</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=2009</guid>
		<description><![CDATA[<p>Developing iOS apps in Xcode is pretty great. With Objective-C and llvm we get type checking and autocompletion of all our classes and method names which is a nice improvement over my favorite dynamic languages. Unfortunately there are still some places where the compiler can&#8217;t help us. There are various resources we load from files [...]</p><p>The post <a href="http://www.cimgf.com/2013/01/29/down-with-magic-strings/">Down with Magic Strings!</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Developing iOS apps in Xcode is pretty great. With Objective-C and llvm we get type checking and autocompletion of all our classes and method names which is a nice improvement over my favorite dynamic languages. Unfortunately there are still some places where the compiler can&#8217;t help us. There are various resources we load from files like images, nibs &amp; xibs and other resources which we need to specify by name, like a view controller we want to load from a storyboard.
<span id="more-2009"></span></p>

<h3>The Problem</h3>

<p>Unfortunately these names are not collected by Xcode, so we must type them in as strings. These names-as-strings are generally referred to as &#8220;Magic Strings&#8221; because they make things happen without the compiler knowing anything about them. This can be problematic for a handful of reasons. Firstly, there&#8217;s no autocompletion. I don&#8217;t know about you, but I can&#8217;t type <code>@"detail_table_view_cell_rounded_top_and_bottom_blue"</code> with enough confidence that I don&#8217;t quadruple check it. Next, when things aren&#8217;t working properly I end up having to de-nest my <code>[imageView setImage:[UIImageView imageNamed:@"background_image"]]</code> method call to ensure that the image is actually being loaded. Thirdly, when the design changes and I have to replace 45 image files the compiler won&#8217;t be able to warn us if any of the names have changed. That can be an irritating source of subtle regressions.</p>

<p>An ideal solution to this problem would:</p>

<ol>
<li>Allow compile time checking of resource requests to ensure the resource exists.  </li>
<li>Enforce runtime checking to ensure the resource loaded properly.  </li>
<li>Create tokens that Xcode can use for autocompletion.  </li>
<li>Tell me how wonderful I am.  </li>
</ol>

<p>Compile time checking would require a compiler verified token of some sort, like an NSString constant, preferably auto-generated. That also would allow for autocompletion. Unfortunately, a simple string constant wouldn&#8217;t solve the third requirement as runtime checking would require some sort of assertion after the resource is loaded.</p>

<h3>A Solution</h3>

<p>The solution I&#8217;ve created so far only deals with images, but could easily be expanded to nibs and xibs. Creating tokens for Storyboard IDs would be a bit more work.</p>

<p>I&#8217;ve written a small python script that solves these problems in a way that I&#8217;m satisfied with. Each time it runs it scans a folder for images. It then compares the image names to collect the various platform specific and scaled versions and groups them together. It then <code>#define</code>s a block for each group that loads the image using <code>imageNamed:</code>, throws an assertion if the image doesn&#8217;t load and then returns the image.</p>

<p>For instance, if I have the following image files in my images folder:</p>

<pre><code>red-button.png  
red-button@2x.png  
red-button~ipad.png  
red-button@2x-ipad.png  
</code></pre>

<p>The script will recognize that they are all part of the same group and will only create one define statement, which will look like this:</p>

<pre><code>#define imgRedButton (UIImage*)^{ UIImage *image = [UIImage imageNamed:@"red-button"]; ZAssert(image, @"Image red-button not found"); return image; }()
</code></pre>

<p>Now, whenever I need to load an image, I can simply type:</p>

<pre><code>[imageView setImage:imgRedButton]  
</code></pre>

<p>(With full auto completion, of course.) and we&#8217;re golden!</p>

<p>I&#8217;ve only used this script on one small project, so I&#8217;m sure there are a million ways it can be improved.</p>

<h3>Using The Script</h3>

<p>Download <a href="https://gist.github.com/4462966">the image.py script</a> and place it in your project directory.</p>

<pre><code>usage: images.py [-h] [-s SOURCE] [-d DESTINATION] [--prefix PREFIX]
                 [--format FORMAT] [--warn-retina RETINA] [--warn-ipad IPAD]
                 [--warn-iphone IPHONE] [--warn-duplicates DUPLICATES]
</code></pre>

<p>The script is invoked via the command line, all values have sane-ish defaults:</p>

<pre><code>Option                          Default  
-s  Directory of images.        Current working directory.  
-d  Output file.                Current working directory.  
--prefix Token Prefix.          'img' Prepended to all image names.  
--format Output format.         A block which loads the image (via imageNamed:) and ensures that it loaded (via ZAssert).  
</code></pre>

<p>In addition the script can add warnings to the output file to more proactively alert you of missing images:</p>

<pre><code>Option              Default Effect  
--warn-iphone       False   Warn if there are only ~ipad versions of images.  
--warn-ipad         False   Warn if there are no ~ipad versions of images.  
--warn-retina       True    Warn if there are no @2x version of images (dependent on --warn-iphone and --warn-ipad).  
--warn-duplicates   True    Warn if there are slight naming inconsistencies that are incompatible with the script.  
</code></pre>

<h3>Xcode integration (The Eye of Sauron)</h3>

<p>Manually running the script every once in a while is dumb, and stupid and stuff. Don&#8217;t do it that way. Instead, run it every time you build. That way you can be sure that it has its watchful eye on your images.</p>

<p>My preferred method is to create a separate target to run the script, set that target as a dependent target, and then import the output file in prefix.pch. That way all my classes have access to the images by default.</p>

<p>To add a new target in Xcode 4.5:</p>

<ol>
<li>Ensure that you have downloaded <a href="https://gist.github.com/4462966">the image.py script</a> and placed it in your project directory. </li>
<li>Choose File > New > Target… An action sheet should appear.</li>
<li>In the left panel under OS X select Other.  </li>
<li>In the right panel select &#8220;External Build System&#8221;.  </li>
<li>Click the &#8220;Next&#8221; button in the bottom right corner.  </li>
<li>Enter the target options:<br />
a. Give your product a name. I use &#8220;Image Script&#8221;.<br />
a. Change the &#8220;Build Tool&#8221; to <code>"/usr/bin/python"</code>.  </li>
<li>Select your project in the Project Navigator.  </li>
<li>Select your newly created target.  </li>
<li>In the Arguments text box enter the appropriate command line arguments.<br />
a. <code>$(SRCROOT)</code> is the root directory of your project.<br />
a. If your project path has spaces in it wrap the argument in quotation marks.<br />
a. For example: <code>"$(SRCROOT)/My Project/image.py" -s "$(SRCROOT)/My Project/Resources/Images" -d "$(SRCROOT)/My Project/images.h"</code>  </li>
<li>Select your build target.  </li>
<li>Select the &#8220;Build Phases&#8221; tab on the right.  </li>
<li>Expand the &#8220;Target Dependencies&#8221; section.  </li>
<li>Click &#8220;+&#8221; and select your new target in the action sheet.  </li>
<li>Build your project. This will create the images.h file for the first time.</li>
<li>Add images.h to your project.</li>
<li>Add <code>#import "images.h"</code> to your <code>prefix.pch</code> file.</li>
</ol>

<p>At this point your project should now recreate the images.h header file with each build, ensuring that your images.h file is always an accurate representation of the image files available in your project. There are still issues that can occur, but now Xcode is working for you. You&#8217;ll learn about missing images right away, and will get a very helpful assertion failure if you&#8217;ve somehow forgotten to add an image to the build target. (Not that that&#8217;s ever an issue with Xcode.) All with less work on your part. Good for you! You get a cookie!</p>

<h3>Update.</h3>

<p>Florian Bürger <a href="https://twitter.com/efelbi/status/296560328685260801">tweeted</a> about his update to the script, which only overwrites the images.h file if there have been changes. I&#8217;ve incorporated his changes into my version. Awesome guy, that Florian.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/3f58fe2e8826c2ed5d1f934a0c53864b?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/phughes/' title='Patrick Hughes'>Patrick Hughes</a></h3><p>Patrick Hughes is a senior typist at Empirical Development. He doesn't actually type faster or with more accuracy, but he's been around for a couple years and wanted a fancy title like everyone else.</p><p><a href='http://www.cimgf.com/author/phughes/' title='More posts by Patrick Hughes'>More Posts</a>  - <a href='http://www.empiricaldevelopment.com' title='Patrick Hughes'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/phughes'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2013/01/29/down-with-magic-strings/">Down with Magic Strings!</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/01/29/down-with-magic-strings/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>NSFetchedResultsController -sectionNameKeyPath discussion</title>
		<link>http://www.cimgf.com/2013/01/03/nsfetchedresultscontroller-sectionnamekeypath-discussion/</link>
		<comments>http://www.cimgf.com/2013/01/03/nsfetchedresultscontroller-sectionnamekeypath-discussion/#comments</comments>
		<pubDate>Thu, 03 Jan 2013 23:40:35 +0000</pubDate>
		<dc:creator>Ben Blakely</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1994</guid>
		<description><![CDATA[<p>Core Data and NSFetchedResultsController do clever things under-the-hood to improve performance, such as loading data in batches as it&#8217;s needed. But there&#8217;s a gotcha with grouping data with sectionNameKeyPath than can cause a big hit in performance. Check this out. Starting Simply Let&#8217;s start with a simple table view without any sections. Our entity will [...]</p><p>The post <a href="http://www.cimgf.com/2013/01/03/nsfetchedresultscontroller-sectionnamekeypath-discussion/">NSFetchedResultsController -sectionNameKeyPath discussion</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Core Data and NSFetchedResultsController do clever things under-the-hood to improve performance, such as loading data in batches as it&#8217;s needed. But there&#8217;s a gotcha with grouping data with sectionNameKeyPath than can cause a big hit in performance. Check this out.
<span id="more-1994"></span></p>

<h2>Starting Simply</h2>

<p>Let&#8217;s start with a simple table view without any sections. Our entity will be an Event with a date and a name:</p>

<pre><code>@interface Event : NSManagedObject

@property (nonatomic) NSDate *date;
@property (nonatomic) NSString *name;

@end
</code></pre>

<p>Next, we&#8217;ll ask our fetched results controller to load a ton of events (ordered by date) for our table view. Even with a large number of events, our table view loads very quickly. To see what&#8217;s happening behind the scenes, we can have Core Data log its SQL statements by doing the following:</p>

<ul>
<li>In Xcode, go to the Product menu and choose Edit Scheme.</li>
<li>Select Debug on the left.</li>
<li>Select Arguments on the right.</li>
<li>Under Arguments Passed On Launch, click the add button.</li>
<li>Enter: <code>-com.apple.CoreData.SQLDebug 1</code></li>
<li>Click OK.</li>
</ul>

<p>Now when we Build and Run, SQL statements will be listed in the app&#8217;s output:</p>

<pre><code>SELECT 0, t0.Z_PK FROM ZEVENT t0 ORDER BY t0.ZDATE DESC

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20
</code></pre>

<p>Our fetched results controller is getting the primary key for all 1000 events, but only loading the first batch of 20 records.</p>

<p>Scrolling the table view triggers another SQL query:</p>

<pre><code>SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20
</code></pre>

<p>The fetched results controller smartly loads the next batch of 20 records when they&#8217;re needed.</p>

<h2>Grouping</h2>

<p>Now we want to group these events by year. Easy, right? We&#8217;ll just write a method to extract the year from the date, and use that as the sectionNameKeyPath. Our object then becomes:</p>

<pre><code>@interface Event : NSManagedObject

@property (nonatomic) NSDate *date;
@property (nonatomic) NSString *name;

- (NSNumber*)year;

@end
</code></pre>

<p>When we load our table view, it looks great but there&#8217;s a long delay before the view is shown. Let&#8217;s check the SQL output:</p>

<pre><code>SELECT 0, t0.Z_PK FROM ZEVENT t0 ORDER BY t0.ZDATE DESC

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20

...
</code></pre>

<p>Our fetched results controller is now loading <em>everything</em>. It doesn&#8217;t keep all the objects loaded in memory (i.e. scrolling down still loads 20 at a time), but all the objects are temporarily loaded upfront.</p>

<p>Why would it do such a thing? There&#8217;s no way for the fetched results controller to know how many groups there are without instantiating all our object to call <code>- (NSNumber*)year</code> on each event.</p>

<p>The bigger our dataset becomes, the longer the delay will be. Fortunately, there&#8217;s a workaround.</p>

<h2>Fast Grouping</h2>

<p>What if we were to use a persistent attribute to group our records? Let&#8217;s <a href="http://en.wikipedia.org/wiki/Denormalization">denormalize</a> (i.e. store redundant data to optimize read performance) by saving the year as a persistent attribute. So our updated Event entity has a date, a name, and now a year:</p>

<pre><code>@interface Event : NSManagedObject

@property (nonatomic) NSDate *date;
@property (nonatomic) NSString *name;
@property (nonatomic) NSNumber *year;

@end
</code></pre>

<p>Let&#8217;s load the view and check out the SQL queries:</p>

<pre><code>SELECT 0, t0.Z_PK FROM ZEVENT t0 ORDER BY t0.ZDATE DESC

SELECT t0.ZYEAR, COUNT (DISTINCT t0.Z_PK) FROM ZEVENT t0 GROUP BY t0.ZYEAR ORDER BY t0.ZYEAR DESC

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZDATE, t0.ZYEAR FROM ZEVENT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZDATE DESC LIMIT 20
</code></pre>

<p>Look how it&#8217;s using GROUP BY. It now does the grouping with SQL! The second SQL query calculates the number of groups and how many records are in each group. From there, it only loads the first batch of 20 records. We get lazy fetching again which means a quick-loading table view.</p>

<h2>Summary</h2>

<p>It&#8217;s pretty amazing that giving NSFetchedResultsController a method to emit sections works at all. But that clever behavior comes at a cost in performance. For small datasets the performance hit might not be noticeable. But if you&#8217;re dealing with a lot of data, you don&#8217;t want to keep your users waiting while all the data loads upfront. In those cases, you can use denormalization to store your section names in the database. The end result is much snappier performance and, hopefully, happier users.</p>

<h2>Empirical Development</h2>

<p><a href="http://www.empiricaldevelopment.com"><img src="http://www.cimgf.com/wp-content/uploads/2013/01/CroppedMasked-286x300.png" alt="EDev Logo" width="100" class="alignright size-medium wp-image-1997" align="left"/></a>This guest post was contributed by Ben Blakely of Empirical Development.  As part of our development cycle we frequently run across interesting discoveries.  When these are potentially of interest to other development teams we will be contributing them to Cocoa Is My Girlfriend.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/55ce35aa7199cf87e926eaed036fbbae?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/bblakely/' title='Ben Blakely'>Ben Blakely</a></h3><p></p><p><a href='http://www.cimgf.com/author/bblakely/' title='More posts by Ben Blakely'>More Posts</a> </p></p><p>The post <a href="http://www.cimgf.com/2013/01/03/nsfetchedresultscontroller-sectionnamekeypath-discussion/">NSFetchedResultsController -sectionNameKeyPath discussion</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2013/01/03/nsfetchedresultscontroller-sectionnamekeypath-discussion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leveraging Basic SEO</title>
		<link>http://www.cimgf.com/2012/12/31/leveraging-basic-seo/</link>
		<comments>http://www.cimgf.com/2012/12/31/leveraging-basic-seo/#comments</comments>
		<pubDate>Tue, 01 Jan 2013 00:23:33 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1944</guid>
		<description><![CDATA[<p>Being that I&#8217;m a blogger as well as a software developer, I&#8217;m going to deviate a little from the normal Cocoa specific programming fare and focus a bit on leveraging basic SEO on your blog. These are some of the lessons I&#8217;ve learned and I think they might be helpful to others. People do some [...]</p><p>The post <a href="http://www.cimgf.com/2012/12/31/leveraging-basic-seo/">Leveraging Basic SEO</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Being that I&#8217;m a blogger as well as a software developer, I&#8217;m going to deviate a little from the normal Cocoa specific programming fare and focus a bit on leveraging basic SEO on your blog. These are some of the lessons I&#8217;ve learned and I think they might be helpful to others.</p>

<p>People do some pretty shady things to try to improve their page rank. There are companies who claim to be able to improve page rank. In fact it&#8217;s an entire market full of snake oil sales people. I&#8217;m sure there are some legitimate &#8220;consultants&#8221; out there, but they&#8217;re tough to find. In the end, the techniques for &#8220;optimizing&#8221; your page so that search engines find your content more readily are the same for the legit folks, like bloggers such as those of us who write for CIMGF, as they are for the folks who are trying to game the system. The difference is that gaming the system is exactly what true SEO helps eliminate. Google will blacklist your site if they detect you are trying to game them and getting off of that list will prove very difficult. It is not worth it to game the system. In the end when leveraging basic SEO, the old adage remains, &#8220;Content is King&#8221;. That single principle is the one and only differentiator. Write great content for your users and everything else will fall into place.<span id="more-1944"></span></p>

<p>Here is how I summarize the basic techniques of effective SEO.</p>

<ul>
<li>Write content that is meaningful, helpful, or useful to your audience that actually enlightens them</li>
<li>Read that first point again. If you don&#8217;t get that one right, the following ones don&#8217;t matter.</li>
<li>Seriously! CONTENT IS KING!! (sorry for yelling).</li>
<li>Provide the &#8220;on page&#8221; attributes, like making search terms part of your post (e.g. in headers and paragraphs, etc.&#8211;more on this later)</li>
<li>Use social media to let your tweeps know about your new content. If they like it, they will retweet it. Tweets get picked up by Google indexing.</li>
<li>Use news aggregators to let other people know about your content</li>
<li>Make sure your site map gets updated when you publish your new content to the world</li>
<li>If your content is good, other bloggers will link back to you. Linking back to you communicates to google that you are an expert site. The more people that link to you, Google will consider you more likely to know what you&#8217;re talking about and your page rank will rise.</li>
</ul>

<p>So if you&#8217;re asking yourself, &#8220;so how can I use SEO to improve sales?&#8221;, please stop asking that question. You are thinking about it all wrong. If you want to make money, spend money&#8211;namely on advertising and stop trying to game the system. You&#8217;re actually part of the problem and the search engines will penalize you for that. Now, that being said, SEO <em>can</em> provide a revenue stream, but <strong>in order to get, you first have to give</strong> and the revenue you do get may be difficult to attribute directly to your SEO efforts. What I mean when I say that you have to give is that you need to <strong>provide actual legitimate and helpful content</strong> to the community&#8211;whatever community that may be.</p>

<p>For us here at CIMGF, legitimate content exists in the form of blog posts that we believe will help our readers become better developers or that will teach them how to do something that will improve their effectiveness. Often, when I perform some web search to see how to do something, there will be a hit on the first page that links back here to CIMGF. Now, of course, my response is often, &#8220;oh, I guess I&#8217;ve done this before.&#8221; In fact, one of the early reasons I started blogging was as a way to keep a journal of the things I was learning. Apparently, these &#8220;journal entries&#8221; are helpful to other people as well&#8211;so people link back to our blog posts and Google therefore considers us an expert site, which is critical for obtaining higher page rank.</p>

<h2>Is SEO Real?</h2>

<p>If someone says, &#8220;I&#8217;m an SEO&#8221;, run for the hills. I just want to ask, is that like a CEO? Presumably it means &#8220;Search Engine Optimize(r)&#8221;, I guess. Is it some sort of real position or job title? Or did you make that up in the hopes you could fool someone into using your&#8230; ahem&#8230; <em>service</em>? These people are just wanting to take your money and promising something in return that they can&#8217;t actually provide. SEO is not a bad word or a bad thing, but because there are these Internet hipsters out there who make promises they can&#8217;t keep, it&#8217;s gotten a bad reputation. As I said earlier, it&#8217;s all about your content. You want to drive traffic to your site not because you have something to sell, but because you have something beneficial and helpful to say. If you pursue SEO, which admittedly is a dumb name that won&#8217;t evolve, you have to think of it the way a search engine company thinks of it. Here&#8217;s what I mean.</p>

<p>If the hits Google returned for every search query led you to just the top bidder (and no I&#8217;m not referring to the paid links you see&#8211;I mean the real hits), how long would you continue using their search engine? If you looked up <em>Peyton Manning</em> on Google, for example, you are likely wanting information about his career stats or the latest news about the star Broncos quarterback. If the first page of hits Google returned were simply places where you could buy jerseys with his number on it, you&#8217;d be pretty irritated. That&#8217;s why content is king. Google <em>needs</em> their users to be able to find the most <em>relevant</em> links. Relevant means simply that it&#8217;s meaningful to <em>you</em>. If they show you what they want you to see, rather than what you actually want to see, you will go somewhere else quickly&#8211;end of discussion. In the end that is detrimental to their bottom line. They would be foolish not to build a system that helps realize the adage.</p>

<p>SEO is real, but it only helps site rank for real and actual content in your specific domain.</p>

<h2>Niches Are Easy, Broad Topics Are Not</h2>

<p>So what do I mean by &#8220;specific domain&#8221;? Well, it&#8217;s pretty easy to get your blog post to be at the top of the search if you are pursuing a niche community&#8211;like, for example, Cocoa developers. I can reach my target audience with my message pretty easily because people in our community are looking for content that is relevant to them and I can produce content that is relevant to them because of my own expertise. If I were to start trying these SEO techniques for say something like the real estate industry, you wouldn&#8217;t see results so quickly. If the adage applies, you would have to start cranking out content that was super interesting and helpful to a very broad target audience on a super frequent basis and you&#8217;d have to have a keen insight on determining search terms that your users are likely to use to find you. You also have to remember that you shouldn&#8217;t release your content all at once in an explosive manner. Google can detect this and may flag your site if you&#8217;re not careful. Your content needs to emerge organically. It needs to find its way in a natural fashion where real people wrote real content on a regular basis. Otherwise, your efforts may be for naught. Reaching a broader audience is not by any means impossible. In fact, the person I learned SEO from is a master at this and has employed techniques that have overtaken the top spot for many many topics on Google. Reaching a broader audience, however, is very challenging and requires vigilance and consistency. Oh, and it requires great content. Did I mention that yet?</p>

<h2>Choices That Benefit Community</h2>

<p>When you build your site pages, you make choices according to your priorities. Site rank can potentially mean revenue, but that depends completely on how you leverage your traffic. And you have to make choices that don&#8217;t negatively affect the attributes that brought people to your site in the first place. If you start throwing ads at your users in an attempt turn your traffic into cash, it&#8217;s possible that it may work, but why risk it? When CIMGF started, we made the conscious decision not to place ads on the site because we felt like it cheapened the content and our message. Almost five years later, we still stand behind that decision. Now, that being said, we have affiliate linked to the books written by the authors who have penned a post here at CIMGF including yours truly, however, we think that this still benefits the community and ties in with our message which is that we want to help other developers like ourselves because we believe in our community. The books we&#8217;ve written, we wouldn&#8217;t have written if it weren&#8217;t something we considered beneficial. Unless you&#8217;re a NYT best seller, you don&#8217;t make much money writing books. And linking to our books is merely a way to help authenticate us with our readers&#8211;giving them confidence that we have something to offer.</p>

<h2>The SEO 80/20 Rule</h2>

<p>I&#8217;ve heard some people quote this incorrectly and claim that the SEO 80/20 rule means that 20% of the optimization will give you 80% of your hits. That, while very positive and optimistic, is just incorrect. The SEO 80/20 rule means that approximately 20% of your hits will occur due to &#8220;on page&#8221; attributes that you&#8217;ve given it (appropriate headers/titles keywords and structure) while the remaining 80% come from off page attributes such as people linking to you and the quality and placement of those links on their sites. The 80% portion is almost completely out of your hands while the 20% is completely in your hands. What I mean is you need to specify the proper page attributes to make sure you take advantage of the full 20% that you can actually control.</p>

<p>To help with this, I recently started using a plugin for WordPress on CIMGF called &#8220;<a href="http://wordpress.org/extend/plugins/wordpress-seo/" title="WordPress SEO by Yoast">WordPress SEO by Yoast</a>&#8220;. It&#8217;s fascinating the things it suggests for you and you can choose to implement them all or you can ignore them or work on everything in between, but it very quickly gives you some insight into what items are helpful and/or important to ensuring your page has all of the basic &#8220;on page&#8221; requirements that you have control over. The rest of your site rank is going to come from people linking to you and they will only do that if you are providing excellent content.</p>

<p>While I was composing this post, here is what &#8220;WordPress SEO by Yoast&#8221; displayed.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/seo_general.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/seo_general-300x222.png" alt="Leveraging Basic SEO: General SEO Details" width="300" height="222" class="alignleft size-medium wp-image-1951" /></a></p>

<p>And here is the analysis.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/seo_analysis.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/seo_analysis-300x196.png" alt="Leveraging Basic SEO: Post Analysis" width="300" height="196" class="alignleft size-medium wp-image-1950" /></a></p>

<p>Even if you don&#8217;t understand all of the details of the analysis, it will give you some helpful insight at a glance that you would otherwise have to discover by reading books on the topic of SEO&#8211;though I&#8217;m not against that. There are some good books out there. There are some articles on the web that talk about WordPress SEO by Yoast specifically and provide more details on the setup and configuration options. You should check those out as well.</p>

<h2>Conclusion</h2>

<p>In the immortal words of Bill and Ted&#8217;s Excellent Adventure, &#8220;be excellent to each other&#8221;. Fight the urge to try to use SEO as a way to make money. It just won&#8217;t work that way. Focus on creating excellent content that your readers will love and benefit from. The revenue may flow, but ironically that is probably directly related to how altruistic your blogging intentions are. The more altruistic, the more revenue potential. But if you start seeking revenue, your attempts at altruism are dashed and revenue generation will fail. How&#8217;s that for a paradox? Until next time.</p>

<h2>Postscript</h2>

<p>One more thing. I was doing a web search and came across a company that provides SEO services. I couldn&#8217;t help but laugh and you&#8217;ll see why when you take a look at the screenshot below. I would be completely shocked if this company provided any legitimate service just going on their site design alone. Even their name makes it seem like they&#8217;re trying to game the system. Who puts a 1 at the beginning of their business name for other than strategic (read, subversive) purposes? Nobody. Anyhow, have a look and a laugh.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/seo_expert_yeah_right.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/seo_expert_yeah_right-300x255.png" alt="Leveraging Basic SEO: How can this be legit?" width="300" height="255" class="alignleft size-medium wp-image-1975" /></a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2012/12/31/leveraging-basic-seo/">Leveraging Basic SEO</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/12/31/leveraging-basic-seo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode LLDB Tutorial</title>
		<link>http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/</link>
		<comments>http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/#comments</comments>
		<pubDate>Thu, 13 Dec 2012 16:42:35 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[.]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1854</guid>
		<description><![CDATA[<p>What inspired the Xcode LLDB Tutorial? Well, I tweeted this the other day: A few people then responded over twitter asking that I would elaborate by writing a tutorial here on CIMGF. So here it is. Your wish is my command, The Xcode LLDB Tutorial Apparent Debugger Design Goals If you have ever done debugging [...]</p><p>The post <a href="http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/">Xcode LLDB Tutorial</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>What inspired the Xcode LLDB Tutorial? Well, I tweeted this the other day:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2012/12/Screenshot-121112-831-PM.png" alt="LLDB Tweet" width="553" height="242" class="alignleft size-full wp-image-1855" /></p>

<p>A few people then responded over twitter asking that I would elaborate by writing a tutorial here on CIMGF. So here it is. Your wish is my command, The Xcode LLDB Tutorial</p>

<p><span id="more-1854"></span></p>

<h2>Apparent Debugger Design Goals</h2>

<p>If you have ever done debugging without a debugger, then you know how great a debugger is&#8211;any debugger is better than none. The alternative is printing out messages in your code using printf back in the day of straight C, or NSLog these days if you aren&#8217;t yet comfortable with using a debugger.</p>

<p>Now, I won&#8217;t go into the history, but suffice it to say we used to use GDB, but LLDB is the current course and while the road has been a little bumpy during the transition, things are getting better and debugging is simpler and more powerful than ever. Apple has made it pretty clear that they are trying to give us the tools that enable us to leave the days of placing debug code in our apps behind. I think we&#8217;re there. You can now stop on a break point and start analyzing all of your code by using debugger commands and injecting actual Objective-C code that will get evaluated right while you&#8217;re running. You can even change the value of your variables on the fly or edit a break point and tell it to print out a variable and then continue running. It&#8217;s really quite powerful and your code can remain clean and un-tainted by debug code.</p>

<h2>Just A Taste of the Xcode LLDB Tutorial</h2>

<p>Let&#8217;s jump right in with a few basic LLDB commands. The most common commands you&#8217;ll use in the debugger are <strong>p</strong> (for print), for primitive types (booleans, integers, floats, etc.) and <strong>po</strong> (for print object) for Objective-C objects. When you type <strong>po</strong> and then then name of an object like the view of your view controller for example:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span>self view<span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>The debugger will print the <strong>description</strong> (found in NSObject and overridden by many classes) of that object. In this case it will print something like:</p>

<blockquote>
(UIView *) $1 = 0x0824c800 &lt;UITableView: 0x824c800; frame = (0 20; 768 1004); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = &lt;NSArray: 0x74c3010&gt;; layer = &lt;CALayer: 0x74c2710&gt;; contentOffset: {0, 0}&gt;
</blockquote>

<p>So how do we get it to do that? Well, the first thing you need to do is set a break point. You do so by clicking in the line numbers on the line where you want to break. For the example above, I set a break point in <code>viewDidLoad:</code> like this:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/Screenshot-121212-1214-AM.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/Screenshot-121212-1214-AM-300x79.png" alt="Xcode LLDB Tutorial: Set a break point" width="300" height="79" class="alignleft size-medium wp-image-1862" /></a></p>

<p>Now run the app and wait for the debugger to break on the break point. Look at the bottom of the Xcode window and you&#8217;ll see the console where you enter in your LLDB commands.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/Screenshot-121212-1219-AM.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/Screenshot-121212-1219-AM-300x132.png" alt="Xcode LLDB Tutorial: Debug Console" width="300" height="132" class="alignleft size-medium wp-image-1865" /></a></p>

<p>A more useful command might be to get the number of subviews contained by our view controller&#8217;s view. Since the count of subviews is an integer, a primitive, we should use the <strong>p</strong> command instead of <strong>po</strong>. Like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">p <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self view<span style="color: #002200;">&#93;</span> subviews<span style="color: #002200;">&#93;</span> count<span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>This will print out:</p>

<blockquote>
(int) $2 = 2
</blockquote>

<p>Notice we type-casted our return type so the debugger knows what to do with it. Cool, isn&#8217;t it? Just wait, it gets better.</p>

<h2>Parsing Twitter Feeds</h2>

<p><em>(The code for this section is in the project called TwoDegrees. You can download it at <a href="https://github.com/perlmunger/TwoDegrees" title="TwoDegrees">github</a>.)</em></p>

<p>If you&#8217;re a seasoned Twitter API developer, you probably know something about the basic layout of the JSON you receive upon successful timeline request, but even you don&#8217;t have the whole thing memorized and will need a way from time to time to look up what the structure is like. Not to mention knowing those folks behind the Twitter API the layout may change from time to time. Wouldn&#8217;t it be nice to just spin off your request and then just analyze the response on the fly when you get it back. Watch this.</p>

<p>Here is some Twitter code implemented with iOS6&#8242;s Social framework.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>downloadTimeline
<span style="color: #002200;">&#123;</span>
  ACAccountStore <span style="color: #002200;">*</span>accountStore <span style="color: #002200;">=</span> <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>;
  ACAccountType <span style="color: #002200;">*</span>accountType <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>accountStore accountTypeWithAccountTypeIdentifier<span style="color: #002200;">:</span>ACAccountTypeIdentifierTwitter<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>accountStore requestAccessToAccountsWithType<span style="color: #002200;">:</span>accountType
                                        options<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                     completion<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span> granted, <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
     <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>granted<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
       <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>accounts <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>accountStore accountsWithAccountType<span style="color: #002200;">:</span>accountType<span style="color: #002200;">&#93;</span>;
&nbsp;
       <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>accounts count<span style="color: #002200;">&#93;</span> &gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
         ACAccount <span style="color: #002200;">*</span>account <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>accounts lastObject<span style="color: #002200;">&#93;</span>;
&nbsp;
         <span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;https://api.twitter.com/1.1/statuses/home_timeline.json&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
         <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>parameters <span style="color: #002200;">=</span> @<span style="color: #002200;">&#123;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;count&quot;</span> <span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;200&quot;</span><span style="color: #002200;">&#125;</span>;
&nbsp;
         SLRequest <span style="color: #002200;">*</span>request <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>SLRequest requestForServiceType<span style="color: #002200;">:</span>SLServiceTypeTwitter
                                                 requestMethod<span style="color: #002200;">:</span>SLRequestMethodGET
                                                           URL<span style="color: #002200;">:</span>url
                                                    parameters<span style="color: #002200;">:</span>parameters<span style="color: #002200;">&#93;</span>;
&nbsp;
         <span style="color: #002200;">&#91;</span>request setAccount<span style="color: #002200;">:</span>account<span style="color: #002200;">&#93;</span>;
&nbsp;
         <span style="color: #002200;">&#91;</span>request performRequestWithHandler<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>responseData,
                                              <span style="color: #400080;">NSHTTPURLResponse</span> <span style="color: #002200;">*</span>urlResponse,
                                              <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
           <span style="color: #a61390;">id</span> response <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSJSONSerialization
                           JSONObjectWithData<span style="color: #002200;">:</span>responseData
                           options<span style="color: #002200;">:</span>NSJSONReadingMutableLeaves
                           error<span style="color: #002200;">:&amp;</span>error<span style="color: #002200;">&#93;</span>;
&nbsp;
           DLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Response: %@&quot;</span>, response<span style="color: #002200;">&#41;</span>;
&nbsp;
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>response count<span style="color: #002200;">&#93;</span> &gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
              dispatch_async<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;">^</span><span style="color: #002200;">&#123;</span>
                <span style="color: #11740a; font-style: italic;">// Do something on the main queue</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> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
       DLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Failed to get twitter account&quot;</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></td></tr></table></div>


<p>I placed a breakpoint on line 34 where the <code>DLog</code> is. Then I ran this in the console.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>response filteredArrayUsingPredicate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSPredicate</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> 
            predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;retweet_count &gt; 0 and retweeted_status.entities.urls.@count &gt; 0&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>
                valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;retweeted_status&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>The response object is an array generated by Apple&#8217;s JSON parsing class, <code>NSJSONSerialization</code> using the raw data response we got back. This <strong>po</strong> command is effectively printing out <em>any tweets that have been retweeted that contain at least one URL</em>. So let&#8217;s think about that for a second:</p>

<blockquote>
&#8220;The philosophy behind this query is that if your tweeps retweeted something, it&#8217;s probably even more important or interesting to you than it would be otherwise and since it has a URL, the page it links to is probably something you&#8217;d be highly interested in reading.&#8221;
</blockquote>

<p>You can see in our debugger command everything is straight Objective-C code except for the <strong>po</strong> itself. Here are some important notes about that 1-liner (er, well I had to wrap it so you could see it without scrolling here, however, in my debugger it&#8217;s one line).</p>

<ul>
<li>When passing a parameter to a method, you have to type-cast that parameter to whatever the method requires. So that&#8217;s why we have an <code>(NSPredicate*)</code> type-cast.</li>
<li>Our predicate contains two parts. The second one uses the @count parameter which evaluates a count of the URLs in the tweet and makes sure there is at least one.
</ul>

<p>If you&#8217;re not familiar with it, KVC, key-value coding, allows us to query our arrays for certain parameters like a count or a sum or we can access a particular property of all of the objects contained within our array. So back in our console, we can dig even deeper. Say that we want to show a list of all of the <code>expanded_urls</code> in those tweets that our tweeps retweeted. We can use some KVC to do it:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>response filteredArrayUsingPredicate<span style="color: #002200;">:</span>
                <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSPredicate</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;retweet_count &gt; 0 and
                         retweeted_status.entities.urls.@count &gt; 0&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> 
                         valueForKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;retweeted_status.entities.urls.expanded_url&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<blockquote><strong>Note:</strong> For those of you who are new to iOS development having come from C#, you&#8217;ll notice that KVC has some things in common with <a href="http://msdn.microsoft.com/en-us/library/bb397933.aspx" title="Microsoft LINQ">Microsoft&#8217;s LINQ</a>. They are different, but have some concepts in common that you may be familiar with.</blockquote>

<p>See our call to <code>valueForKeyPath:</code> at the end of our array. Passing it the key path <code>"retweeted_status.entities.urls.expanded_url"</code> is accessing the <code>expanded_url</code> parameter for the list of <code>urls</code> in the <code>entities</code> collection inside each of the retweeted (<code>retweet_count</code> greater than zero) tweets. (Say what? Read it again. It&#8217;ll make more sense, I promise.)</p>

<p>Here is what the description for one of the retweeted tweet dictionaries (remember it&#8217;s a dictionary now that we parsed the raw JSON) looks like when printed in the console:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#123;</span>
    contributors <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;&lt;null&gt;&quot;</span>;
    coordinates <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;&lt;null&gt;&quot;</span>;
    <span style="color: #bf1d1a;">&quot;created_at&quot;</span> <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;Wed Dec 12 19:32:40 +0000 2012&quot;</span>;
    entities <span style="color: #002200;">=</span>     <span style="color: #002200;">&#123;</span>
        hashtags <span style="color: #002200;">=</span>         <span style="color: #002200;">&#40;</span>
        <span style="color: #002200;">&#41;</span>;
        urls <span style="color: #002200;">=</span>         <span style="color: #002200;">&#40;</span>
                        <span style="color: #002200;">&#123;</span>
                <span style="color: #bf1d1a;">&quot;display_url&quot;</span> <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;gizmodo.com/5958794/friend<span style="color: #2400d9;">\U</span>2026&quot;</span>;
                <span style="color: #bf1d1a;">&quot;expanded_url&quot;</span> <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;http://gizmodo.com/5958794/friends-dont-let-friends-drink-and-windows-8&quot;</span>;
                indices <span style="color: #002200;">=</span>                 <span style="color: #002200;">&#40;</span>
                    <span style="color: #2400d9;">12</span>,
                    <span style="color: #2400d9;">32</span>
                <span style="color: #002200;">&#41;</span>;
                url <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;http://t.co/13rMfmAm&quot;</span>;
            <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#41;</span>;
        <span style="color: #bf1d1a;">&quot;user_mentions&quot;</span> <span style="color: #002200;">=</span>         <span style="color: #002200;">&#40;</span>
        <span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>;
    <span style="color: #bf1d1a;">&quot;retweet_count&quot;</span> <span style="color: #002200;">=</span> <span style="color: #2400d9;">5</span>;
    retweeted <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
    source <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;&lt;a href=<span style="color: #2400d9;">\&quot;</span>http://www.metrotwit.com/<span style="color: #2400d9;">\&quot;</span> rel=<span style="color: #2400d9;">\&quot;</span>nofollow<span style="color: #2400d9;">\&quot;</span>&gt;MetroTwit&lt;/a&gt;&quot;</span>;
    text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;Brilliant.  http://t.co/13rMfmAm&quot;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Truncated for brevity...</span></pre></td></tr></table></div>


<p>If you realize our response object is actually an array containing a bunch of these dictionaries, you&#8217;ll understand that we are filtering that array with a predicate that is looking only for objects with a <code>retweet_count</code> greater than zero. That’s what tells us that it was retweeted. Then, with the <code>valueForKeyPath:</code> we are telling the resulting filtered array to give us all of the <code>expanded_url</code>s for all of those records. That&#8217;s pretty cool. Here&#8217;s what the output of that <strong>po</strong> command looks like:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/expandedurls.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/expandedurls-300x175.png" alt="Xcode LLDB Tutorial: Expanded URLs list" width="300" height="175" class="alignleft size-medium wp-image-1929" /></a></p>

<h2>Change The Value of Your Variables On The Fly</h2>

<p><em>(The code for this section is in the project called BogusLogin. You can download it at <a href="https://github.com/perlmunger/BogusLogin" title="BogusLogin">github</a>. The code is really pointless/useless unless you set the breakpoints I describe below to see how they work. Breakpoints don&#8217;t get stored in the project, so you have to set them yourself.)</em></p>

<p>Let&#8217;s push a little farther. How often have you made some changes and restarted the debugger only to realize that the data you wanted is incorrect. Well, just fix it on the fly when you hit a break point using the <strong>expr</strong> command. Here&#8217;s how:</p>

<p>Say you&#8217;ve created a login method that authenticates with a server at the press of a login button (our sample code is just a dummy stub with no server connection, btw). If you have to enter those credentials in your app every time you run&#8211;tapping away on your device&#8217;s glass (and nearly knocking it over if you have a gorilla touch like me), it gets a little tedious and even time consuming. You could use a <code>#ifdef DEBUG</code> macro in your code and specify your debug credentials hard-coded, but why? Use a breakpoint instead. Here is some code with a breakpoint to demonstrate what I mean.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/login.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/login-300x89.png" alt="Xcode LLDB Tutorial: Login Code" width="300" height="89" class="alignleft size-medium wp-image-1884" /></a></p>

<p>If you run your code and stop on that break point, you can just type:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">expr username <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;username&quot;</span>
expr password <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;badpassword&quot;</span></pre></td></tr></table></div>


<p>The console will respond back with:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> $0 <span style="color: #002200;">=</span> 0x3d3504c4 <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;username&quot;</span>
<span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> $1 <span style="color: #002200;">=</span> 0x1d18ef60 <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;badpassword&quot;</span></pre></td></tr></table></div>


<p>Now, if you let the next two log statements print to the console, you&#8217;ll see:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#40;</span>0x1c59aae0<span style="color: #002200;">&#41;</span> A line <span style="color: #a61390;">for</span> the breakpoint
<span style="color: #002200;">&#40;</span>0x1c59aae0<span style="color: #002200;">&#41;</span> Username and Password after<span style="color: #002200;">:</span> username<span style="color: #002200;">:</span>badpassword</pre></td></tr></table></div>


<p>But we can go even farther with this. You can edit your breakpoint and have it change the expression automatically and continue on without actually stopping. To do so, right click on the breakpoint and select &#8220;Edit Breakpoint&#8230;&#8221; (or Option-Cmd Click the breakpoint). Then give the breakpoint the settings you see here:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/breakpoint.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/breakpoint-300x122.png" alt="Xcode LLDB Tutorial: Breakpoint" width="300" height="122" class="alignleft size-medium wp-image-1885" /></a></p>

<p>Notice that the checkbox labeled <strong>Automatically continue after evaluating</strong> is checked. This will ensure that your username and password get changed every time the breakpoint gets hit, but execution will just continue. So, if you have some testing credentials you use while working on your app, just set them in a breakpoint and you&#8217;ll never have to actually enter them into your credentials text fields on your login view and you&#8217;ll never have to set them in your source either. And the beautiful thing is you didn&#8217;t have to have any macros to determine if you were in DEBUG or not. When you ship your app, the breakpoints don&#8217;t exist so you will never run the risk of shipping conditional macro code with inverted logic. How awesome is that?</p>

<p>Just to drive the point home, go back into Xcode and click on the breakpoint we set again to disable it. It should now be a light blue color. If you run it again, you&#8217;ll see that the username and password no longer get changed.</p>

<h2>Conditionals</h2>

<p>Finally, one of the greatest powers of using breakpoints is that they allow for conditionals. Say you have a dataset coming back with tens of thousands of records. Say one of the records is corrupted and you know it&#8217;s ID, but you want to see what&#8217;s going on when that record is being processed/accessed. Place a breakpoint by clicking in the line number column on the line where your data is being processed&#8211;likely in some sort of loop. Or I sometimes find I need to see it when I&#8217;m trying to render a table cell in the table view delegate method <code>tableView:cellForRowAtIndexPath:</code>. I set the breakpoint there and as soon as that ID matches, I know that the related record is getting displayed. Execution stops and I can start analyzing the data using the other methods we&#8217;ve discussed in this post.  You set a condition in your breakpoint like this:</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2012/12/conditional.png" alt="Xcode LLDB Tutorial: Conditionals" width="480" height="191" class="alignleft size-full wp-image-1921" /></p>

<p>You can&#8217;t see the whole condition syntax in that screenshot, so here&#8217;s the actual line:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>item valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ID&quot;</span><span style="color: #002200;">&#93;</span> isEqualToString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;93306&quot;</span><span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p>As with any commands you give the debugger that contains code you have to typecast <em>everything</em>. In this line we are saying that we only want the breakpoint to stop if our item&#8217;s ID field is equal to &#8220;93306&#8243;. If you do place this breakpoint in <code>tableView:cellForRowAtIndexPath:</code>, you may find that your table view performance suffers, but keep in mind that you only need to keep that breakpoint enabled until you&#8217;ve figure out your issue. Then you can either disable it, or remove it.</p>

<blockquote><strong>Note:</strong> Sometimes I get overzealous and accidentally remove breakpoints that I may need again later. It&#8217;s probably best to just get in the habit of disabling them to keep from accidentally removing them. Obviously it&#8217;s not a big deal if they have no conditional logic, but if you&#8217;ve spent the time to add a condition, you&#8217;ll want to protect that breakpoint so you don&#8217;t have to enter it in again. Once you remove the breakpoint, you can&#8217;t undo. I suggest you train yourself to disable rather than remove unless you&#8217;re absolutely sure you won&#8217;t need that breakpoint again.</blockquote>

<h2>Formatting Strings</h2>

<p>If we&#8217;re ever to get rid of <code>NSLog</code>, we need a way to get meaningful messages when we&#8217;re debugging through some other means. Fortunately, you can just format a string the way you normally would in code when adding a command to a breakpoint, except there&#8217;s one gotcha. You may be used to using <code>NSString</code>&#8216;s <code>stringWithFormat:</code> however, this won&#8217;t work in the break point. You will instead need to use alloc/init like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">po <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> alloc<span style="color: #002200;">&#93;</span> initWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Item index is: %d&quot;</span>, index<span style="color: #002200;">&#93;</span></pre></td></tr></table></div>


<p><a href="http://www.cimgf.com/wp-content/uploads/2012/12/stringformat.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/12/stringformat.png" alt="Xcode LLDB Tutorial: Format String In Debugger" width="528" height="254" class="alignleft size-full wp-image-2120" /></a></p>

<p>I don&#8217;t know the exact reason at this time, however, when you try to use <code>stringWithFormat:</code>, you get the following error in the console window:</p>

<p><pre>
error: too many arguments to method call, expected 1, have 2
error: 1 errors parsing expression
</pre></p>

<p>Just use the alloc/init version and it will work fine.</p>

<p>I find this technique very handy and it allows me to avoid using <code>NSLog</code> at all. I realize that <code>DLog</code> is a good substitution for <code>NSLog</code> because it allows you to automatically remove <code>NSLog</code> when you ship a release build, but I&#8217;m really starting to like the options that LLDB gives you and you don&#8217;t have to add any additional pre-compiler conditional code to your PCH file. Cleaner/less code is always better in my opinion.</p>

<h2>Conclusion</h2>

<p>Obviously a lot of the LLDB functionality is built into Xcode&#8211;things like setting breakpoints by simply clicking on the line number where you want to set it, however, there is a lot of power with the commands that are available to you to execute while running in the debugger. This tutorial has only scratched the surface, but even with the few commands we&#8217;ve covered here, you can tell just how much power those few commands give you. If you have any other awesome pro tips for commands that have made your debugging life simpler in Xcode, please share them in the comments. Until next time.</p>

<p>Download the related source code here:</p>

<p><a href="https://github.com/perlmunger/TwoDegrees" title="TwoDegrees Project">TwoDegrees Xcode Project</a><br />
<a href="https://github.com/perlmunger/BogusLogin" title="BogusLogin Project">BogusLogin Xcode Project</a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/">Xcode LLDB Tutorial</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Better Fullscreen Asset Viewer with QuickLook</title>
		<link>http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/</link>
		<comments>http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/#comments</comments>
		<pubDate>Wed, 11 Jul 2012 19:03:19 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[QuickLook]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1775</guid>
		<description><![CDATA[<p>Since last year I&#8217;ve spent a lot of time working on iPad apps for medical device companies. These companies want to be able to display their sales materials/digital assets to potential buyers on the iPad because of its gorgeous presentation. We can&#8217;t blame them. This is a great choice especially with the retina display on [...]</p><p>The post <a href="http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/">A Better Fullscreen Asset Viewer with QuickLook</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Since last year I&#8217;ve spent a lot of time working on iPad apps for medical device companies. These companies want to be able to display their sales materials/digital assets to potential buyers on the iPad because of its gorgeous presentation. We can&#8217;t blame them. This is a great choice especially with the retina display on the third generation iPad. It&#8217;s incredibly compelling.</p>

<p>Our go-to solution for presenting these files until recently has been to just load everything into a UIWebView because it supports so many formats. Voila! Done! We like simple solutions to problems that would otherwise be very difficult.</p>

<p>This solution has worked great, but over time it&#8217;s become a noticeably dull spot in the app with some UX problems to boot. This is not good&#8211;especially for the part of the app that gets the most customer face time. It needs to shine. To go fullscreen, we just load a full size view controller modally. One issue with this approach though was that it only worked in landscape. For some reason it would get wonky (engineering parlance for, &#8220;um, I don&#8217;t know&#8221;) if we allowed both orientations since the rest of the app supported landscape only. It also had a nav bar that would never be hidden, so the user would always see it even when they were scrolling through the document content. Finally, there was no way to jump down deep into a document. If you needed to get to page 325, for example, you had to scroll all the way there. That&#8217;s just a bad user experience&#8211;incredibly tedious making it unlikely anyone would use it with a large document. These were some significant drawbacks and I didn&#8217;t have a good solution to bring the polish that this segment of the app deserved.<span id="more-1775"></span></p>

<p>Then, while working on one of these apps, I got tasked with adding the &#8220;Open In&#8230;&#8221; capability that would allow any of the Keynote presentations to actually be opened in Keynote. While implementing it, I realized that the QuickLook feature, which is one of the default &#8220;Open In&#8230;&#8221; options, provided a simple yet robust fullscreen viewer that provides the polish we were missing. We could build a better asset viewer with QuickLook. In the screenshot below, you can see some of the basic differences between our original viewer implementation (on the left) and the QuickLook based one (right).</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/07/comparison3.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/07/comparison3-300x224.png" alt="Viewer Comparison" title="Viewer Comparison" width="300" height="224" class="alignleft size-medium wp-image-1780" /></a></p>

<p>You notice that we now have a navigation bar that disappears as the user scrolls. The user can jump to a page by using the thumbnail page view control on the right hand side. The view is true fullscreen as everything but the content itself disappears.</p>

<p>Another benefit of using the QuickLook preview controller is that both orientations work and look great as you can see here in the portrait orientation:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/07/viewerportrai.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/07/viewerportrai-225x300.png" alt="Portrait Viewer" title="Portrait Viewer" width="225" height="300" class="alignleft size-medium wp-image-1783" /></a></p>

<p>If you&#8217;ve worked with the QuickLook preview controller, you might have noticed that the action button is missing in the upper right hand corner of the preview window&#8217;s navigation bar. It&#8217;s funny how different companies have different requirements for the same component. While the first company wanted the &#8220;Open In&#8230;&#8221; feature, albeit just for Keynote documents, another company didn&#8217;t want export/editing functionality at all. This is only a problem of course for MS Office or iWork documents since others such as PDFs are read only, however, the second company didn&#8217;t want to the user have any editing capability at all. They are working hard to ensure the document versions are up to date and not edited by anyone who is not authorized to do so.</p>

<p>If you load the QuickLook preview by using a <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDocumentInteractionController_class/Reference/Reference.html" target="_blank">UIDocumentInteractionController</a>, you get the action button and the user can do whatever they want with the documents. Here is what the actions popover looks like when using the standard UIDocumentInteractionController implementation:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2012/07/openin.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2012/07/openin-300x225.png" alt="Standard Open In" title="Standard Open In" width="300" height="225" class="alignleft size-medium wp-image-1784" /></a></p>

<p>You see here that you can open in iBooks, choose to open in anything else on the device that supports the format of the selected document, or print. My second client didn&#8217;t want those options, so in the end we decided not to use the UIDocumentInteractionController and instead implement our own viewer that is directly derived from the <a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Reference/QLPreviewController_Class/Reference/Reference.html" target="_blank">QLPreviewController</a> class. At that point, all we had to do was override the -viewWillAppear: method and remove the right bar button item in the view&#8217;s navigation bar, like this:</p>

<p><strong>iOS6 Update</strong> This technique of overriding the QLPreviewController will no longer work in iOS 6. I have contacted Apple about the situation, but they simply stated that it is no longer supported and it is considered a private API. If you would like to see more flexibility in this API and the ability to override certain aspects, please file a radar.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Header</span>
<span style="color: #6e371a;">#import &lt;QuickLook/QuickLook.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> MLQuickLookPreviewController <span style="color: #002200;">:</span> QLPreviewController
&nbsp;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Implementation</span>
<span style="color: #a61390;">@implementation</span> MLQuickLookPreviewController
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewWillAppear<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>animated
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>super viewWillAppear<span style="color: #002200;">:</span>animated<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self navigationItem<span style="color: #002200;">&#93;</span> setRightBarButtonItem<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> animated<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>shouldAutorotateToInterfaceOrientation<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIInterfaceOrientation<span style="color: #002200;">&#41;</span>interfaceOrientation
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>You can also see that we are allowing all orientations for this view controller in -shouldAutorotateToInterfaceOrientation:. That&#8217;s all we needed to do to get the QuickLook preview controller to behave the way our client specified&#8211;fullscreen preview without the ability to export or edit yet visible and navigable in both portrait and landscape orientations.</p>

<p>Of course, to use the QLPreviewController, you will need to add QuickLook.framework to your project and then import the headers <code>&lt;QuickLook/QuickLook.h&gt;</code> into your project somewhere such as in the derived QuickLook viewer class header as shown in the previous code block above. Then you can implement your custom previewer like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>presentFullscreen
<span style="color: #002200;">&#123;</span>
  MLQuickLookPreviewController <span style="color: #002200;">*</span>previewer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MLQuickLookPreviewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>previewer setDataSource<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>previewer setCurrentPreviewItemIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self presentModalViewController<span style="color: #002200;">:</span>previewer animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Notice we&#8217;ve set the data source for our preview controller to self. This means that our class where we&#8217;re implementing this will need to implement the QLPreviewControllerDataSource methods. So in our header file, we need to specify</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> MLDetailViewController <span style="color: #002200;">:</span> UIViewController &lt;QLPreviewControllerDataSource&gt;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>And then in the implementation file, we need to implement these two methods:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#pragma mark -</span>
<span style="color: #6e371a;">#pragma mark QLPreviewControllerDataSource</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>numberOfPreviewItemsInPreviewController<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>QLPreviewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller 
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self asset<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> ? <span style="color: #2400d9;">1</span> <span style="color: #002200;">:</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>id&lt;QLPreviewItem&gt;<span style="color: #002200;">&#41;</span>previewController<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>QLPreviewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller previewItemAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>index 
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self asset<span style="color: #002200;">&#93;</span> pathOnDiskAtCachePath<span style="color: #002200;">:</span>CACH_PATH<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> fileURLWithPath<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Sometimes you might provide a list of assets to display, but in our case we just want to display one asset, so I check a local property to see if it is nil and return 1 if it is not and zero otherwise for the number of preview items. Then, when previewItemAtIndex gets called, I just return a file URL that points to the location of the file on disk. That&#8217;s it for the code that we need to write. And that&#8217;s it for providing a very attractive and functional fullscreen asset viewer on iPad.</p>

<h2>Conclusion</h2>

<p>Projects mature over time and certain duller aspects of our apps often start glaring at us while this maturing happens. On the iPad, presentation is of the utmost importance so making small visual tweaks that gradually add the polish our apps need and deserve is very important. Go forth and do likewise. Until next time.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/bf67c9e6eb55f7fbe1d2486a8ceac095?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/perlmunger/' title='Matt Long'>Matt Long</a></h3><p>Matt Long works for Colorado Springs iOS Development shop, <a href="http://www.skyeroadsystems.com">Skye Road Systems</a>. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at <a href="mailto:matt@cimgf.com">Matt at CIMGF dot com</a> to discuss your iOS software development needs.

Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "<a href="http://www.amazon.com/Core-Animation-Simplified-Techniques-Development/dp/0321617754/ref=sr_1_2">Core Animation: Simplified Animation Techniques for Mac and iPhone Development</a>"</p><p><a href='http://www.cimgf.com/author/perlmunger/' title='More posts by Matt Long'>More Posts</a>  - <a href='http://www.skyeroadsystems.com/' title='Matt Long'>Website</a> </p><p class="wpa-nomargin">Follow Me:<br /><a class='wpa-social-icons' href='http://www.twitter.com/perlmunger'><img src='http://www.cimgf.com/wp-content/plugins/wp-about-author//images/twitter.png' alt='Twitter'/></a></p></p><p>The post <a href="http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/">A Better Fullscreen Asset Viewer with QuickLook</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing Data Made Easy</title>
		<link>http://www.cimgf.com/2012/05/29/importing-data-made-easy/</link>
		<comments>http://www.cimgf.com/2012/05/29/importing-data-made-easy/#comments</comments>
		<pubDate>Tue, 29 May 2012 22:54:20 +0000</pubDate>
		<dc:creator>Saul Mora</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Importing]]></category>
		<category><![CDATA[MagicalRecord]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1721</guid>
		<description><![CDATA[<p>Importing data is a problem that feels like it should have a library of work ready for you to use. Especially when it comes to importing data into Core Data where you have a description of your data to work with. What if there was such a library, or reusable framework, of importing code that [...]</p><p>The post <a href="http://www.cimgf.com/2012/05/29/importing-data-made-easy/">Importing Data Made Easy</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Importing data is a problem that feels like it should have a library of work ready for you to use. Especially when it comes to importing data into Core Data where you have a description of your data to work with. What if there was such a library, or reusable framework, of importing code that basically converts raw data to Core Data entities? Well, wonder no further because in this post, I&#8217;ll be discussing a new addition to the <a href="http://magicalrecord.com">MagicalRecord</a> toolset, MagicalImport available now on Github!</p>

<p><span id="more-1721"></span></p>

<p>Importing data is a simple idea, but one with many subtle complexities at the same time. The idea is easy: you need data in one form, typically an NSDictionary from a processed JSON string or file, to be converted to another form, the structured goodness of Entities in your Core Data model. This sounds a little like <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">Object-Relational Mapping</a> in the sense that you will need to tell MagicalImporting how data should be imported into your persistence mechanism. However, this case is slightly different as we&#8217;ll piggyback on Xcode, Core Data and the built in toolset to achieve our goals. </p>

<h1>Goals</h1>

<p>The data importing features now included in MagicalRecord were designed with a few design goals in mind:</p>

<ul>
<li>Be highly reusable</li>
<li>Promote maintainable import code</li>
<li>Don&#8217;t worry about performance until it&#8217;s a measured problem</li>
<li>Solve the 90% case, but make most common exceptions easy to work around</li>
<li>Keep all configurations out of code</li>
</ul>

<p>It&#8217;ll be up to all of you to determine if I did indeed meet these goals, so I encourage you to grab a copy and try it out for yourself. </p>

<h1>Implementation</h1>

<p>Rather simply, we know what a Core Data entity looks like at a class-like level. I say class-like because NSManagedObject is a class itself, but it also describes how to store data, which is also a descriptive mechanism. An NSMangedObject has three key parts, the Entity Description, a list of attributes and a list of relationships. To import data, we first import all the attributes. This is a simple enumeration, and this step simply copies values from one object to the Managed Object.</p>

<p>The next step is to import relationships. This can be a bit more tricky depending on whether the relationship is a one-to-one or one-to-many relationship. Once you figure out that you need to import a new object, you start importing that as well. Start with importing attributes on the related objects, then start importing the relationships. Sound familiar? This sounds like a job for <a href="#">recursion</a>!</p>

<p>Now, since you define reciprocal relationships in your Core Data models (if you don&#8217;t, you should), you will also have to be wary of traversing the relationship back to your original object and starting the import process all over again. This scenario is avoided if the data does not contain any cycles. Just like in physical memory, you could have a linked list of data, with the end of the list pointing back to the top of the list. Despite having a data model that is a fully connected graph, if your data doesn&#8217;t have cycles, you will avoid infinite recursion.</p>

<p>Oddly, during the import process, we can treat many-to-many as a one-to-many relationship since Core Data handles the many-to-many mapping for us. From the perspective of importing, we only work on one instance at a time, so at any point in time, looking out from an object through the many-to-many relationship, it will appear as if that single object is all that is involved.</p>

<p>The guiding philosophy during the development of MagicalImport was to assume that the defined Core Data model file is how the import data should be structured. That is, data you&#8217;re importing looks exactly like your data model. That makes the common importing code easy to write. And if that was all it did, MagicalImport would be less impressive. However, in real life situations, the source data never matches the data model exactly, but it does have generally minor deviations. By adding simple ways to handle these deviations, MagicalImport provides a simple, but powerful, framework for importing data into your Core Data based apps.</p>

<h1>Features</h1>

<p>Getting started with the MagicalImport is as easy as telling it where you want to start. The basic idea is you know which entity into which the data should be imported, so you then write a single line of code tying this entity with the data to import. There are a couple of options to kick off the import process. The first is by creating your own empty entity object, and telling that instance to import the data provided.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>contactInfo <span style="color: #002200;">=</span> <span style="color: #11740a; font-style: italic;">//processed JSON data</span>
&nbsp;
Person <span style="color: #002200;">*</span>person <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>Person MR_createEntity<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>person MR_importValuesForKeysWithObject<span style="color: #002200;">:</span>contactInfo<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>This can be helpful if you&#8217;re basically overwriting data since <em>MR_importFromObject:</em> will also perform a lookup for an existing object based on a configured lookup value (described below). Also notice how this follows the built in paradigm of importing a list of key-value pairs in Cocoa, as well as following the <a href="http://www.cimgf.com/2011/06/02/saving-json-to-core-data/">safe way to import data</a>.</p>

<p>For importing data, and automatically creating a new instance, starting with an entity class, and using a class method can also describe the process, in code, of importing a completely new set of data. Let&#8217;s see an example:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>contactInfo <span style="color: #002200;">=</span> <span style="color: #11740a; font-style: italic;">/// result from JSON parser</span></pre></td></tr></table></div>



<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">Person <span style="color: #002200;">*</span>importedPerson <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>Person MR_importFromObject<span style="color: #002200;">:</span>contactInfo<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>The <em>MR_importFromObject:</em> method provides a wrapper around creating a new object using the previously mentioned <em>MR_importValuesForKeysWithObject:</em> method, and returns the newly created object filled with data.</p>

<p>A key item of note is that both these methods are synchronous. While some imports will take longer than others, it&#8217;s still highly advisable to perform <em>all imports</em> in the background so as to not impact user interaction. As <a href="http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/">previously discussed</a>, MagicalRecord provides a handy API to make using background threads more manageable:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>MagicalRecord saveInBackgroundWithBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>localContext <span style="color: #002200;">&#123;</span>
&nbsp;
  Person <span style="color: #002200;">*</span>importedPerson <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>Person MR_importFromObject<span style="color: #002200;">:</span>personRecord inContext<span style="color: #002200;">:</span>localContext<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<h2>Array Import Wrapper</h2>

<p>It&#8217;s common for a list of data to be served using a JSON array, or you&#8217;re importing a large list of a single type of data. The details of importing such a list are taken care of in the <em>MR_importFromArray:</em> method. </p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>arrayOfPeopleData <span style="color: #002200;">=</span> <span style="color: #11740a; font-style: italic;">/// result from JSON parser</span>
&nbsp;
<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>people <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>Person MR_importFromArray<span style="color: #002200;">:</span>arrayOfPeopleData<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>This method, like <em>MR_importFromObject:</em> is also synchronous, so for background importing, use the previously mentioned helper method for performing blocks in the background.</p>

<p>If your import data exactly matches your Core Data model, then read no further because the aforementioned methods are all you need to import your data into your Core Data store. However, if your data, like most, has little quirks and minor deviations, then read on, as we&#8217;ll walk through some of the features of MagicalImport that will help you handle several commonly encountered deviations.</p>

<h2>Codeless Data Mapping</h2>

<p><img style="float: right" src="http://www.cimgf.com/wp-content/uploads/2012/05/Xcode-MappedKeyName.png" alt="Mapped Key Name in Xcode Model Editor" width="306" height="346" border="0" />MagicalImport makes extensive use of the userInfo dictionary to make configuring various options available without editing code. The userInfo dictionary is simply an NSDictionary that is attached to each entity, attribute or relationship. The Xcode Model editor handily gives you access to this dictionary with a small three row view labeled &#8216;<em>User Info</em>&#8216;. Each of the three key objects we deal with in Core Data, Entities, Attributes and Relationships, have specific MagicalImport options that are to be specified in the userInfo structure. This is important in providing context to MagicalImport. Since each Core Data object (entity, attribute and relationship) has it&#8217;s own set of mapping options, it&#8217;ll be easier to see at a glance that an attribute is using an option for an entity, for example.</p>

<p>The guiding philosophy of assuming the data model and the imported data match exactly comes in handy when it comes to the mapping step. First, MagicalImport will assume that the names of the attributes and relationships of each entity are identical to the keys of the imported data. For example, if an attribute on an entity is called &#8216;<strong>name</strong>&#8216;, MagicalImport will assume the key in the import data that matches that attribute is also called &#8216;<strong>name</strong>&#8216;.</p>

<p>However, it&#8217;s rarely the case that source data matches your model exactly. So, to tell MagicalImport what key to look for, enter &#8216;<strong>mappedKeyName</strong>&#8216; as a key in the userInfo section of the specific attribute. The value of mappedKeyName is the key that MagicalImport will use in order to query your object for a value. It&#8217;s a level of indirection that can be a little confusing, however, since it&#8217;s tied directly to the attribute to which the data is tied, it should be a little more clear that this is the mapping from the source data to your Core Data model.</p>

<p>Relationships also use the <strong>mappedKeyName</strong> option to specify which value in the source data maps to the relationship. Relationship key mapping works exactly as attribute key mapping, which will be important regarding more of the features of MagicalImport.</p>

<p>In the case of missing data, such as an attribute that is not present in the imported data, MagicalImport will simply not import anything into that attribute.</p>

<h3>Data Keypath Support</h3>

<p><a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html">Key Value Coding</a> is a common and effective tool in Objective C. MagicalImport gives you access to some of this power by allowing you to specify keyPaths as part of a <strong>mappedKeyName</strong>. If you&#8217;re familiar with KVC, this should be a fairly straightforward feature as Magicalmport passed these specified keys to the KVC methods under the covers. </p>

<p>Keypath support allows you to map data to an entity that may not have exactly the same hierarchy as the data model. For example, a data entity may store latitude and longitude, but the source data looks more like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#123;</span>
  <span style="color: #bf1d1a;">&quot;name&quot;</span><span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Point Of Origin&quot;</span>,
  <span style="color: #bf1d1a;">&quot;location&quot;</span><span style="color: #002200;">:</span>
  <span style="color: #002200;">&#123;</span>
    <span style="color: #bf1d1a;">&quot;latitude&quot;</span><span style="color: #002200;">:</span> <span style="color: #2400d9;">0.00</span>,
    <span style="color: #bf1d1a;">&quot;longitude&quot;</span><span style="color: #002200;">:</span> <span style="color: #2400d9;">0.00</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>In this case, we can specify as our data import key paths, <strong>location.latitude</strong> and <strong>location.longitude</strong> in our mappedKeyName configuration to dig into the nested data structure and import those values specifically into our core data entity.</p>

<h3 style="font-size: 1.17em">Related By Keys</h3>

<p style="text-align: justify"><img style="border-style: initial;border-color: initial;float: right;border-width: 0px" src="http://www.cimgf.com/wp-content/uploads/2012/05/XcodeRelatedByAttribute.png" alt="Xcode - Relationship related by an Attribute" width="292" height="382" border="0" />In classic relational databases, there exists the concept of a primary key. This has several nasty implications which I won&#8217;t get into here. However, for data importing to be automatic, it&#8217;s necessary to borrow this concept.</p>

<p>In order for automatic object to object mapping to occur, MagicalRecord needs to have a concept familiar to most database developers, that of a primary key.</p>

<p>MagicalImport will try a default lookup before it looks into the userInfo configuration based on the relationship definition from the model file. Every relationship in Core Data has two entities, the source and target. So, MagicalRecord will lookup the target entity, add &#8216;ID&#8217; to the end of the name, and if there is an attribute with that name, that is how related data will be connected on import. For example, if there is a relationship connected to a Person entity, MagicalImport will look for an attribute named <em>personID.</em></p>

<p>To specify a different attribute to MagicalImport, specify a value for the <strong>relatedByAttribute</strong> key in the userInfo structure. When specifying the value of this attribute, it&#8217;s important to ensure that you enter in the name of the attribute as it is known to Core Data. This way, if there is a mapping, or fail over list needed in order to determine the lookup value, MagicalImport can grab the proper configuration information straight from the attribute&#8217;s userInfo dictionary.</p>

<h3>Related By a List of Data IDs</h3>

<p>Sometimes you will get a list of data that looks something like this:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#123;</span>
   <span style="color: #bf1d1a;">&quot;name&quot;</span><span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Title of Blog post&quot;</span>,
   <span style="color: #bf1d1a;">&quot;attachments&quot;</span><span style="color: #002200;">:</span> <span style="color: #002200;">&#91;</span><span style="color: #2400d9;">3</span>, <span style="color: #2400d9;">5</span>, <span style="color: #2400d9;">100</span><span style="color: #002200;">&#93;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>This type if data is most commonly found in JSON from rails apps. It&#8217;s great because it&#8217;s efficient for transmission. However, it can be tricky in your code to do the proper lookups and connect the related entities together. MagicalImport supports this type of data format, and is handled automatically when you satisfy the two following conditions:</p>

<ul>
<li>The relationship is either a one to many, or many to many relationship</li>
<li>The <em>relatedByAttribute</em> key is specified with a proper value</li>
</ul>

<p>These two conditions basically mean its automatically detected.</p>

<h3>Failover Keys</h3>

<p>It is a common occurrence when grabbing data from web-based JSON APIs that multiple endpoints will return common data structures. However, in some cases, the same data structure may have a slightly different name in the secondary endpoint versus the primary API endpoint. To help with this case, MagicalImport provides a simple method to try multiple keys for a particular attribute or relationship. Keys are tried in a priority order, starting with a priority of one, and continuing until 10 attempts have been made. The assumption was that after 10 tries, and there is still no match, the data is either missing, or you really need to fix your source data.</p>

<p><img src="http://www.cimgf.com/wp-content/uploads/2012/05/Xcode-mappedKeyNamesWithPriority.png" alt="Mapped Key Names with fail over priorities" width="305" height="98" border="0" /></p>

<p>Setting a list of keys to try is as simple as adding &#8216;<strong>mappedKeyName.1</strong>&#8216; with the highest priority value in the userInfo structure. The next key MagicalImport will try will be &#8216;<strong>mappedKeyName.2</strong>&#8216;, and so on until it reaches &#8216;<strong>mappedKeyName.9</strong>&#8216;. Remember that the fail over order starts with 1, and increments up. This is important to remember if you find that your data isn&#8217;t importing even when you specify your list of available keys.</p>

<h2>Date Format Parsing</h2>

<p><img style="float: right" src="http://www.cimgf.com/wp-content/uploads/2012/05/XcodeDateAttributeWithCustomDateFormat.png" alt="Xcoode - Date attribute configured with a custom date format" width="295" height="344" border="0" />When an attribute on an entity is specified as a Date format, MagicalRecord uses its default date parsing function to read the dates and import them. There are two options when it comes to importing dates, the default, and custom date formats.</p>

<h3>Default Date Format</h3>

<p>The default date format for converting string dates into NSDate objects for use with your entities is:</p>

<blockquote>yyyy-MM-dd&#8217;T'HH:mm:ss&#8217;Z&#8217;</blockquote>

<p>This format was chosen as the default based on the most commonly encountered format when transmitting dates via JSON files. MagicalImport uses two pieces of information to determine when you need to parse dates. Basically, when the attribute is a Date attribute type, MagicalImport assumes that the data will be a string to be parsed, and run if through it&#8217;s own NSDateFormatter instance that will read the date string and convert it to an NSDate for use by Core Date and your app.</p>

<h3>Custom Date Formats</h3>

<p>Of course, there will be times when you encounter date formats that don&#8217;t conform to the default date format provided by MagicalRecord. You can, however, specify your own custom date format for use when MagicalRecord converts a date string to an NSDate for any particular attribute. In the userInfo dictionary, specify the key <strong>dateFormat</strong>, with the value being the date format that matches your data. MagicalRecord will proceed as usually, except it will now use your specified date format to convert the date.</p>

<h2>Import Processing Callbacks</h2>

<p>Importing data can be tricky depending on any number of factors including the complexity of the data involved or how well the data model matches the data to be imported. MagicalRecord allows for custom handling of individual attribute and relationship importing, as well as giving you control to skip over entire sections of data that may be invalid for importing in the first place.</p>

<h2>willImport: and didImport:</h2>

<p>If you&#8217;ve read Apple&#8217;s documentation on <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html">Importing data into Core Data</a>, you&#8217;ll notice that there&#8217;s a mention of <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW4">creating all your new entities first</a> so that you don&#8217;t have to do a fetch request every time you need to relate two objects together during the import processing. MagicalImport has <em>willImport:</em> and <em>didImport:</em> callbacks in your entity objects to allow you to warm up your cache if necessary. It also provides a post import hook for any post processing or notifications the should be fired after an import is complete.</p>

<h2>shouldImport:</h2>

<p>In some cases, data for importing will not be valid, and should not be imported even though it&#8217;s included in your set of data for import. MagicalImport provides a simple way to check data before it&#8217;s imported. The goal here was to provide a simple hook for a quick check of a simple attribute value. The return value of this method matters, so to allow MagicalImport to import the data provided as the parameter, return YES. And to skip the entire set of data, return NO. If you don&#8217;t specify this method at all on your entity, MagicalImport will just assume you want the data and continue with the import process.</p>

<h2>shouldImport<;relationshipName>;:</h2>

<p>Sometimes, you&#8217;re data for importing is good, except for a small subset of data connected via a relationship. Rather than going through and wasting precious cycles importing the data, only to toss it later when you determine it&#8217;s not useful, MagicalRecord provides a nice callback basically asking permission to import a relationship. At this point, you can reach down into the data, perform your check, and return YES if you should import that set of data, or NO if you don&#8217;t want that data to be imported. If no <em>shouldImport<;relationshipName>;:</em> instance method is defined on your entity, MagicalRecord will assume you want all that data below. That makes this a deviation on the standard importing logic, when you need it.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> shouldImportContacts<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>data;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>zipCode <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>data lastObject<span style="color: #002200;">&#93;</span> valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;zipCode&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> IsFormattedAsZipPlusFour<span style="color: #002200;">&#40;</span>zipCode<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>In this example, we&#8217;re checking the last object in our list for a zip code with the zip+4 format. When it&#8217;s not valid, we&#8217;ll assume the whole lump of data should be skipped. This code snippet is provided as an example of how to author a <em>shouldImport<;relationshipName>;:</em> method.</p>

<h2 style="font-size: 1.5em">import<;attributeName>;: and import<;relationshipName>;:</h2>

<p>MagicalImport does not make any assumptions as to the format of your data. While data is being imported, MagicalImport will check the attribute types, and try to make a few choices and to what, if any, data conversions to make. In the case of dates, MagicalRecord knows what to do, but what happens when you encounter a string that is in a structured, but non-standard format that should be converted to a number? The way to handle these special cases with MagicalImport is to implement an instance method named <em>import<;attributeName>;:</em> in your entity.</p>

<p>Sometimes processing data requires more custom knowledge of the data than MagicalRecord should know about. MagicalRecord provides these callbacks to allow you to handle importing of tricky sets of data. Simply implement these methods for any attribute or relationship you wish to have more control over data processing.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> importKeywords<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>data;
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSCharacterSet</span> <span style="color: #002200;">*</span>set <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSCharacterSet</span> characterSetWithCharactersInString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; ,&quot;</span><span style="color: #002200;">&#93;</span>;
    self.keywords <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>data componentsSeparatedByCharactersInSet<span style="color: #002200;">:</span>set<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>In this sample import method, you can see that our entity has an attribute called keywords. In this case, it&#8217;s a transient entity, and also an array (configured for us using <a href="https://github.com/rentzsch/mogenerator">mogenerator</a> and the Transformable attribute type). Our custom processing callback passed in the data relevant to this attribute as a parameter. This is enough narrowly scoped information for custom processing the data in this short method.</p>

<p>You&#8217;ll also notice that this method returns a boolean. This tells MagicalImport that your custom code handled the import. Return a YES if your code processed the data, so that MagicalRecord won&#8217;t. This is also the way to skip importing a particular entity, though this behavior is not encouraged. And, conversely, return NO if you want MagicalImport to continue processing the attribute and use the default import routines.</p>

<h1>An Example</h1>

<p>Let&#8217;s try a quick code example using MagicalImport to grab data into your app. Let&#8217;s suppose you want to build an RSS Feed reader. You can grab an excellent feed parsing library on github. Generally, the Feed Parser will go through the RSS or Atom styled XML and give you a structure in memory for you to traverse and display. What you may want to do is import this RSS feed into Core Data so you can quickly display it later, search or filter your feeds. Exactly what Core Data is good at doing. Let&#8217;s take a look a the code required to import such a feed.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// In APPFeed.m Core Data Entity file</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span> feedWithName<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name inContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;
<span style="color: #002200;">&#123;</span>
    APPFeed <span style="color: #002200;">*</span>feed <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self MR_findFirstByAttribute<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;name&quot;</span> withValue<span style="color: #002200;">:</span>name inContext<span style="color: #002200;">:</span>context<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>feed <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        feed <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self MR_createInContext<span style="color: #002200;">:</span>context<span style="color: #002200;">&#93;</span>;
        feed.name <span style="color: #002200;">=</span> name;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">return</span> feed;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span> importFeedStream<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSInputStream</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>inputStream;
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    FPFeed <span style="color: #002200;">*</span>feed <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>FPParser parsedFeedWithStream<span style="color: #002200;">:</span>inputStream error<span style="color: #002200;">:&amp;</span>amp;error<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>feed <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Error Parsing Feed: %@&quot;</span>, error<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    __block APPFeed <span style="color: #002200;">*</span>appFeed <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #002200;">&#91;</span>MagicalRecord saveDataWithBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span>localContext<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
        <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>feedTitle <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>feed title<span style="color: #002200;">&#93;</span>;
        appFeed <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>APPFeed feedWithName<span style="color: #002200;">:</span>feedTitle inContext<span style="color: #002200;">:</span>localContext<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#91;</span>appFeed MR_importValuesForKeysWithObject<span style="color: #002200;">:</span>feed<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p><img style="border-style: initial;border-color: initial;float: right;border-width: 0px" src="http://www.cimgf.com/wp-content/uploads/2012/05/XcodeSampleCoreDataModel.png" alt="A Sample Core Data Model for RSS Feed Content" width="600" height="370" border="0" /></p>

<p>The feedWithName:inContext: method is a general purpose pattern I like to implement in my Core Data entities. This let&#8217;s me implement how I want to look up an entity, or create it if it is not present in the data store. In this case, the important method is importFeedStream:. The logic is fairly simple. First, we parse the RSS or Atom feed based on an NSInputStream. The result is an FPFeed instance that contains the structure of the feed, sort of like a DOM in HTML. Next, we want to take the object containing the data, the feed object, and send it to the MR_importValuesForKeysWithObject: method. But first, we make sure that we have the correct instance to import into. That is, if there already is an APPFeed object that represents the content of Hacker News, for example, then we want to reuse that object. Otherwise, we need to create it, and that new instance will be our representation for Hacker News. And that&#8217;s really all there is to it from the code perspective.</p>

<p>Take a look at the sample Core Data model shown. This model contains a simple set of entities into which this data is to be imported. We can see that we have an APPFeed that contains many APPItems. Each of these also has many attributes which are copied over. In this case, the Core Data model matches the structure of the FPFeed object fairly well, so there isn&#8217;t too much custom logic needed. To import the data, we tell MagicalImport that we&#8217;ll start at the top, namely with both the entity and the data that correspond to a &#8220;Feed&#8221;. Then, MagicalImport will begin by copying data from the feed data to the feed entity. For every attribute, it examines the userInfo dictionary for one or more of the features described above, and imports according to those rules. Once the traversal reaches a relationship, in this case <em>items</em>, MagicalImport will examine the relationship, and determine if there is data corresponding to the relationship, and begin importing those entities, and the those item entities to the feed entity while also importing the attribute data according to the rules specified in the userInfo dictionary. Shown in the screenshot here is how we tell MagicalImport that the dateReleased in our model actually matches pubDate in the RSS Feed. With MagicalImport, these mappings are all specified on the specific attributes to which they apply. But in all cases, there is no code needed in order to simply tell MagicalImport which attributes map to which data field.</p>

<h1>Testing</h1>

<p>While there is no need to touch code beyond the single line required to kick off the import  process, in order to verify that your mappings work, I highly encourage you to unit test your data mappings with sample data files. <a href="http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/">Unit testing with Core Data</a> is fairly straight forward as unit tests go, especially with MagicalRecord at your side. However, downloading the same data over and over can be cumbersome when you have quite a bit of configuration to go through. It&#8217;s also easier if you understand how to decouple your data download code from your data import code. You should at least use a small set of unit tests using canned data samples to make sure you&#8217;re importing data the way you intend.</p>

<h1>Performance</h1>

<p>MagicalRecord was designed and implemented without regard specifically to performance. That is, there may currently be spots where performance lags. That does not mean that MagicalRecord is slow. It&#8217;s been quite speedy in my informal testing and general use. However, as this is an importing library, there are several logic points that are made. Remember, MagicalImport has to make several determinations about your data as it pertains to the model such as checking if selectors are implemented, determining if relationships are one-to-one, one-to-many, or many-to-many and so forth. The callbacks and traversal logic make your code easier to follow via the callbacks, but over all this will always be slower than if you had just sucked in all the data directly with hand-coded Objective C mappings.</p>

<p>If you do use MagicalRecord to import your data, and it does feel slow, please <a href="https://github.com/magicalpanda/magicalrecord/issues?utf8=?">open a ticket.</a> Or better yet, I invite you to try and fix the performance issue, and send in a pull request. I promise, I won&#8217;t <a href="https://github.com/torvalds/linux/pull/17">bite</a>. It would also really help if you added a test that included your own sample data and your solution to the included suite of unit tests. This will help ensure that that the bug won&#8217;t appear again any time soon.</p>

<h1>Conclusion</h1>

<p>Importing data has always felt like a solvable problem to me since I&#8217;ve written quite a bit of data import code for various iOS apps. MagicalImport is my attempt to solve the most common issues I&#8217;ve encountered when writing data import code, and make it so that any code I write for data import is specific to the problem at hand, rather than writing more boilerplate code. This also allows for future performance optimizations to benefit all of us with the same class of problems.</p>

<p>It is less common practice in announcement type blog posts to include things that a library doesn&#8217;t do, but I&#8217;ll list a few things on the todo list.  First, MagicalImport doesn&#8217;t handle stream parsing. That is, having a structure in memory is required at the moment. This is akin to a DOM XML parser where the entire XML structure is in memory. I&#8217;d like to someday have the SAX style option of stream parsing and importing based on events.</p>

<p>The fact that parsing relies on an in-memory data structure, that also means that a particularly large set of data could mean a rather large memory footprint during import. The most straight forward way to mitigate this is to measure any memory overhead during your imports, and break them up as necessary to keep your live memory footprint under control. But if there are other ways this could be improved, I&#8217;d love to hear your ideas.</p>

<p>An interesting side benefit of having the <em>import<;attributeName>;:</em> and <em>import<;relationshipName>;:</em> callback hooks is that my import code is far more simple, quicker to browse through. The specific code to process a particular attribute or relationship is in it&#8217;s own method making the logic of parsing a particular piece of data and easier to test and debug.</p>

<p>Also, one of my favorite aspects of MagicalImport is that there is very little code involved in the simplest of imports. Placing the mapping configuration in the Model files may feel a little cumbersome at first, and when things are not working, it can be a little tricky to find the mis-configured attribute. However, placing key-value configuration close to the data it configures feels like a good compromise of configuration and automation.</p>

<p>I hope you find MagicalImport as useful in your code and apps as I&#8217;ve found it in mine. I look forward to seeing MagicalImport in your apps! And if you do add it, I&#8217;d love to see your app on the <a href="https://github.com/magicalpanda/MagicalRecord/wiki/Apps-using-MagicalRecord">list of apps with MagicalRecord</a>!</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/e510cac938662af7c0919aeca341b139?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/magicalpanda/' title='Saul Mora'>Saul Mora</a></h3><p></p><p><a href='http://www.cimgf.com/author/magicalpanda/' title='More posts by Saul Mora'>More Posts</a>  - <a href='http://www.magicalpanda.com' title='Saul Mora'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2012/05/29/importing-data-made-easy/">Importing Data Made Easy</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/05/29/importing-data-made-easy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testing with Core Data</title>
		<link>http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/</link>
		<comments>http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/#comments</comments>
		<pubDate>Tue, 15 May 2012 21:43:58 +0000</pubDate>
		<dc:creator>Saul Mora</dc:creator>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[MagicalRecord]]></category>
		<category><![CDATA[UnitTesting]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1673</guid>
		<description><![CDATA[<p>Whether you subscribe to Test Driven Development (TDD) or another testing practice, when it comes automated unit testing with Core Data, things can be a little tricky. But if you keep it simple, and take things step by step, you can get up and running with unit testing using Core Data fairly quickly. We&#8217;ll explore [...]</p><p>The post <a href="http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/">Unit Testing with Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Whether you subscribe to Test Driven Development (TDD) or another testing practice, when it comes automated unit testing with Core Data, things can be a little tricky. But if you keep it simple, and take things step by step, you can get up and running with unit testing using Core Data fairly quickly. We&#8217;ll explore the what, how and why of unit testing with Core Data. We&#8217;ll also be using the helper library <a href="http://magicalrecord.com">MagicalRecord</a>. MagicalRecord not only lets us get up and running faster, but helps to cut down on the noise in our tests.</p>

<p><span id="more-1673"></span></p>

<h2>Testing Environment</h2>

<p>When you set up a Core Data stack using a file based store (say, using the sqlite store), that file becomes tied to the data model. That is for good reason. Core Data needs to first verify several things before it can use that data store. It must verify the entities have all the attributes the data model expects, as well as to ensure all entities are present in the store. The data and the description of that data must match exactly. However, when you are developing an app using Core Data, this schema changes fast. Adding a new attribute, or even simply changing it&#8217;s type can alter the version hashes enough so that the file version and the model version don&#8217;t match.</p>

<p>All this is to say that using a file based datastore for unit testing is problematic. Even if you were to set up your file based Core Data model to be auto migrating, it&#8217;s still highly likely you&#8217;ll perform a refactoring that is simply not compatible with automigrations. Another likely scenario when testing is that you&#8217;ll want to create simple test data for a single test, or suite of tests, and then delete it.</p>

<p>While testing with a file based Core Data store is possible, it&#8217;s fairly tricky and error prone. Generally, when you setup your test cases, you&#8217;ll want to load your sample set of data. When you&#8217;re finished, you&#8217;ll then want to delete all that data. Unit tests should fail on an error with our application code, not our test infrastructure, setup or teardown code. And besides, I know you&#8217;ve already jumped to the same conclusion I have by now, and that&#8217;s to use an In-Memory persistent store. Not only are there no file deletions to deal with, you will never have to perform a migration. Since during unit testing, you want a temporary store, the in-memory store is a perfect setup.</p>

<blockquote><strong>Note:</strong> Using an in-memory store to perform tests against a Core Data store is not an entirely new concept. <a href="http://twitter.com/secboffin">Graham Lee</a> has also previously <a href="http://iamleeg.blogspot.com/2010/01/unit-testing-core-data-driven-apps-fit.html">described</a> his process and setup for testing Core Data with an in-memory store.</blockquote>

<h2>Quickly Setting up Tests</h2>

<p>Now that we&#8217;ve gone over a little background, let&#8217;s get to how we can use <a href="http://www.magicalrecord.com">MagicalRecord</a> to easily setup our Core Data tests.</p>

<p>As we&#8217;ve discussed previously, MagicalRecord comes with a set of helpers to build a simple Core Data stack for you. We&#8217;ll use one that&#8217;s fairly straight forward:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>We&#8217;ll also want to clean up the Core Data stack after some tests, and, yes, MagicalRecord provides a handy cleanup method for you:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>MagicalRecordHelpers cleanUp<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>Let&#8217;s explore when and where to incorporate these method calls into your tests.</p>

<h2>Testing Frameworks</h2>

<p>Up to this point, the discussion hasn&#8217;t been geared toward any particular testing framework, although the syntax is common to the SenTestingKit testing framework that is now built in (and a first class citizen in Xcode4). However, there are now several testing frameworks now that provide many structural similarities, while improving on the syntax. Let&#8217;s see how things differ across a few of the more popular testing frameworks available for Objective C.</p>

<h3>SenTest, OCUnit, GHUnit</h3>

<p>SenTestingKit and <a href="https://github.com/gabriel/gh-unit">GHUnit</a> offer a very similar experience from a testing perspective. Primarily, you create a new subclass of SenTestCase, or GHTestCase, and author all your tests in methods starting with the word &#8220;<em>test</em>&#8220;. You can also run a method before all tests in the class are performed, or before each method.</p>

<p>Depending on how you set up your tests, you have two options on where to put the simple MagicalRecord setup method. If you want a pristine data store for every test (useful for isolating tests), then you&#8217;ll want to put this method in the setUp method like so:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setUp;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>However, there are certain cases where you&#8217;ll need to preload a larger test data set to test against. I would recommend doing this before each and every test as it will only slow your test runs down. And making tests slower can eventually lead to you not running them at all. I recommend setting this up once per test suite:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setUpClass;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>And to clean up your stack, simply add a call to the clean up method using the appropriate post-test method, tearDown, or tearDownClass.</p>

<h3>Kiwi, Cedar</h3>

<p><a href="https://github.com/allending/Kiwi">Kiwi</a> and <a href="https://github.com/pivotal/cedar">Cedar</a> are the <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior Driven Development (BDD)</a> style frameworks. Rather than methods, you format your tests using blocks, however there are similar mechanics when runnings tests. That is, you also have ways to setup and teardown your test Core Data stack even if the methods aren&#8217;t called setup and teardown. However, with it&#8217;s block type syntax, you can have nested setup calls to <em>beforeAll</em> and <em>beforeEach</em>, <em>afterAll</em> and <em>afterEach</em> (the BDD versions of the setup and teardown methods). You will want to place your calls to set up your test core data stack at an appropriate level within your block contexts.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">describe<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;MyEntity&quot;</span>, <span style="color: #002200;">^</span><span style="color: #002200;">&#123;</span>
&nbsp;
  beforeEach<span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span><span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
  afterEach<span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span><span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord cleanUp<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
  it<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;should do something awesome&quot;</span>, <span style="color: #002200;">^</span><span style="color: #002200;">&#123;</span> <span style="color: #11740a; font-style: italic;">/* Put your test here! */</span> <span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>As you can see, setting up and cleaning up after your tests is fairly easy with MagicalRecord.</p>

<h2>Supporting Xcode&#8217;s Unit Test Support</h2>

<p>When using a testing framework like GHUnit, the afore mentioned steps are all that&#8217;s required to get started. However, when it comes to using Xcode&#8217;s built in unit test bundle, there is one extra step required in order to get the stack setup.</p>

<p>When you first need to load up the Core Data stack, you typically use the method:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectModel</span> mergedModelsFromBundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>This method, give the parameter of nil, will look in the main bundle, which is generally the application bundle, and look for all data model files, and merge those files into a single Core Data model instance for use when instantiating an NSPersistentStoreCoordinator and it&#8217;s related NSPersistentStore. However, with the Unit Test bundle, this call does not return the correct answer, as <a href="http://iamleeg.blogspot.com/2010/01/unit-testing-core-data-driven-apps-fit.html">documented</a> by Graham Lee. The solution to this problem is simple: we need to specify the correct bundle so that the Core Data stack initialization process can continue on it&#8217;s way. To do this with MagicalRecord, we use the following setUp method for our tests:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setUp;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setDefaultModelFromClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>The <em>setDefaultModelFromClass:</em> method will perform the solution provided by Graham Lee, which is to load the model from the specified class, which, in turn, is the class of the currently executing test case. And now that we have something more generic, we have the ability to create a very simple boilerplate Core Data unit test case:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">//CoreDataTestCase.h</span>
&nbsp;
<span style="color: #a61390;">@interface</span> CoreDataTestCase <span style="color: #002200;">:</span> SenTestCase
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">//CoreDataTestCase.m</span>
<span style="color: #6e371a;">#import &quot;CoreDataTestCase.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> CoreDataTestCase
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setUp;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setDefaultModelWithClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tearDown;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord cleanUp<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>This means that when you begin authoring unit tests requiring Core Data, you can simply inherit from this base test case, and you&#8217;re ready to start writing tests.</p>

<h2>A Test Case</h2>

<p>First of all, it goes without saying that when you&#8217;re using Core Data, you create a set of custom entity classes, which are subclasses of NSManagedObject.  And, to make your life easier, you should always use <a href="http://rentzsch.github.com/mogenerator/">mogenerator</a> to create your custom entities. This is where your custom logic will live. Let&#8217;s author a sample test:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> SampleTestCase</pre></td></tr></table></div>



<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setUp;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord setDefaultModelWithClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>MagicalRecord setupCoreDataStackWithInMemoryStore<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tearDown;
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>MagicalRecord cleanUp<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>testSomeCalculationOnMyEntity;
<span style="color: #002200;">&#123;</span>
	MyEntity <span style="color: #002200;">*</span>testEntity <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>MyEntity MR_createEntity<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">float</span> expectedValue <span style="color: #002200;">=</span> …;
	STAssert<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>testEntity customCalculation<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> expectedValue, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;expected a good calculation&quot;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>The <em>MR_createEntity</em> method will use the default context that was set up when the <em>setupCoreDataStackWithInMemoryStore</em> method was called earlier on in the test run. This makes for clean tests based on Core Data, but doesn&#8217;t let the Core Data syntax get in the way of expressing the intent of the test. And, when the test has completed, this sample entity will be deleted by virtue of the store being released from memory, so that the next test can have a clean slate with which to work.</p>

<h2>Conclusion</h2>

<p>And with that, you have an extremely simple and fast way to get a test environment setup for unit testing with Core Data. What I enjoy most about this setup is that when authoring unit tests which require Core Data, I am not focused on the details of setting up and tearing down Core Data. Rather, I&#8217;m focused on a single entity, and the things it requires in order to work properly. A sample set of unit tests which, in turn, test MagicalRecord itself are included in the <a href="http://magicalrecord.com">MagicalRecord source</a> on github.</p>

<p>&nbsp;</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/e510cac938662af7c0919aeca341b139?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/magicalpanda/' title='Saul Mora'>Saul Mora</a></h3><p></p><p><a href='http://www.cimgf.com/author/magicalpanda/' title='More posts by Saul Mora'>More Posts</a>  - <a href='http://www.magicalpanda.com' title='Saul Mora'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/">Unit Testing with Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending NSData and (not) Overriding dealloc</title>
		<link>http://www.cimgf.com/2012/02/17/extending-nsdata-and-not-overriding-dealloc/</link>
		<comments>http://www.cimgf.com/2012/02/17/extending-nsdata-and-not-overriding-dealloc/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 05:53:29 +0000</pubDate>
		<dc:creator>Tom Harrington</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[System Programming]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1686</guid>
		<description><![CDATA[<p>A couple of weeks ago Matt Long was having a problem with an app running out of memory. He had a ginormous data file he needed to load up and process, and that memory hit was more than the app could bear. It would load just fine, into an NSData, but before he could finish [...]</p><p>The post <a href="http://www.cimgf.com/2012/02/17/extending-nsdata-and-not-overriding-dealloc/">Extending NSData and (not) Overriding dealloc</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>A couple of weeks ago Matt Long was having a problem with an app running out of memory. He had a ginormous data file he needed to load up and process, and that memory hit was more than the app could bear. It would <em>load</em> just fine, into an NSData, but before he could finish with it the app would run short of memory and die.</p>

<p>Until recently the obvious thing would have been to tell NSData to create a memory-mapped instance. Given <code>NSString *path</code> pointing to a file, you could create an NSData with almost no memory hit regardless of file size by creating it as:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfMappedFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>Starting with iOS 5 though, this method has been deprecated. Instead, what you&#8217;re supposed to do is:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
<span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithContentsOfFile<span style="color: #002200;">:</span>path options<span style="color: #002200;">:</span>NSDataReadingMappedAlways error<span style="color: #002200;">:&amp;</span>error<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>So, fine, whatever, it&#8217;s a different call, so what? Well, it wasn&#8217;t working. Instruments was showing that the app was taking the full memory hit when the NSData was created. Mapping wasn&#8217;t working despite using NSDataReadingMapped<em>Always</em>. So what could he do? The wheels of my mind started turning.</p>

<p><span id="more-1686"></span></p>

<h2>Memory mapped files</h2>

<p>But first, a brief aside about memory mapping.</p>

<p>Memory mapping is a cool Unix trick that lets you load a file into memory without, as it were, actually loading it into memory. It&#8217;s a way of using virtual memory to your advantage when you have a really big file and you don&#8217;t want to spend the RAM on it.</p>

<p>Contrary to common misconception, iOS does have virtual memory. It just doesn&#8217;t create swap files. But the full power of virtual memory is at your disposal. When you create a memory mapped file, the operating system gives you a memory pointer that you can use to access the file&#8217;s data. It&#8217;s as if the file was already loaded into memory but had since been swapped back out. When you access bytes in the memory map, data blocks are selectively read from the file as needed, and disposed of when they aren&#8217;t.</p>

<p>In short, it&#8217;s <strong>exactly</strong> what you need when your data file is too big to load, and if NSData won&#8217;t do it, I&#8217;ll just have to force it.</p>

<h2>By the power of <del datetime="2012-02-14T05:50:40+00:00">Greyskull</del> Unix!</h2>

<p>To create memory mapped files NSData is making use of iOS&#8217;s excellent Unix core. NSData isn&#8217;t actually mapping files itself, instead it&#8217;s using the Unix <code>mmap(2)</code> call. I can use that too. Given an <code>NSString *path</code> pointing to a file, you can create an memory mapped file like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Get an fd</span>
<span style="color: #a61390;">int</span> fd <span style="color: #002200;">=</span> open<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>path fileSystemRepresentation<span style="color: #002200;">&#93;</span>, O_RDONLY<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>fd &lt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Get file size</span>
<span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>fileAttributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSFileManager</span> defaultManager<span style="color: #002200;">&#93;</span> attributesOfItemAtPath<span style="color: #002200;">:</span>path error<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>fileAttributes <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    close<span style="color: #002200;">&#40;</span>fd<span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #400080;">NSNumber</span> <span style="color: #002200;">*</span>fileSize <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>fileAttributes objectForKey<span style="color: #002200;">:</span>NSFileSize<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// mmap</span>
<span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>mappedFile;
mappedFile <span style="color: #002200;">=</span> mmap<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#91;</span>fileSize intValue<span style="color: #002200;">&#93;</span>, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
close<span style="color: #002200;">&#40;</span>fd<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mappedFile <span style="color: #002200;">==</span> MAP_FAILED<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Map failed, errno=%d, %s&quot;</span>, <span style="color: #a61390;">errno</span>, <span style="color: #a61390;">strerror</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">errno</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>To call <code>mmap(2)</code> this code first gets a file descriptor for the file via <code>open(2)</code>. That, combined with the file&#8217;s size, is enough to create the memory mapping. Once the mapping exists, the code disposes of the file descriptor via <code>close(2)</code>. At this point, <code>mappedFile</code> points to a bunch of bytes which is more or less indistinguishable from what you&#8217;d get if you had actually read the file into memory. And NSData knows how to use byte blobs.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Create the NSData</span>
<span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>mappedData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSData</span> dataWithBytesNoCopy<span style="color: #002200;">:</span>mappedFile length<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>fileSize intValue<span style="color: #002200;">&#93;</span> freeWhenDone<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>I can convert the pointer into an NSData using one of NSData&#8217;s longer convenience initializers. Why create it this way? Because (a) I don&#8217;t want to copy the bytes, since that would negate the advantage of memory mapping, and (b) I don&#8217;t want NSData to try and clean up those bytes when it gets deallocated.</p>

<h2>The Complication</h2>

<p>But I <em>do</em> need to clean up those bytes. I just don&#8217;t want NSData to do it, because it doesn&#8217;t know the bytes came from a mapping and won&#8217;t clean them up properly. I need to remove the memory map. What needs to happen is a call to <code>munmap(2)</code> when the NSData deallocates.</p>

<p>So, what does the code need to look like in order to make this call? Ideally the cleanup should happen automatically. I could just call <code>munmap(2)</code> directly. But that would mean keeping the map pointer around and then making a separate call. All to clean up what is, conceptually at least, an internal data structure. It would work but it&#8217;s ugly.</p>

<p>Anyway, with ARC there&#8217;s the chance that I&#8217;d make the call before the NSData deallocated, with disastrous results. Really what I&#8217;d like to do is wrap the code above into a convenient API where you can create the mapped NSData, use it, and dispose of it normally. Any extra cleanup should just <em>happen</em>. After all this is Cocoa and it&#8217;s supposed to work well.</p>

<p>My first thought was to subclass NSData and have the subclass store the map pointer. Then the subclass could call <code>munmap(2)</code> from its <code>-dealloc</code> method. But NSData is a class cluster, and subclassing class clusters is kind of a pain in the ass. Class clusters are a bunch of classes that masquerade as a specific public class. Examples include NSString, NSArray, and others. And of course NSData.</p>

<p>You may recall that <code>-init</code> is not required to return an instance of the class you thought you were creating. That is, if you call</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;">Foo <span style="color: #002200;">*</span>myFoo <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>Foo alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>&#8230;the resulting object is not required to actually be an instance of <code>Foo</code>. Class clusters are a case where this happens. When you create an NSData, what you&#8217;re probably getting is an instance of something like NSConcreteData. That class isn&#8217;t documented but it acts like an NSData and you generally can&#8217;t tell the difference.</p>

<p>Subclassing class clusters can be challenging. You need to override all of the superclass&#8217;s <em>primitive</em> methods. Those are the methods that access the object&#8217;s data directly. NSData&#8217;s primitive methods aren&#8217;t documented, either. If you don&#8217;t get them all you&#8217;ll get crashes with fairly incomprehensible exceptions like:</p>

<p><pre>
Catchpoint 6 (exception thrown).2012-02-07 21:04:10.620 MapTest[9719:f803] <strong>*
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '</strong>*
initialization method -initWithBytes:length:copy:freeWhenDone:bytesAreVM: cannot be
sent to an abstract object of class NSMappedData: Create a concrete instance!'
</pre></p>

<p>I could probably figure out what the primitive methods are but doing that without documentation has a strong whiff of reverse engineering. I&#8217;d really rather avoid that. But how else can I make sure the call happens? And can I make it happen automatically?</p>

<h2>Adding dealloc code in a category</h2>

<p>The method I had in mind for creating mapped NSData instances would look something like:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>dataWithContentsOfReallyMappedFile<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>path;</pre></td></tr></table></div>


<p>I could put that in a category except that to make it easy to use I&#8217;d need to have some code to <code>-dealloc</code> that could call <code>munmap(2)</code>. That&#8217;s more or less what what I&#8217;m going to do.</p>

<p>Wait, what? You can&#8217;t override <code>-dealloc</code> in a category. But thanks to associated objects, you don&#8217;t have to. If have some object A, and you associate a secondary object B with it, then when A gets deallocated, B will too. If you have something you really need to happen when A gets deallocated, you can call that code from B&#8217;s dealloc method. Bingo, deallocation code for A that runs in a separate class. As long as you don&#8217;t need to access A&#8217;s private internal data, anyway.</p>

<p>This could be pretty useful so I decided to write it as a generic system that I could use with memory mapped NSData instances but that isn&#8217;t tied to them. I created a generic class called <code>DeallocationHandler</code>:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> DeallocHandler <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>readwrite, copy<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">void</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span>theBlock<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> DeallocHandler
<span style="color: #a61390;">@synthesize</span> theBlock;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>theBlock <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        theBlock<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>This doesn&#8217;t do much on its own. Give it a block and it will run the block when it gets deallocated. Where it gets interesting is when you use it in a category on NSObject:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">static</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>deallocArrayKey <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;deallocArrayKey&quot;</span>;
&nbsp;
<span style="color: #a61390;">@implementation</span> <span style="color: #400080;">NSObject</span> <span style="color: #002200;">&#40;</span>deallocBlock<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addDeallocBlock<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">^</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>theBlock;
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>deallocBlocks <span style="color: #002200;">=</span> objc_getAssociatedObject<span style="color: #002200;">&#40;</span>self, <span style="color: #002200;">&amp;</span>deallocArrayKey<span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>deallocBlocks <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        deallocBlocks <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
        objc_setAssociatedObject<span style="color: #002200;">&#40;</span>self, <span style="color: #002200;">&amp;</span>deallocArrayKey, deallocBlocks, OBJC_ASSOCIATION_RETAIN_NONATOMIC<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
    DeallocHandler <span style="color: #002200;">*</span>handler <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DeallocHandler alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>handler setTheBlock<span style="color: #002200;">:</span>theBlock<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>deallocBlocks addObject<span style="color: #002200;">:</span>handler<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>The <code>-addDeallocBlock:</code> method associates an array of DeallocationHandler instances with the target object. Each DeallocationHandler in turn has a block provided by the caller. The upshot is that, when the target object deallocates, all of those blocks will be run. This lets me attach dealloc-time code to any object. In fact I could add as many blocks as I needed and they&#8217;d run in order.</p>

<p>One minor caveat is that you <em>really</em> need to watch the memory references in these blocks. If the block references the object that it&#8217;s attached to, then the circular references mean that the object won&#8217;t ever get deallocated. This is just standard safe block usage, though.</p>

<h2>Getting back to NSData</h2>

<p>Using the deallocation block scheme I can add a block calling <code>munmap(2)</code> to my NSData object by adding this code right after I create it:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>mappedData addDeallocBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#123;</span>
    munmap<span style="color: #002200;">&#40;</span>mappedFile, <span style="color: #002200;">&#91;</span>fileSize intValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>This leaves me with two categories instead of just one, but in the end I can just create mapped NSData instances and not bother with special cleanup code in my app.</p>

<h2>Conclusion</h2>

<p>Never forget that Apple&#8217;s APIs are not a menu of possibilities. They&#8217;re a set of tools, but you can and should build your own tools when you need them. Unix is available on iOS, so don&#8217;t be afraid to use it. In this example we&#8217;ve seen how to:</p>

<ul>
<li>Add deallocation code to any object without subclassing.</li>
<li>Create memory mapped NSData instances even though the official API has been deprecated and the new one doesn&#8217;t currently work.</li>
</ul>

<p>The code described in this post can be found at <a href="https://github.com/atomicbird/atomictools">Github</a>.</p>

<p><strong>Update:</strong> In response to queries I&#8217;ve had via Twitter, please be aware that the code described here assumes that you&#8217;re using ARC. If you&#8217;re not using ARC you&#8217;ll need to add a line that releases the new DeallocHandler before <code>-addDeallocBlock:</code> returns.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/be7f8a20fac1215c06fa723565fdfb80?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/atomicbird/' title='Tom Harrington'>Tom Harrington</a></h3><p></p><p><a href='http://www.cimgf.com/author/atomicbird/' title='More posts by Tom Harrington'>More Posts</a>  - <a href='http://www.atomicbird.com/' title='Tom Harrington'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2012/02/17/extending-nsdata-and-not-overriding-dealloc/">Extending NSData and (not) Overriding dealloc</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/02/17/extending-nsdata-and-not-overriding-dealloc/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A phased approach to sandboxing</title>
		<link>http://www.cimgf.com/2012/02/04/a-phased-approach-to-sandboxing/</link>
		<comments>http://www.cimgf.com/2012/02/04/a-phased-approach-to-sandboxing/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 04:04:07 +0000</pubDate>
		<dc:creator>Fraser Hess</dc:creator>
				<category><![CDATA[AppStore]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1655</guid>
		<description><![CDATA[<p>With the March 1st start date approaching when sandboxing becomes a requirement for submissions to the Mac App Store, I&#8217;ve been considering my options. I have 2 products, one of which was easy to sandbox and the other, well, not so much. When I say &#8220;easy to sandbox&#8221;, I mean it fit neatly in the [...]</p><p>The post <a href="http://www.cimgf.com/2012/02/04/a-phased-approach-to-sandboxing/">A phased approach to sandboxing</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>With the March 1st start date approaching when sandboxing becomes a requirement for submissions to the Mac App Store, I&#8217;ve been considering my options.<span id="more-1655"></span>
I have 2 products, one of which was easy to sandbox and the other, well, not so much. When I say &#8220;easy to sandbox&#8221;, I mean it fit neatly in the &#8220;permanent&#8221; entitlements and doesn&#8217;t need any files migrated into the sandbox, besides it&#8217;s preferences, which is done automatically for you.</p>

<p>Now, my sandbox technical challenges are not DOA. Some apps and classes of app are in effect outlawed by the sandbox rules. I feel for the developers of those apps, but fortunately for me, I&#8217;m not facing that.</p>

<p>My challenges fall more the &#8220;a few features may need rethinking and rewriting&#8221; category. At first I expected to have a long hiatus between updates while I worked on these features. But instead, I&#8217;m easing this transition by implementing sandboxing in 2 phases.</p>

<ol>
<li>Add sandboxing to the MAS build of my app. Use temporary entitlements where necessary to maintain functionality. Make minor adjustments to run inside the sandbox. Submit an update to test the approval process.</li>
<li>Begin the rethinking and rewriting of sandbox-incompliant features.</li>
</ol>

<p>Advantages I can see to this approach:</p>

<ul>
<li>I can continue to fix bugs, and issue updates beyond March 1st without a long hiatus.</li>
<li>Development on my app does not appear quiescent.</li>
<li>By submitting early, I&#8217;m not testing approval when trying to push out a needed bug fix.</li>
<li>By using temporary entitlements, I signal to Apple that these are needed and useful.</li>
<li>I buy more time to rethink and rewrite.</li>
</ul>

<p>Sandboxing is a great leap in application security but every app has a different story when it comes to the implementation details. I encourage <a href="http://bugreport.apple.com/">bug reporting</a>. It&#8217;s important to explain to the Apple engineers what we developers need. And I hope that some of the thoughts here help you navigate the challenges.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/fe6fd7c5ff617da23c7ef2ced524a622?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/fraser/' title='Fraser Hess'>Fraser Hess</a></h3><p></p><p><a href='http://www.cimgf.com/author/fraser/' title='More posts by Fraser Hess'>More Posts</a> </p></p><p>The post <a href="http://www.cimgf.com/2012/02/04/a-phased-approach-to-sandboxing/">A phased approach to sandboxing</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/02/04/a-phased-approach-to-sandboxing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handling incoming JSON redux</title>
		<link>http://www.cimgf.com/2012/01/11/handling-incoming-json-redux/</link>
		<comments>http://www.cimgf.com/2012/01/11/handling-incoming-json-redux/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 15:00:37 +0000</pubDate>
		<dc:creator>Tom Harrington</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[System Programming]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1573</guid>
		<description><![CDATA[<p>A few months ago I wrote here about a generic approach to safely take incoming JSON and save values to Core Data object. The goals of that code were twofold: Provide a safe, generic alternative to Cocoa&#8217;s -setValuesForKeysWithDictionary: for use with NSManagedObject and its subclasses Handle cases where JSON data didn&#8217;t match up with what [...]</p><p>The post <a href="http://www.cimgf.com/2012/01/11/handling-incoming-json-redux/">Handling incoming JSON redux</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>A few months ago I wrote here about <a href="http://www.cimgf.com/2011/06/02/saving-json-to-core-data/">a generic approach to safely take incoming JSON and save values to Core Data object</a>. The goals of that code were twofold:</p>

<ol>
    <li>Provide a safe, generic alternative to Cocoa&#8217;s <code>-setValuesForKeysWithDictionary:</code> for use with NSManagedObject and its subclasses</li>
    <li>Handle cases where JSON data didn&#8217;t match up with what the managed objects expected. Getting a string where you expect a numeric value, or vice versa, for example, or getting a string representation of a date when you want a real NSDate object.</li>
</ol>

<p>The first item was the most important. It&#8217;s tempting to use <code>-setValuesForKeysWithDictionary:</code> to transfer JSON to a model object in one step. The method runs through the dictionary and calls <code>-setValue:forKey:</code> on the target object for every entry. It has a fatal flaw though, in that it doesn&#8217;t check to see if the target object actually has a key before trying to set it. Using this method when you don&#8217;t have absolute control over the dictionary contents is an invitation to unknown key exceptions and nasty app crashes.</p>

<p>Fixing this for managed objects was relatively easy because Core Data provides convenient Objective-C introspection methods. The general approach was:</p>

<ul>
    <li>Get a list of the target object&#8217;s attributes</li>
    <li>For each attribute, see if the incoming dictionary has an entry. If so,</li>
<ul>
    <li>Compare the incoming type to the expected type, and convert if necessary.</li>
    <li>Call <code>-setValue:forKey:</code> with that key and its value.</li>
</ul>
</ul>

<p>And then just last week I had the thought, wouldn&#8217;t it be nice if this worked for <em>any</em> object, not just for managed objects?</p>

<p><span id="more-1573"></span></p>

<h2>Objective-C introspection</h2>

<p>Since Objective-C is dynamic, pretty much everything you&#8217;d want to know about a class is available at run time. I&#8217;m not just talking about methods like <code>-respondsToSelector:</code> and <code>-isKindOfClass:</code>, though those are extremely useful. You can go much, much deeper than that, inspecting (and even changing) every aspect of a class&#8217;s implementation. Much of this happens via C function calls rather than Objective-C method calls. The Objective-C runtime is not actually written in Objective-C, and it&#8217;s the runtime that has the information.</p>

<p>To update the code for use with objects that don&#8217;t inherit from NSManagedObject the new code looks through the properties declared on a class and uses those to run through the incoming JSON. The general approach is the same but the implementation uses NSObject properties instead of NSEntityDescription attributes.</p>

<p>It&#8217;s also possible to look through the instance variables instead of the properties. Often this would amount to the same thing. Where they differ is when the backing ivar has a different name, i.e. when you&#8217;re using something like:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@synthesize</span> foo <span style="color: #002200;">=</span> __myReallyBizarrePrivateName____;</pre></td></tr></table></div>


<p>In that case iterating over properties would find <code>foo</code> while iterating over instance variables would find <code>__myReallyBizarrePrivateName____</code>. Either is valid but I&#8217;m going with the properties because (at least for me) they&#8217;re more likely to match up with the JSON keys.</p>

<h2>First pass: iterating over properties</h2>

<p>A simple version that meets requirement #1 looks like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setValuesForKeysWithJSONDictionary<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>keyedValues dateFormatter<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>dateFormatter
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">int</span> propertyCount;
    objc_property_t <span style="color: #002200;">*</span>properties <span style="color: #002200;">=</span> class_copyPropertyList<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&amp;</span>propertyCount<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;propertyCount; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        objc_property_t property <span style="color: #002200;">=</span> properties<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>propertyName <span style="color: #002200;">=</span> property_getName<span style="color: #002200;">&#40;</span>property<span style="color: #002200;">&#41;</span>;
        <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>keyName <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithUTF8String<span style="color: #002200;">:</span>propertyName<span style="color: #002200;">&#93;</span>;
&nbsp;
        <span style="color: #a61390;">id</span> value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>keyedValues objectForKey<span style="color: #002200;">:</span>keyName<span style="color: #002200;">&#93;</span>;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>value <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>keyName<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>properties<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>This starts with a call to <code>class_copyPropertyList()</code>, which gets a C-style array of property declarations for the requested class. The <code>propertyCount</code> argument indicates how many properties are in the array. The array contains zero or more <code>objc_property_t</code> entries, which is an opaque structure.</p>

<p>The code iterates through this array. For each one it uses <code>property_getName</code> to get the property name as a C-style string. Then it converts this to an NSString and uses that to look up entries in the incoming dictionary. And, <em>voila</em>, we&#8217;re using the class&#8217;s own properties to look up values in the dictionary instead of the other way around.</p>

<p>A final detail&#8211; unusual in Objective-C code&#8211; is the call to <code>free()</code>. Since <code>class_copyPropertyList()</code> has <em>copy</em> in its name, the calling code is responsible for disposing of the returned data. And since it&#8217;s a C call, this needs to be done C style. This call would need to be there even if the project were using ARC.</p>

<h2>Back to Core Data, briefly</h2>

<p>The great thing about this solution is that it&#8217;s not the non-managed-object alternative to the previous version, it&#8217;s a direct replacement. This approach works just as well on managed objects as on other objects&#8211; provided, that is, that you create custom subclasses of <code>NSManagedObject</code> for your entities that declare properties for managed object attributes. So long as the properties exist, the code works. If you&#8217;re using Xcode or <a href="http://rentzsch.github.com/mogenerator/">mogenerator</a> to generate your managed object subclasses, you&#8217;re covered. If you aren&#8217;t creating custom subclasses, first of all, why not? But in that case this approach won&#8217;t work since <code>NSManagedObject</code> doesn&#8217;t have the necessary property declarations.</p>

<h2>Does it have to be like this?</h2>

<p>Some of you may have noticed that it&#8217;s possible to do the same thing without any mucking about with the runtime by doing something like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>key <span style="color: #a61390;">in</span> keyedValues<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">@try</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>keyedValues objectForKey<span style="color: #002200;">:</span>key<span style="color: #002200;">&#93;</span> forKey<span style="color: #002200;">:</span>key<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
        <span style="color: #a61390;">@catch</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSException</span> <span style="color: #002200;">*</span>exception<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            <span style="color: #11740a; font-style: italic;">// Do nothing</span>
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>In this case the dictionary keys still drive the action, but exception handling means the code doesn&#8217;t crash on unknown keys. So why bother then? Because of requirement #2 above. Coercing JSON into appropriate data types is going to require introspection. With this simplified approach you don&#8217;t crash, but you also don&#8217;t get type conversions. If not crashing is all you&#8217;re interested in, this works just as well and is probably faster. It&#8217;s certainly simpler anyway. It&#8217;s not going to do what I need though.</p>

<h2>JSON Fixes</h2>

<p>To meet requirement #2 the code needs to go deeper. As with the Core Data implementation, it needs to look up the expected value for the property and compare that to the type of the incoming data. To do this I&#8217;ll expand the <code>if</code> block beginning on line 12 above to look like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>value <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>typeEncoding <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
    typeEncoding <span style="color: #002200;">=</span> property_copyAttributeValue<span style="color: #002200;">&#40;</span>property, <span style="color: #bf1d1a;">&quot;T&quot;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>typeEncoding <span style="color: #002200;">==</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">continue</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">switch</span> <span style="color: #002200;">&#40;</span>typeEncoding<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'@'</span><span style="color: #002200;">:</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #11740a; font-style: italic;">// Object</span>
            <span style="color: #a61390;">Class</span> class <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">strlen</span><span style="color: #002200;">&#40;</span>typeEncoding<span style="color: #002200;">&#41;</span> &gt;<span style="color: #002200;">=</span> <span style="color: #2400d9;">3</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>className <span style="color: #002200;">=</span> strndup<span style="color: #002200;">&#40;</span>typeEncoding<span style="color: #002200;">+</span><span style="color: #2400d9;">2</span>, <span style="color: #a61390;">strlen</span><span style="color: #002200;">&#40;</span>typeEncoding<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#41;</span>;
                class <span style="color: #002200;">=</span> NSClassFromString<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithUTF8String<span style="color: #002200;">:</span>className<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
            <span style="color: #002200;">&#125;</span>
            <span style="color: #11740a; font-style: italic;">// Check for type mismatch, attempt to compensate</span>
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>class isSubclassOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value stringValue<span style="color: #002200;">&#93;</span>;
            <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>class isSubclassOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                <span style="color: #11740a; font-style: italic;">// If the ivar is an NSNumber we really can't tell if it's intended as an integer, float, etc.</span>
                <span style="color: #400080;">NSNumberFormatter</span> <span style="color: #002200;">*</span>numberFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumberFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
                <span style="color: #002200;">&#91;</span>numberFormatter setNumberStyle<span style="color: #002200;">:</span>NSNumberFormatterDecimalStyle<span style="color: #002200;">&#93;</span>;
                value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>numberFormatter numberFromString<span style="color: #002200;">:</span>value<span style="color: #002200;">&#93;</span>;
                <span style="color: #002200;">&#91;</span>numberFormatter release<span style="color: #002200;">&#93;</span>;
            <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>class isSubclassOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDate</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#40;</span>dateFormatter <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span>value<span style="color: #002200;">&#93;</span>;
            <span style="color: #002200;">&#125;</span>
&nbsp;
            <span style="color: #a61390;">break</span>;
        <span style="color: #002200;">&#125;</span>
&nbsp;
        <span style="color: #a61390;">default</span><span style="color: #002200;">:</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">break</span>;
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#91;</span>self setValue<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>keyName<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>typeEncoding<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>The runtime provides information about properties via the call to <code> property_copyAttributeValue()</code> on line 3. The first argument is the property of interest. The second one can have a bunch of different values depending on what you want to look up. A &#8220;T&#8221; requests a C-style string that describes the property type. For full details on what you can do with the second argument, see the (somewhat out of date as of this writing) <a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html">&#8220;Declared Properties&#8221; section of Apple&#8217;s Objective-C Runtime Programming Guide</a>.</p>

<p>If the property type is a pointer to a class, the return value will be something like <code>T@"NSNumber"</code>, <code>T@"NSString"</code>, <code>T@"MyClass"</code>, etc. The next thing the code does then is to check for a leading <code>@</code> and, if found, set about getting the <code>Class</code> that the type string names. This happens in lines 12-16. The code strips off the <code>@</code> and the quotes, converts to <code>NSString</code>, and uses <code>NSClassFromString</code> to get the <code>Class</code>.</p>

<p>The rest of this code is remarkably similar to the Core Data version, looking for type mismatches and converting the incoming value where needed. The chief difference is that it uses <code>-isSubclassOfClass:</code> to check on the expected type of the property instead of looking at the Core Data-specific <code>NSAttributeType</code>.</p>

<p>Except for one important difference. For numeric properties, the Core Data attribute type would indicate whether a floating point or integer value was expected. With <code>NSNumber</code> we have no way of knowing. So the code uses <code>NSNumberFormatter</code> to parse incoming strings and leaves it at that. If this kind of mismatch occurs then there are bigger problems anyway. You could change the code to round a <code>float</code> to an <code>int</code>, but is that actually going to be a valid result? Maybe, maybe not.</p>

<p>The type comparisons in this code could go on forever but in this case the code is specifically looking for problems that sometimes crop up with JSON.</p>

<p>Since <code>property_copyAttributeValue()</code> has <em>copy</em> in its name, this block adds another call to <code>free()</code> to clean up after itself.</p>

<h2>Handling primitives</h2>

<p>But what if the expected value is not an object at all? What if it&#8217;s a primitive <code>int</code>? Fortunately <code>property_copyAttributeValue()</code> covers that case as well. In this case the type encoding string is shorter, with values like <code>Ti</code> for <code>int</code>, <code>Tf</code> for <code>float</code>, <code>TQ</code> for <code>unsigned long long</code>, etc (again, see Apple&#8217;s docs for a full list).</p>

<p>With this information, the <code>switch</code> statement above can be expanded with a few more cases.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'i'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// int</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'s'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// short</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'l'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// long</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'q'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// long long</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'I'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// unsigned int</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'S'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// unsigned short</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'L'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// unsigned long</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'Q'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// unsigned long long</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'f'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// float</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'d'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// double</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'B'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// BOOL</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                <span style="color: #400080;">NSNumberFormatter</span> <span style="color: #002200;">*</span>numberFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumberFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
                <span style="color: #002200;">&#91;</span>numberFormatter setNumberStyle<span style="color: #002200;">:</span>NSNumberFormatterDecimalStyle<span style="color: #002200;">&#93;</span>;
                value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>numberFormatter numberFromString<span style="color: #002200;">:</span>value<span style="color: #002200;">&#93;</span>;
                <span style="color: #002200;">&#91;</span>numberFormatter release<span style="color: #002200;">&#93;</span>;
            <span style="color: #002200;">&#125;</span>
            <span style="color: #a61390;">break</span>;
        <span style="color: #002200;">&#125;</span>
&nbsp;
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'c'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// char</span>
        <span style="color: #a61390;">case</span> <span style="color: #bf1d1a;">'C'</span><span style="color: #002200;">:</span> <span style="color: #11740a; font-style: italic;">// unsigned char</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>value isKindOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
                <span style="color: #a61390;">char</span> firstCharacter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>value characterAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
                value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithChar<span style="color: #002200;">:</span>firstCharacter<span style="color: #002200;">&#93;</span>;
            <span style="color: #002200;">&#125;</span>
            <span style="color: #a61390;">break</span>;
        <span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>The first half of this, up to line 20, handles all the numeric types. As with the previous code block there&#8217;s no attempt to work out floating point/integer conflicts since it&#8217;s impossible to know how to handle this in the general case. It would be possible to break this up into more specific checks, say by using <code>-[NSString intValue]</code> when an integer result is expected and hope for valid data. But the code above handles the case where you actually have an integer value, and if you don&#8217;t have one then again, you have bigger problems.</p>

<p>The rest of this block handles a primitive <code>char</code> property by taking the first character in the incoming string. Longer strings can&#8217;t be stored in a <code>char</code> anyway, so this is the best approach.</p>

<p>In both cases the conversion results in an <code>NSNumber</code> instead of a primitive type. That&#8217;s OK though&#8211; <code>-setValue:forKey:</code> has our back here and will unbox the object for us.</p>

<h2>Conclusion</h2>

<p>Using this approach makes it a lot easier to deal with web services. You can&#8217;t always rely on the results matching what you expect (or what&#8217;s documented). Inspecting classes at run time takes a more defensive approach to dealing with data you can&#8217;t control.</p>

<p>A category on NSObject that implements this code can be found at <a href="https://gist.github.com/1592634">github</a>.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://1.gravatar.com/avatar/be7f8a20fac1215c06fa723565fdfb80?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/atomicbird/' title='Tom Harrington'>Tom Harrington</a></h3><p></p><p><a href='http://www.cimgf.com/author/atomicbird/' title='More posts by Tom Harrington'>More Posts</a>  - <a href='http://www.atomicbird.com/' title='Tom Harrington'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2012/01/11/handling-incoming-json-redux/">Handling incoming JSON redux</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2012/01/11/handling-incoming-json-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parent Watching Its Child</title>
		<link>http://www.cimgf.com/2011/10/14/parent-watching-its-child/</link>
		<comments>http://www.cimgf.com/2011/10/14/parent-watching-its-child/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 10:28:19 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Core Data]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1542</guid>
		<description><![CDATA[<p>Recently on StackOverflow I have seen several questions regarding the desire for a parent Entity to be updated whenever an attribute within the child has changed. There are several different ways to solve this problem. The easiest is to have the child ping the parent whenever it changes and then the parent can update any [...]</p><p>The post <a href="http://www.cimgf.com/2011/10/14/parent-watching-its-child/">Parent Watching Its Child</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Recently on <a href="http://stackoverflow.com">StackOverflow</a> I have seen several questions regarding the desire for a parent Entity to be updated whenever an attribute within the child has changed.</p>

<p>There are several different ways to solve this problem.  The easiest is to have the child ping the parent whenever it changes and then the parent can update any values it needs to as a result of that ping.
<span id="more-1542"></span>
Another solution that I considered was to have the parent observe the property on each child.  Of course this requires additional code to handle when a child is removed from the parent and when a new child is added to the parent.  Lots of code to manage and the potential for fragility is rather high.</p>

<p>The most interesting solution that I offered was to have the parent watch for change notifications and react to them.  It is this solution that I will discuss in a little more depth.</p>

<h2>Change Notifications</h2>

<p>Core Data produces several different notifications during its lifecycle.  The most commonly used notification is <code>NSManagedObjectContextDidSaveNotification</code>.  Whenever a <code>NSManagedObjectContext</code> saves it will fire two notifications, one before the save and one after the save.  The one before the save does not contain any direct information about what is going to be saved although you can discover it yourself.</p>

<p>The second one, <code>NSManagedObjectContextDidSaveNotification</code> contains a reference to each entity that it saved; whether they are newly inserted entities, updated entities or deleted entities.</p>

<p>There is another notification that is not used nearly as often; <code>NSManagedObjectContextObjectsDidChangeNotification</code>.  This notification is significantly more chatty than the other two.  It potentially can fire every time an entity changes.  More specifically it will fire at the end of each run loop where an entity has changed.  While this notification is more chatty, it is more useful for this purpose.</p>

<h2>Why use NSManagedObjectContextObjectsDidChangeNotification?</h2>

<p>Of the three, the <code>NSManagedObjectContextObjectsDidChangeNotification</code> is the most useful for a parent/child monitoring.  Both <code>NSManagedObjectContextDidSaveNotification</code> and <code>NSManagedObjectContextWillSaveNotification</code> only fire when a <code>NSManagedObjectContext</code> has been asked to save.  A save can be a very rare event; possibly only once during the life of the application.</p>

<p>However, <code>NSManagedObjectContextObjectsDidChangeNotification</code> fires frequently enough that we can use it without having to worry about when a save is going to occur.  We can use it during the life of the application and keep a parent updated to the status of its children.</p>

<h2>An Example</h2>

<p>A common example that I like to use while I am testing these theories is my very simple RSS reader. Those who have watched my <a href="http://ideveloper.tv/video/coredatacourse.html">Core Data videos</a> are familiar with Zeader.</p>

<p>In Zeader, there are only two entities:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2011/10/Model.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2011/10/Model-300x163.png" alt="" title="Model" width="300" height="163" class="alignnone size-medium wp-image-1543" /></a></p>

<p>In this example we want the Server entity to be updated whenever the read attribute on a child has changed.  To do that we are going to make a few enhancements to the Server entity subclass.</p>

<h3><code>-awakeFromInsert</code> and <code>-awakeFromFetch</code></h3>

<p>The first change we need to make is with the awake methods.  Whenever a Server entity is created or loaded we need to start listening for <code>NSManagedObjectContextObjectsDidChangeNotification</code> postings.</p>

<pre><code>- (void)awakeFromInsert
{
  [super awakeFromInsert];

  NSString *name = NSManagedObjectContextObjectsDidChangeNotification;
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center addObserver:self 
             selector:@selector(changes:) 
                 name:name 
               object:nil];
}

- (void)awakeFromFetch
{
  [super awakeFromFetch];

  NSString *name = NSManagedObjectContextObjectsDidChangeNotification;
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center addObserver:self 
             selector:@selector(changes:) 
                 name:name 
               object:nil];
}
</code></pre>

<h3><code>-willTurnInfoFault</code></h3>

<p>To be clean we need to stop listening whenever the Server is about to be removed from memory.  Since it is inappropriate to override the <code>-dealloc</code> method of a <code>NSManagedObject</code> we need to do so in the <code>-willTurnIntoFault</code> method.</p>

<pre><code>- (void)willTurnIntoFault
{
  [super willTurnIntoFault];
  NSString *name = NSManagedObjectContextObjectsDidChangeNotification;
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center removeObserver:self 
                    name:name 
                  object:nil];
}
</code></pre>

<p>This method of course, just like the two awake methods previously can be rolled up into just two lines.  They are broken apart here to make it easier to consume on the web.</p>

<h3><code>-changes:</code></h3>

<p>The last piece to the puzzle is the need to react to those changes as they are posted.</p>

<pre><code>- (void)changes:(NSNotification*)notification
{
  NSSet *objects = nil;
  NSMutableSet *combinedSet = nil;
  NSPredicate *predicate = nil;
  NSSet *unreadItems = nil;

  NSDictionary *userInfo = [notification userInfo];

  objects = [userInfo valueForKey:NSInsertedObjectsKey];
  combinedSet = [NSMutableSet setWithSet:objects];

  objects = [[notification userInfo] valueForKey:NSUpdatedObjectsKey];
  [combinedSet unionSet:objects];

  objects = [[notification userInfo] valueForKey:NSDeletedObjectsKey];
  [combinedSet unionSet:objects];

  predicate = [NSPredicate predicateWithFormat:@"entity.name == %@ &amp;&amp; server == %@", 
              @"FeedItem", self];
  [combinedSet filterUsingPredicate:predicate];

  if ([combinedSet count] == 0) {
    return;
  }

  predicate = [NSPredicate predicateWithFormat:@"read == NO"];
  unreadItems = [[self feedItems] filteredSetUsingPredicate:predicate];
  [self setUnreadCount:[unreadItems count]];
  DLog(@"server status changed %i", [unreadItems count]);
}
</code></pre>

<p>First, we do not really care whether the entities are inserted, deleted or updated.  We just need an answer to a simpler question: Are any of the entities that I care about in this change set?  Since our question is easier, we first can lump all of the changes into a single set.</p>

<p>Once we have all of the changes in a single set we then filter that set on the important question.  The predicate needs to be in a specific order; first we filter on the type of entity (<code>FeedItem</code>) we care about and then we filter on its relationship (is its <code>Server</code> me?).</p>

<p>This predicate reduces the <code>NSMutableSet</code> to only those <code>FeedItem</code> entities that are children of this instance of <code>Server</code>.  If that resulting <code>NSMutableSet</code> is zero then there are no relevant changes and we return; done.</p>

<p>If there are changes we want to update our <code>unreadCount</code>.  To do that we grab all of our <code>feedItems</code> and filter them with a simpler predicate of <code>@"read == NO"</code>.  The result of that filter can then be plugged into our <code>unreadCount</code>.</p>

<h2>Conclusion</h2>

<p>There are a few potential performance hot spots in this example.  However, the monitoring of children by the parent is always going to be a performance hotspot.  Therefore, great care should be given whenever to adding a watcher like this.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/4451102e25dedd74169cf84deea71738?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/mzarra/' title='Marcus Zarra'>Marcus Zarra</a></h3><p></p><p><a href='http://www.cimgf.com/author/mzarra/' title='More posts by Marcus Zarra'>More Posts</a>  - <a href='http://www.zarrastudios.com/' title='Marcus Zarra'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2011/10/14/parent-watching-its-child/">Parent Watching Its Child</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/10/14/parent-watching-its-child/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data and the Undo Manager</title>
		<link>http://www.cimgf.com/2011/10/11/core-data-and-the-undo-manager/</link>
		<comments>http://www.cimgf.com/2011/10/11/core-data-and-the-undo-manager/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 20:27:15 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Core Data]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1530</guid>
		<description><![CDATA[<p>Note: This is a re-print from the Mac Developer Network. One of the nice things about developing software for OS X is all the “freebies” we get out of Cocoa. For example, when we are building a UI with text input we get undo support for free! How cool is that? Likewise, when we are [...]</p><p>The post <a href="http://www.cimgf.com/2011/10/11/core-data-and-the-undo-manager/">Core Data and the Undo Manager</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><em>Note: This is a re-print from the Mac Developer Network.</em></p>

<p>One of the nice things about developing software for OS X is all the “freebies” we get out of Cocoa.  For example, when we are building a UI with text input we get undo support for free!  How cool is that?</p>

<p>Likewise, when we are working with Core Data, it also has undo support built right in.  Every <code>NSManagedObjectContext</code> has a NSUndoManager that we can use.  However there are some situations where the default undo support is insufficient.</p>

<p>In this article we are going to walk through one such situation.
<span id="more-1530"></span></p>

<h2>Edit Window Undo</h2>

<p>There are situations where we want to group actions together so that from the user’s point of view they are an atomic operation.  For example, if we have a window with an edit sheet; once the edit sheet is closed we want to avoid walking through the individual edits that occurred while the sheet was present.</p>

<p>However, while the sheet is present, we do want to give the user the ability to undo each individual edit.  To perform this, we will be creating a commit group on the undo manager contained within the <code>NSManagedObjectContext</code> and we will use a separate Undo Manager that is responsible for the edit sheet.  We could use the undo manager within Core Data for both but I have found it to be cleaner to keep them separated in this situation.</p>

<h2>Building Our Application</h2>

<p><a href="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM001.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM001-300x276.png" alt="" title="CDUM001" width="300" height="276" class="alignnone size-medium wp-image-1531" /></a></p>

<p>In this application the main window will present the user with a single table view which has two columns, a date and a name.  The table itself is non-editable but double clicking on a row will present a sheet for the user to edit the row.  In addition, clicking on the add button will present the same sheet but with a new entry.  The edit sheet contains three fields for data entry as shown.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM002.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM002-300x269.png" alt="" title="CDUM002" width="300" height="269" class="alignnone size-medium wp-image-1532" /></a></p>

<p>The data model for our project contains a single NSManagedObject named TestEntity with three properties: name, date and desc.  The model is shown in.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM003.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM003.png" alt="" title="CDUM003" width="185" height="139" class="alignnone size-full wp-image-1533" /></a></p>

<h2>Implementing the App Delegate</h2>

<p>Most of the <code>AppDelegate</code> is straight out of the Core Data Application template provided by Xcode.  However we are going to add a double click action to the table view as well as handling for the add and remove buttons.  To do this we need to add the table view as an outlet with the AppDelegate.  We also need to add the <code>NSArrayController</code> as an outlet.</p>

<pre><code>@interface AppDelegate : NSObject
{
  IBOutlet NSWindow *window;
  IBOutlet NSArrayController *arrayController;
  IBOutlet NSTableView *tableView;

  NSPersistentStoreCoordinator *persistentStoreCoordinator;
  NSManagedObjectModel *managedObjectModel;
  NSManagedObjectContext *managedObjectContext;
}

- (NSManagedObjectContext *)managedObjectContext;

- (IBAction)saveAction:(id)sender;
- (IBAction)addEntity:(id)sender;
- (IBAction)removeEntity:(id)sender;

@end
</code></pre>

<p>Once we have those bound in Interface Builder we can finish the configuration within the <code>-awakeFromNib:</code> method.</p>

<pre><code>- (void)awakefromNib
{
  [tableView setTarget:self];
  [tableView setDoubleAction:@selector(editEntry:)];
}
</code></pre>

<p>In the <code>-awakeFromNib:</code> we set ourselves as the target for the tableView and add the <code>-editEntry:</code> method as its double click action.  Now when a user double-clicks on a row our method will be called.</p>

<pre><code>- (void)editEntry:(id)sender
{
  id object = [[arrayController selectedObjects] lastObject];
  if (!object) return;
  SEL endSelector = @selector(editSheetDidEnd:returnCode:object:);
  [[[self managedObjectContext] undoManager] beginUndoGrouping];
  [[[self managedObjectContext] undoManager] setActionName:@"Undo Object Edit"];
  [EditWindowController editSheetForWindow:window
                                  delegate:self
                               endSelector:endSelector
                                    entity:object];
}
</code></pre>

<p>In the <code>-editEntry:</code> method we first get the object for the row that was clicked on.  We do a quick nil check and then hand the object off to our edit window controller.  As you can see we have a convenience method in our <code>EditWindowController</code> to make it easy to create one, pass off the object and display the sheet.  The method also accepts a delegate and a callback <code>@selector</code>.</p>

<p>You should pay particular attention to the line of code in the middle; the call to the NSManagedObjectContext&#8217;s NSUndoManager.  In that line we are starting a grouping before we present the sheet.  This guarantees that any changes made while the sheet is displayed will be considered &#8220;atomic&#8221; to the <code>NSUndoManager</code> contained within the <code>NSManagedObjectContext</code>.</p>

<h2>Implementing the EditWindowController</h2>

<p>The <code>EditWindowController</code> is a subclass of <code>NSWindowController</code> with a fairly simple header.</p>

<pre><code>#import &lt;Cocoa/Cocoa.h&gt;

@interface EditWindowController : NSWindowController 
{
  NSUndoManager *undoManager;
  NSManagedObject *testEntity;
  IBOutlet NSObjectController *entityController;
}

@property (assign) NSManagedObject *testEntity;

+ (void)editSheetForWindow:(id)window 
                  delegate:(id)delegate 
               endSelector:(SEL)selector 
                    entity:(NSManagedObject*)object;

- (IBAction)saveAction:(id)sender;
- (IBAction)cancelAction:(id)sender;

@end
</code></pre>

<p>We retain a reference to the <code>NSManagedObject</code> that gets passed in, an <code>NSObjectController</code> which is initialized within Interface Builder and a <code>NSUndoManager</code> which we will discuss below.  In addition to the iVars, we also have the accessor method that we used in the <code>AppDelegate</code> and two IBActions for the buttons on the edit sheet.</p>

<p>The interface builder xib only has a couple of objects:</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM004.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2011/10/CDUM004-300x180.png" alt="" title="CDUM004" width="300" height="180" class="alignnone size-medium wp-image-1534" /></a></p>

<p>The idea behind this design is that the window controller will receive an object which we will set into the <code>NSObjectController</code>.  The panel/sheet will then feed from this <code>NSObjectController</code> to display all of the editable fields.  Once the edit is complete the user will click either save or cancel which will close the sheet and cause the callback <code>@selector</code> to fire.</p>

<pre><code>+ (void)editSheetForWindow:(id)window 
                  delegate:(id)delegate 
               endSelector:(SEL)selector 
                    entity:(NSManagedObject*)object;
{
  EditWindowController *controller;
  controller = [[EditWindowController alloc] initWithWindowNibName:kNibName];

  [controller setTestEntity:object];

  [NSApp beginSheet:[controller window] 
     modalForWindow:window 
      modalDelegate:delegate 
     didEndSelector:selector 
        contextInfo:object];
}
</code></pre>

<p>Within our helper method we take advantage of the existing underlying API.  We first initialize an instance of the <code>EditWindowController</code> using the parent&#8217;s <code>-initWithWindowNibName:</code> which will load in the nib and attach all of the bindings for us.  Once that is complete we use the <code>-setTestEntity:</code> method to pass in the NSManagedObject which will populate all of the fields.  We then use the NSApplication call <code>+beginSheet: modalForWindow: modalDelegate: didEndSelector: contextInfo:</code> to present our associated window (a <code>NSPanel</code> really) as a sheet on top of the passed in window; which in this case happens to be the main window for our application.  The beauty of using this method to present the sheet is that we do not need to retain the delegate or the callback method, the existing structure handles it for us.</p>

<pre><code>- (void)saveAction:(id)sender;
{
  [[self window] orderOut:sender];
  [NSApp endSheet:[self window] returnCode:NSOKButton];
}

- (void)cancelAction:(id)sender;
{
  [[self window] orderOut:sender];
  [NSApp endSheet:[self window] returnCode:NSCancelButton];
}
</code></pre>

<p>We can further take advantage of the underlying structure in the save and cancel methods.  In each of these methods the only thing we need to do is call <code>-orderOut:</code> on our window and then call <code>-endSheet: returnCode:</code> on the NSApplication itself.  This will in turn call the delegate&#8217;s callback method with the appropriate return code.  Keeps our sheet very simple and clean.</p>

<p>The interesting part of this sheet is the undo manager.  In Interface Builder, I assigned the <code>EditWindowController</code> as the delegate to the window.  This means that the window looks to the <code>EditWindowController</code> to get a reference to the <code>NSUndoManager</code> that it should be using.  It is possible to use the <code>NSUndoManager</code> that is part of Core Data but we want to keep the edits made in this window local.  Therefore we are going to create a separate <code>NSUndoManager</code>.</p>

<pre><code>- (NSUndoManager*)windowWillReturnUndoManager:(NSWindow*)window
{
  if (!undoManager) {
    undoManager = [[NSUndoManager alloc] init];
  }
  return undoManager;
}
</code></pre>

<p>We create this <code>NSUndoManager</code> lazily.  We wait until it is requested the first time and then initialize it.</p>

<h2>Handling the Sheet Closing</h2>

<p>When the user is done with the sheet they will either hit save or cancel.  Both of those actions will cause the delegate&#8217;s callback method to be invoked.</p>

<pre><code>- (void)editSheetDidEnd:(id)sheet returnCode:(int)returnCode object:(id)object
{
  [[[self managedObjectContext] undoManager] endUndoGrouping];
  if (returnCode == NSOKButton) return;
  [[[self managedObjectContext] undoManager] undo];
}
</code></pre>

<p>In the callback method within the AppDelegate we first end the undo grouping that we started just before presenting the sheet.  We then check to see if the user pressed save or cancel.  If they pressed save we return and are done.  If they pressed cancel, however, we then request an undo on the <code>NSManagedObjectContext</code>&#8216;s <code>NSUndoManager</code>.  This will roll the <code>NSManagedObject</code> back to the state it was before we presented the sheet to the user.  Because we named this action the user will actually see it in the Edit menu.</p>

<h2>Handling Add Item</h2>

<p>We can reuse this edit sheet for when we are dealing with a new entity as well as editing an existing entity.  The only difference is in the <code>AppDelegate</code>&#8216;s <code>-addEntity:</code> method.</p>

<pre><code>- (void)addEntity:(id)sender;
{
  NSManagedObject *newObject;
  NSManagedObjectContext *moc = [self managedObjectContext];
  SEL endSelector = @selector(editSheetDidEnd:returnCode:object:);

  [[[self managedObjectContext] undoManager] beginUndoGrouping];
  [[[self managedObjectContext] undoManager] setActionName:@"Undo Object Add"];
  newObject = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity"
                                            inManagedObjectContext:moc];
  [EditWindowController editSheetForWindow:window
                                  delegate:self
                               endSelector:endSelector
                                    entity:newObject];
}
</code></pre>

<p>Instead of grabbing the selected object from the NSArrayController we construct a new one.  However we set the undoGrouping to begin <em>before</em> we create the object.  This allows us to include the creation of the <code>NSManagedObject</code> as part of the atomic undo.  If the user hits cancel on the sheet, the <code>NSManagedObject</code> will automatically be removed from the <code>NSManagedObjectContext</code> for us.</p>

<h2>Handling the Remove Item</h2>

<p>Like the Add menu item above, we can use the <code>NSUndoManager</code> to make the removing of objects easy for us as well.</p>

<pre><code>- (void)removeEntity:(id)sender;
{
  id object = [[arrayController selectedObjects] lastObject];
  if (!object) return;

  [[[self managedObjectContext] undoManager] beginUndoGrouping];
  [[[self managedObjectContext] undoManager] setActionName:@"Undo Object Remove"];
  [[self managedObjectContext] deleteObject:object];
  [[[self managedObjectContext] undoManager] endUndoGrouping];
}
</code></pre>

<p>Here we are grabbing the selected object from the table and if it exists we remove it from the <code>NSManagedObjectContext</code>.  However, we make sure to give the action a name.  Since it is a single action there is no need for a grouping but it is helpful, and improves the user experience to name the action so that the user understands exactly what they are undoing.</p>

<h2>Wrap-Up</h2>

<p>In this short article, we walked through how the <code>NSUndoManager</code> plays very nicely with Core Data and how we can use more than one <code>NSUndoManager</code> to keep the edits separate from each other instead of rolling them all into one undo stack and thereby avoiding all of the complication that entails.</p>

<p>It is possible to combine all of this work within one <code>NSUndoManager</code> but that causes the undo stack to be larger and more complicated unnecessarily.  There is no reason to retain the edits that were made within the edit sheet in the same <code>NSUndoManager</code> that handles the changes to the context.  By pulling these into their own <code>NSUndoManager</code> we can keep each separate function of the UI separate and easier to manage.</p>

<p><a href="http://cimgf.com/files/MultipleUndoManagers.zip">Download Sample Code</a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/4451102e25dedd74169cf84deea71738?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/mzarra/' title='Marcus Zarra'>Marcus Zarra</a></h3><p></p><p><a href='http://www.cimgf.com/author/mzarra/' title='More posts by Marcus Zarra'>More Posts</a>  - <a href='http://www.zarrastudios.com/' title='Marcus Zarra'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2011/10/11/core-data-and-the-undo-manager/">Core Data and the Undo Manager</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/10/11/core-data-and-the-undo-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing and displaying large data sets in Core Data</title>
		<link>http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/</link>
		<comments>http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 19:48:18 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[NSOperation]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1525</guid>
		<description><![CDATA[<p>Note: This is a re-print from the Mac Developer Network. I tend to frequent the StackOverflow website and watch for questions about Core Data. Generally if it is a question I can answer I will and if it is a question I can&#8217;t answer then I really dig in for a fun session of exploration [...]</p><p>The post <a href="http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/">Importing and displaying large data sets in Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><em>Note: This is a re-print from the Mac Developer Network.</em></p>

<p>I tend to frequent the StackOverflow website and watch for questions about Core Data. Generally if it is a question I can answer I will and if it is a question I can&#8217;t answer then I really dig in for a fun session of exploration and attempt to find the answer.
<span id="more-1525"></span>
One question that I have been seeing with a tremendous amount of regularity is importing and displaying data on CocoaTouch devices.  Generally the question comes from one of a few problems:</p>

<ul>
<li>Trying to import a large amount of data causes the UI to hang.</li>
<li>Trying to save a large block of data causes the UI to hang.</li>
<li>Saving on exit causes the OS to kill the app.</li>
<li>Importing on launch causes the OS to kill the app.</li>
</ul>

<p>All of these &#8220;problems&#8221; are symptoms of the same two issues.</p>

<h2>Issues with large imports</h2>

<p>Importing a large amount of data, either from disk or from a network takes time and memory. If this is done on the main/UI thread then it becomes obvious to the user because the user interface is slow or unresponsive.  This leads to a poor experience for the user.</p>

<p>On the other side of this, once you get the data imported into Core Data then you need to save it.  If you are using a SQLite database then it can take a considerable amount of time.  If you are using a binary store then it will take even longer.  Again a poor user experience.</p>

<p>The answer to this problem involves multi-threading and breaking the job down into smaller pieces.</p>

<h2>Multi-threading</h2>

<p>There is a persistent rumor that you cannot use Core Data in a multi-threaded environment.  This is patently false.  Core Data works very well in a multi-threaded environment but you need to play by the rules:</p>

<ul>
<li>One <code>NSManagedObjectContext</code> per thread.</li>
<li><code>NSManagedObject</code> instances cannot pass between threads.</li>
</ul>

<p>As long as we follow those two rules, we can use Core Data in a multi-threaded environment.</p>

<h2>Breaking It Apart</h2>

<p>The biggest issue with imports is that they are generally huge.  That is going to kill performance even if it is done on a background thread.  This is especially apparent on Cocoa Touch right now because of the single core devices that it runs on.  Therefore, the first thing we <strong>must</strong> do is break that import apart.</p>

<p>I recommend splitting the incoming data (XML/JSON/whatever) into multiple files that you save on disk.  Number these files sequentially.  When the data is fully transferred from the network then start processing them.  In addition, keep track of which file you are currently working on.  When that file is complete and saved, move on to the next file and update the marker.  You can store the marker either in the <code>NSUserDefaults</code> or inside of the metadata of the <code>NSPersistentStore</code> itself.  In either case the idea is that if the user quits in the middle of the import you do not need to start over at zero.  You pick up right where you left off.</p>

<h2>Code Example</h2>

<p>In the attached sample project I have created a very trivial example of an import occurring on a background thread.  If you were actually pulling in data from the net as I described above, you would actually have numerous <code>NSOperation</code> objects that are queued up to run.  However in this example we have a single <code>NSOperation</code> that sleeps periodically.</p>

<p>The heart of this example is the periodic saves.  We want to save frequently enough that each save is very quick.  In addition, when the save occurs, we want to update the main <code>NSManagedObjectContext</code> so that it can refresh which will in turn update the <code>NSFetchedResultsController</code> which will in turn update the UI.  Crazy enough? Let&#8217;s dive in.</p>

<h3>RootViewController <code>-startImport:</code></h3>

<p>If you are familiar with Core Data on Cocoa Touch then most of this class will be very familiar.  Other than code clean up it is straight from the current Xcode template.  Having said that, there are a couple of differences.</p>

<p>The <code>-startImport:</code> method is fired from tapping the start button in the <code>NSNavigationItem</code> shown at the top of the screen.  This method will create the <code>NSOperationQueue</code> if it has not already been created and then it will create our <code>NSOperation</code> which will do the simulated work in the background.</p>

<pre><code>- (void)startImport:(id)sender
{
  [[[self navigationItem] rightBarButtonItem] setEnabled:NO];
  [[[self navigationItem] leftBarButtonItem] setEnabled:NO];

  if (![self operationQueue]) {
    operationQueue = [[NSOperationQueue alloc] init];
  }

  ZSImportOperation *op = [[ZSImportOperation alloc] init];
  [op setPersistentStoreCoordinator:[[self managedObjectContext] persistentStoreCoordinator]];
  [op setRunSpeed:0.25];
  [op setEntriesToCreate:1000];
  [op setSaveFrequency:10];

  [operationQueue addOperation:op];
  [op release], op = nil;
}
</code></pre>

<p>Note that we have several parameters that we are setting on the <code>ZSImportOperation</code> instance.  This dependency injection allows us to pass along the <code>NSPersistentStoreCoordinator</code> to the operation so that it can construct its own <code>NSManagedObjectContext</code> once it starts.  We cannot create the <code>NSManagedObjectContext</code> ourselves and pass it along because that will break the thread barrier and the results are undetermined (<em>i.e.</em> very bad).</p>

<p>We also tell it how many objects to create, how long to pause between each creation and how often to save (<em>i.e.</em> switch files).  Once everything is configured we pass it along to the <code>NSOperationQueue</code> and it starts.</p>

<h3>RootViewController <code>-contextChanged:</code></h3>

<p>This is where the magic happens as they say.  This method is called whenever any <code>NSManagedObjectContext</code> in the entire application saves.  We configured this in the <code>-viewDidLoad</code> method by calling:</p>

<pre><code>[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];
</code></pre>

<p>When this method is fired we know that the data has changed somehow, somewhere.  So we need to narrow it down and confirm it is a data change we care about.</p>

<pre><code>- (void)contextChanged:(NSNotification*)notification
{
  if ([notification object] == [self managedObjectContext]) return;

  if (![NSThread isMainThread]) {
    [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
    return;
  }

  [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}
</code></pre>

<p>Fortunately we are not in a document based application so we really just need to check that the object pointer in the notification is not pointing to our <code>NSManagedObjectContext</code>.  If it is, we bail.</p>

<p>We also need to make sure that all work done is on the main thread.  Now I could just perform the last line of code in the <code>-performSelectorOnMainThread:withObject:waitUntilDone:</code> method and in this case I probably should.  However this is another option in case the code you need to perform on the main thread is complex and you don&#8217;t want to write 12 <code>-performSelectorOnMainThread:withObject:waitUntilDone:</code> calls or write yet another method to be called.  In this example, if we are not on the main thread we recursively call ourselves from the main thread and wait.  This will guarantee that what happens next will always be on the main thread.</p>

<p>The final line is what triggers everything.  This line of code is telling the main <code>NSManagedObjectContext</code> that the underlying data has changed and that it needs to update itself.  This will in turn cause the <code>NSFetchedResultsController</code> to get woken up which finally updates the UI.</p>

<h3>ZSImportOperation <code>-main</code></h3>

<p>This <code>NSOperation</code> subclass is the most trivial example I could come up with.</p>

<pre><code>- (void)main
{
  ZAssert([self persistentStoreCoordinator], @"PSC is nil");
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSRunLoopCommonModes];

  NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
  [moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]];

  NSError *error = nil;

  for (NSInteger index = 0; index &lt; [self entriesToCreate]; ++index) {
    id object = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:moc];
    [object setValue:[NSString stringWithFormat:@"User %i", index] forKey:@"name"];
    [object setValue:[NSNumber numberWithInteger:(arc4random() % 99)] forKey:@"age"];

    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:[self runSpeed]]];

    if (index % [self saveFrequency] != 0) continue;

    ZAssert([moc save:&amp;error], @"Error saving context on operation: %@\n%@", [error localizedDescription], [error userInfo]);

    DLog(@"saving background context");
    [moc reset];
    [pool release];
    pool = [[NSAutoreleasePool alloc] init];
  }

  ZAssert([moc save:&amp;error], @"Error saving context on operation: %@\n%@", [error localizedDescription], [error userInfo]);

  [moc release], moc = nil;

  [[NSNotificationCenter defaultCenter] postNotificationName:kImportRoutineComplete object:self];

  [pool release], pool = nil;
}
</code></pre>

<p>It starts with creating a separate <code>NSManagedObjectContext</code> as per the rules.  We then add an empty port so that we can lazily sleep this thread.  From there we start looping based on the set <code>entriesToCreate</code> value.</p>

<p>Inside of the loop we create a new <code>NSManagedObject</code> and give it some random values.  We then sleep based on the <code>runSpeed</code> value.  From there we check to see if it is time to save and if not we move on to the next iteration of the loop.</p>

<p>If it is time to save we then perform a <code>-save:</code> on the <code>NSManagedObjectContext</code> instance wrapped inside of a <code>ZAssert</code>.  The <code>ZAssert</code> allows us to do a conditional check on the results and then spit out either a <code>NSAssert</code> or <code>NSLog</code> depending on whether we are compiling in debug (which would throw an assertion) or production (which will spit out an NSLog).</p>

<p>Once the save is complete we reset the <code>NSManagedObjectContext</code> instance to release the memory it is holding onto and then drain the <code>NSAutoreleasePool</code>.</p>

<p>Once all of the requested objects have been created we perform one final save of the <code>NSManagedObjectContext</code> and drain the <code>NSAutoreleasePool</code> one final time.  We also send out a <code>NSNotification</code> just so that we can update the UI and re-enable the buttons.</p>

<h2>Wrap Up</h2>

<p>If you run the sample application you will notice a few things:</p>

<ul>
<li>The app runs smoothly even while processing data.</li>
<li>The app does not crash on launch due to the OS killing it.</li>
<li>THe app does not crash on exit because the save takes too long.</li>
</ul>

<p>Naturally this is more work for us as the developers but the end result is an application that can handle any amount of data without fear of freezing the UI or having the OS kill our application.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2011/08/PerformantImport.zip'>You can download the sample project here.</a></p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/4451102e25dedd74169cf84deea71738?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/mzarra/' title='Marcus Zarra'>Marcus Zarra</a></h3><p></p><p><a href='http://www.cimgf.com/author/mzarra/' title='More posts by Marcus Zarra'>More Posts</a>  - <a href='http://www.zarrastudios.com/' title='Marcus Zarra'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/">Importing and displaying large data sets in Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Conference: MacTech (Los Angeles, CA, USA)</title>
		<link>http://www.cimgf.com/2011/08/12/conference-mactech-los-angeles-ca-usa/</link>
		<comments>http://www.cimgf.com/2011/08/12/conference-mactech-los-angeles-ca-usa/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 17:26:32 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1516</guid>
		<description><![CDATA[<p>When: November 2-4, 2011 Where: Los Angeles, CA Schedule and Additional Information The speaker line up for MacTech this year is amazing. I am quite honored to be sharing the stage with such a group of people. What is MacTech Conference? MacTech Conference is a 3-day, immersive, technical conference specifically designed for Apple developers, IT [...]</p><p>The post <a href="http://www.cimgf.com/2011/08/12/conference-mactech-los-angeles-ca-usa/">Conference: MacTech (Los Angeles, CA, USA)</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>When: November 2-4, 2011<br />
Where: Los Angeles, CA</p>

<p><a href="http://www.mactech.com/conference/about">Schedule and Additional Information</a></p>

<p>The speaker line up for MacTech this year is amazing. I am quite honored to be sharing the stage with such a group of people.</p>

<h2>What is MacTech Conference?</h2>

<p>MacTech Conference is a 3-day, immersive, technical conference specifically designed for Apple developers, IT Pros, and Enterprise. &#8220;The whole idea of MacTech Conference is to allow members of the Apple community to meet and exchange ideas,&#8221; said Edward Marczak, Conference Chair and Executive Editor of MacTech Magazine. &#8220;This will be spurred on by presentations from some of the best and well-known experts in the community.&#8221;</p>

<p>MacTech Conference will have two separate tracks: one focused on programming / development, and the other on IT/Enterprise. Sessions will focus on both desktop and mobile, with appropriate levels of attention paid to the Mac, iPhone, iPad and iPod.</p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/4451102e25dedd74169cf84deea71738?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/mzarra/' title='Marcus Zarra'>Marcus Zarra</a></h3><p></p><p><a href='http://www.cimgf.com/author/mzarra/' title='More posts by Marcus Zarra'>More Posts</a>  - <a href='http://www.zarrastudios.com/' title='Marcus Zarra'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2011/08/12/conference-mactech-los-angeles-ca-usa/">Conference: MacTech (Los Angeles, CA, USA)</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/08/12/conference-mactech-los-angeles-ca-usa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transient Entities and Core Data</title>
		<link>http://www.cimgf.com/2011/08/08/transient-entities-and-core-data/</link>
		<comments>http://www.cimgf.com/2011/08/08/transient-entities-and-core-data/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 23:24:04 +0000</pubDate>
		<dc:creator>Saul Mora</dc:creator>
				<category><![CDATA[Core Data]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1493</guid>
		<description><![CDATA[<p>Core Data has many features, one of which is the Transient attribute. This type of attribute on a Core Data entity is part of a data model, but is not persisted in your Core Data persistent store. If you open up the raw SQLite store file and peek at the schema, you will not find [...]</p><p>The post <a href="http://www.cimgf.com/2011/08/08/transient-entities-and-core-data/">Transient Entities and Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Core Data has many features, one of which is the Transient attribute. This type of attribute on a Core Data entity is part of a data model, but is not persisted in your Core Data persistent store. If you open up the raw SQLite store file and peek at the schema, you will not find any transient attributes. These transient attributes are still handy despite no data being persisted to the data store. One useful scenario is when a value is calculated based on other attributes. This calculation can be performed in an entity&#8217;s awakeFromFetch method, and stored at run time in this transient attribute.</p>

<p>One scenario I&#8217;ve been asked about on more than one occasion recently is that of temporary, or transient entities. It seems that more and more developers have a need for temporary, or transient instances of entities in your Mac or iOS apps. Having temporary object instances can be useful and necessary in certain situations. Unfortunately, Transient Entities do not technically exist within the Core Data framework, however there are simple solutions to add temporary, un-persisted, data within the context of Core Data. Let&#8217;s go over some methods to effectively use the concept of Transient, or more appropriately Temporary Entities in Core Data without direct built-in support.</p>

<p><span id="more-1493"></span></p>

<h2>Why even put them in Core Data in the first place?</h2>

<p>This should be the first qustion you ask when you&#8217;re talking about going down the path of doing something with Core Data that it doesn&#8217;t already do for you. So, why not just use Plain Old Objective-C Objects &#8230; POOCOs anyone? There are a couple scenarios in which you would want even your temporary objects to be NSManagedObjects. The main situation is where you actually do persist the instance to the persistent store. Another case may be that your data objects are easily defined, modeled and imported through the Core Data toolset. That is, you have an entity defined and related to other entities in your object graph in your Model, and the import code is shared or related. In this case, it may be more maintainable to just let that all coexist. The most common reason is that you want to have a temporary object with the option to cancel and destroy it at any time. This is common in a &#8220;New Document&#8221; situtation where the user wants to enter new data, but decides to cancel half way in, and discard what&#8217;s already been entered.</p>

<p>Whatever the reason, it should be through a rigorous process that you have ultimately decided that your objects are better off as NSManagedObject instances and not just plain old Objective C objects with references to NSManagedObjects. In most cases you will be better off not even dealing with the complexity of temporary NSManagedObjects in the first place.</p>

<p>That being said, since you&#8217;ve come this far, it seems likely that maybe you really do have a good reason to have a temporary object instance as a Core Data object. Great, let&#8217;s go over three common, and easy to implement, solutions with code to show how to handle this as simply as possible. Also, we&#8217;ll go over the pros and cons of each approach as there are certainly tradeoffs which you must evaluate in order to choose the correct solution for your problem.</p>

<p>The code samples shown here will be using the helpers found in <a href="http://github.com/magicalpanda/MagicalRecord">Magical Record</a>, available on github.</p>

<h2>Scratch Managed Object Context</h2>

<p>Perhaps the simplest scenario in creating temporary NSManagedObjects is to create them in a temporary NSManagedObjectContext. Apple&#8217;s documentation commonly refers to the NSManagedObjectContext as a &#8216;scratch pad&#8217; or &#8216;working area&#8217; for changes to NSManagedObjects. When you create any NSManagedObject in a Managed Object Context, it is not perisisted to the store util you call <strong>save: </strong>on that context. By not calling <strong>save:</strong> on a second scratch context, any changes made will dissappear when the context, and the managed objects it contains, is dealloc&#8217;ed. Let&#8217;s take a look at implementing this example in code:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> MyViewController <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span>scratchContext;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> MyViewController
@synthensize scratchContext <span style="color: #002200;">=</span> scratchContext_;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad
<span style="color: #002200;">&#123;</span>
  self.scratchContext <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectContext</span> context<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
...
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>importData
<span style="color: #002200;">&#123;</span>
  MyEntity <span style="color: #002200;">*</span>instance <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>MyEntity createInContext<span style="color: #002200;">:</span>self.scratchContext<span style="color: #002200;">&#93;</span>;
  <span style="color: #11740a; font-style: italic;">// data initialization code</span>
  <span style="color: #11740a; font-style: italic;">// don't call save:</span>
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectContext</span> defaultContext<span style="color: #002200;">&#93;</span> save<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// won't save anything in the scratch context</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>In this first example, we have two NSManagedObjectContext objects, the first is created for you when you use one of <a href="http://github.com/magicalpanda/MagicalRecord">MagicalRecord&#8217;s</a> setup methods. As described <a href="http://www.cimgf.com/2011/03/13/super-happy-easy-fetching-in-core-data/">in a previous post</a>, this first context is set as the default context for all Core Data operations. However, in this scenario, we want to create a second context that uses the same persistent store. Using MagicalRecord, this is as simple as using the <strong>context</strong> method. This will create a new NSManagedObjectContext instance, and initialize it with the default NSPersistentStoreCoordinator. This is all that&#8217;s necessary to create a usable scratch context. Now, instead of creating entities in the default context, perform them in this scratch context. This is what&#8217;s happening in the importData method. By creating a new entity in the scratch context, we&#8217;re making a temporary object that potentially can be thrown away when we&#8217;re done with the view controller.</p>

<h2>In Memory SQLite Persistent Store</h2>

<p>One of the useful features of SQLite is that it can also persist simply in memory, or system RAM, only. This feature translates to Core Data persistent stores quite nicely as it&#8217;s a simple configutation change to the <strong>addPersistentStore: </strong>call when setting up your NSPersistentStoreCoordinator instance.  To simplify things, while adding this option, we&#8217;re going to go over adding an in-memory SQLite store to the same default NSPersistentStoreCoordinator.  This route may not be the common route in iOS apps, but Core Data is set up to handle the mapping and complexity of multiple stores for you, so it makes sense to use that functionality for this solution to try to keep the code as simple as possible.  Let&#8217;s take a look at some code:</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> SampleAppDelegate <span style="color: #002200;">&amp;</span>lt;UIApplicationDelegate<span style="color: #002200;">&amp;</span>gt;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain, readonly<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSPersistentStore</span> <span style="color: #002200;">*</span>inMemoryStore;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain, readonly<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSPersistentStore</span> <span style="color: #002200;">*</span>fileBasedStore;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> SampleAppDelegate
<span style="color: #a61390;">@synthesize</span> inMemoryStore <span style="color: #002200;">=</span> inMemoryStore_;
<span style="color: #a61390;">@synthesize</span> fileBasedStore <span style="color: #002200;">=</span> fileBasedStore_;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>awakeFromNib
<span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>MagicalRecordHelpers setupDefaultCoreDataStack<span style="color: #002200;">&#93;</span>;
    self.fileBasedStore <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>NSPersistenStoreCoordinator defaultCoordinator<span style="color: #002200;">&#93;</span> persistentStores<span style="color: #002200;">&#93;</span> objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
    self.inMemoryStore <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPersistentStoreCoordinator</span> defaultCoordinator<span style="color: #002200;">&#93;</span> addInMemoryStore<span style="color: #002200;">&#93;</span>;  <span style="color: #11740a; font-style: italic;">//configure in memory store&lt;br /&gt;</span>
<span style="color: #002200;">&#125;</span>
...
<span style="color: #a61390;">@implementation</span> MyViewController
<span style="color: #11740a; font-style: italic;">//assign new object to in memory persistent store</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>MyEntity<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>createTemporaryEntity
<span style="color: #002200;">&#123;</span>
    MyEntity <span style="color: #002200;">*</span>newInstance <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>MyEntity createEntity<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span>context <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectContext</span> defaultContext<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSPersistentStore</span> <span style="color: #002200;">*</span>inMemoryStore <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span>SampleAppDelegate <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> delegate<span style="color: #002200;">&#93;</span> inMemoryStore<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>context assignObject<span style="color: #002200;">:</span>newInstance toPersistentStore<span style="color: #002200;">:</span>inMemoryStore<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> newInstance;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>


<p>We&#8217;ve again use the <a href="http://github.com/magicalpanda/MagicalRecord">MagicalRecord</a> helpers in this second example to create an in-memory SQLite store on the default NSPersistentStoreCoordinator. Notice that we also must keep a reference to it in our app delegate. The reason for this reference is easy to understand once we get to creating temporary object instances in the createTemporaryEntity method on MyViewController. Creating an entity is as straight forward as always, however, we must then assign this new entity to the in-memory store using our saved reference. We must also assign our non-temporary objects to the <em>fileBasedStore</em> as well.</p>

<p>There is one rather large caveat to this solution&#8211;on iOS devices in particular. There is a finite limit to what you can store in memory during the lifetime of an app. Going over this limit can be grounds for termination by the system watchdog process. If you implement this solution and find that you are constantly hitting a memory limit in your app due to the temporary in memory store, a simple variant to this solution is to make this a regular disk based SQLite store, but make it a secondary store, one that can easily be deleted by some clean up code later on. By persisting the store to disk, you don&#8217;t have the same constant memory pressure, and you also still have a secondary store which only contains temporary instances of your objects.</p>

<h2>Mark Entities for deletion, and delete later</h2>

<p>In our third scenario, the Core Data stack remains the same as in our original simple Core Data stack setup. However, this situation is helpful when objects are being used by the UI. In some cases, references to managed objects in the UI may have a reason to delay the release of these objects. In order to avoid crashes due to deleting the persistence information out from under the object, we can simply say that entity should be deleted later. <a href="http://github.com/magicalpanda/MagicalRecord">MagicalRecord</a> provides a truncateAll (and the truncateAllInContext: variant) to remove all the instances of a particular type from the store. However, in this case, we need to have a more specific filter on a flag on the entity.</p>


<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>MRCoreDataAction saveDataWithBlock<span style="color: #002200;">:^</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span>localContext<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSPredicate</span> <span style="color: #002200;">*</span>itemsToDeleteSearch <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;shouldBeDeleted = YES&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>itemsToDelete <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>SampleEntity findAllWithPredicate<span style="color: #002200;">:</span>itemsToDeleteSearch<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObject</span> <span style="color: #002200;">*</span>entity <span style="color: #a61390;">in</span> itemsToDelete<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>entity deleteInContext<span style="color: #002200;">:</span>localContext<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>In the case where the shouldBeDeleted flag is a transient attribute, using an NSPredicate search against the store will not work as this attribute is not even created in the SQLite schema for that entity. A variant on this solution is to hang on to those deleted references in an NSMutableArray (or NSMutableSet) and iterate on that collection at the appropriate time. However, this variant may backfire in the event of a crash or a forced termination. That is, in either of those scenarios, your collection of instances to delete will no longer be in memory.</p>

<p>On iOS 4 and above, applications can enter the &#8220;background&#8221;. This is a perfect time to perform this delayed purge as it can be done without the user really noticing any UI jerkiness caused by merges. Heck, if you make other apps slow down, the user may just blame that one! (Don&#8217;t do this…be a good app citizen).</p>

<h2>Conclusion</h2>

<p>I&#8217;ve just described three ways to deal with temporary Core Data objects. These are by no means the only ways to handle transient entities, however, these are relatively simple concepts. The code for each of these examples is also simple enough to retrofit into existing application code. If you have other solutions relating to the idea of temporary storage, I&#8217;d be happy to hear about them in the comments below!</p>

<p> </p>
<p><div style="float:left; text-align:left;><img alt='' src='http://0.gravatar.com/avatar/e510cac938662af7c0919aeca341b139?s=100&amp;d=&amp;r=G' class='avatar avatar-100 photo' height='100' width='100' /></div><h3><a href='http://www.cimgf.com/author/magicalpanda/' title='Saul Mora'>Saul Mora</a></h3><p></p><p><a href='http://www.cimgf.com/author/magicalpanda/' title='More posts by Saul Mora'>More Posts</a>  - <a href='http://www.magicalpanda.com' title='Saul Mora'>Website</a> </p></p><p>The post <a href="http://www.cimgf.com/2011/08/08/transient-entities-and-core-data/">Transient Entities and Core Data</a> appeared first on <a href="http://www.cimgf.com">Cocoa Is My Girlfriend</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2011/08/08/transient-entities-and-core-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
