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

<channel>
	<title>Nial Giacomelli</title>
	<atom:link href="http://nial.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://nial.me</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 21:14:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Calculating screen coordinates from NSView-relative coordinates in Cocoa</title>
		<link>http://nial.me/2012/01/calculating-screen-coordinates-from-view-relative-coordinates-in-cocoa/</link>
		<comments>http://nial.me/2012/01/calculating-screen-coordinates-from-view-relative-coordinates-in-cocoa/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 20:49:16 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://nial.me/?p=398</guid>
		<description><![CDATA[For a recent release of SpriteRight I set out to integrate snap-to-grid functionality. Unfortunately this required that I calculate screen coordinates from a set of view-relative coordinates. I&#8217;ve decided to make the code I ended up with public in the hope that it avoids someone a little head scratching down the road. It should be [...]]]></description>
			<content:encoded><![CDATA[<p>For a recent release of <a href="http://spriterightapp.com" title="SpriteRight">SpriteRight</a> I set out to integrate snap-to-grid functionality. Unfortunately this required that I calculate screen coordinates from a set of view-relative coordinates. </p>
<p>I&#8217;ve decided to make the code I ended up with public in the hope that it avoids someone a little head scratching down the road. It should be noted that the following code makes use of Oscar Del Ben&#8217;s fantastic <a href="https://github.com/oscardelben/NSScreen-PointConversion" title="NSScreen+PointConversion">NSScreen+PointConversion category</a> to help with determining the active NSScreen and flipping said screens coordinates.</p>
<p>The following code should handle flipped coordinate systems and multi-monitor displays gracefully. Also included is a function to warp the mouse (without simulating any events) to a specified point in screen coordinates.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="objc"><pre class="de1"><span class="sy0">-</span> <span class="br0">&#40;</span><span class="kw4">NSPoint</span><span class="br0">&#41;</span>convertToScreenFromLocalPoint<span class="sy0">:</span><span class="br0">&#40;</span><span class="kw4">NSPoint</span><span class="br0">&#41;</span>point relativeToView<span class="sy0">:</span><span class="br0">&#40;</span><span class="kw7">NSView</span> <span class="sy0">*</span><span class="br0">&#41;</span>view
<span class="br0">&#123;</span>
	<span class="kw7">NSScreen</span> <span class="sy0">*</span>currentScreen <span class="sy0">=</span> <span class="br0">&#91;</span><span class="kw7">NSScreen</span> currentScreenForMouseLocation<span class="br0">&#93;</span>;
	<span class="kw1">if</span><span class="br0">&#40;</span>currentScreen<span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw4">NSPoint</span> windowPoint <span class="sy0">=</span> <span class="br0">&#91;</span>view convertPoint<span class="sy0">:</span>point toView<span class="sy0">:</span><span class="kw2">nil</span><span class="br0">&#93;</span>;
		<span class="kw4">NSPoint</span> screenPoint <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span>view window<span class="br0">&#93;</span> convertBaseToScreen<span class="sy0">:</span>windowPoint<span class="br0">&#93;</span>;
		<span class="kw4">NSPoint</span> flippedScreenPoint <span class="sy0">=</span> <span class="br0">&#91;</span>currentScreen flipPoint<span class="sy0">:</span>screenPoint<span class="br0">&#93;</span>;
		flippedScreenPoint.y <span class="sy0">+=</span> <span class="br0">&#91;</span>currentScreen frame<span class="br0">&#93;</span>.origin.y;
&nbsp;
		<span class="kw1">return</span> flippedScreenPoint;
	<span class="br0">&#125;</span>
&nbsp;
	<span class="kw1">return</span> NSZeroPoint;
<span class="br0">&#125;</span>
&nbsp;
<span class="sy0">-</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span>moveMouseToScreenPoint<span class="sy0">:</span><span class="br0">&#40;</span><span class="kw4">NSPoint</span><span class="br0">&#41;</span>point
<span class="br0">&#123;</span>
	CGPoint cgPoint <span class="sy0">=</span> NSPointToCGPoint<span class="br0">&#40;</span>point<span class="br0">&#41;</span>;
&nbsp;
	CGSetLocalEventsSuppressionInterval<span class="br0">&#40;</span><span class="nu0">0.0</span><span class="br0">&#41;</span>;
	CGWarpMouseCursorPosition<span class="br0">&#40;</span>cgPoint<span class="br0">&#41;</span>;
	CGSetLocalEventsSuppressionInterval<span class="br0">&#40;</span><span class="nu0">0.25</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


]]></content:encoded>
			<wfw:commentRss>http://nial.me/2012/01/calculating-screen-coordinates-from-view-relative-coordinates-in-cocoa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>App Store rank tracking that (hopefully) doesn&#8217;t suck</title>
		<link>http://nial.me/2012/01/app-store-rank-tracking-that-doesnt-suck/</link>
		<comments>http://nial.me/2012/01/app-store-rank-tracking-that-doesnt-suck/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 21:01:23 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=392</guid>
		<description><![CDATA[I&#8217;ve recently become fairly obsessed with watching the ebb and flow of App Store rankings. This started recently, following the release of SpriteRight, but has since extended to encompass a number of unrelated applications. Unfortunately I wasn&#8217;t able to find a simple, uncluttered web interface for viewing historic App Store ranking data. Which is why [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently become fairly obsessed with watching the ebb and flow of App Store rankings. This started recently, following the release of <a href="http://spriterightapp.com" title="SpriteRight">SpriteRight</a>, but has since extended to encompass a number of unrelated applications.</p>
<p>Unfortunately I wasn&#8217;t able to find a simple, uncluttered web interface for viewing historic App Store ranking data. Which is why I spent this weekend knocking up <a href="http://appstorerank.net" title="AppStoreRank.net">AppStoreRank.net</a>. It&#8217;s a fairly simple site with a fairly simple objective: display data and don&#8217;t piss people off in the process.</p>
<p>I use it to track my <a href="http://appstorerank.net/info/492081694" target="Houdini">own</a> <a href="http://appstorerank.net/info/488584662" title="SpriteRight">applications</a> and to also get an appreciation for just how turbulent ranking can be towards the lower end of the top 100 scale. Hopefully some of you find it interesting too.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2012/01/app-store-rank-tracking-that-doesnt-suck/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Houdini to appear in the Mac App Store</title>
		<link>http://nial.me/2011/12/houdini-to-appear-in-the-mac-app-store/</link>
		<comments>http://nial.me/2011/12/houdini-to-appear-in-the-mac-app-store/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 14:57:14 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=380</guid>
		<description><![CDATA[Houdini will soon appear in the Mac App Store. Relax! It&#8217;s still free. This is just a note to say that I will be retiring the currently active Sparkle appcast. Which means that all future updates will be exclusive to the App Store. Edit: Houdini is now available to download.]]></description>
			<content:encoded><![CDATA[<p><a href="http://nial.me/wp-content/uploads/2011/12/256.png"><img src="http://nial.me/wp-content/uploads/2011/12/256.png" alt="" title="Houdini" width="256" height="256" class="aligncenter size-full wp-image-386" /></a></p>
<p><a href="http://uglyapps.co.uk/houdini" title="Houdini">Houdini</a> will soon appear in the Mac App Store. Relax! It&#8217;s still free. This is just a note to say that I will be retiring the currently active Sparkle appcast. Which means that all future updates will be exclusive to the App Store.</p>
<p><strong>Edit:</strong> Houdini is now <a href="http://itunes.apple.com/us/app/houdini/id492081694?ls=1&#038;mt=12" title="Download">available to download</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/12/houdini-to-appear-in-the-mac-app-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SpriteRight</title>
		<link>http://nial.me/2011/12/spriteright/</link>
		<comments>http://nial.me/2011/12/spriteright/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 16:42:33 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=369</guid>
		<description><![CDATA[SpriteRight is a spritesheet generator for the Mac that lets you import your existing images or stylesheets. Make your sites load faster, cut bandwidth costs and save time. SpriteRight even generates CSS code on the fly. And best of all, it&#8217;s available now on the Mac App Store.]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/us/app/spriteright/id488584662?ls=1&amp;mt=12"><img src="http://nial.me/wp-content/uploads/2011/12/icon-0.png" alt="Available now!" title="SpriteRight" width="400" height="300" class="aligncenter size-full wp-image-370" /></a></p>
<p><a href="http://spriterightapp.com" title="SpriteRight">SpriteRight</a> is a spritesheet generator for the Mac that lets you import your existing images or stylesheets. Make your sites load faster, cut bandwidth costs and save time. SpriteRight even generates CSS code on the fly. And best of all, it&#8217;s available now on the <a href="http://itunes.apple.com/us/app/spriteright/id488584662?ls=1&#038;mt=12" title="SpriteRight">Mac App Store</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/12/spriteright/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Net neutrality</title>
		<link>http://nial.me/2011/10/net-neutrality/</link>
		<comments>http://nial.me/2011/10/net-neutrality/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 17:29:15 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=366</guid>
		<description><![CDATA[I&#8217;m fairly appalled by todays Orwellian announcement regarding Cameron&#8217;s push to negotiate pornographic filtering as an opt-out service across the UK&#8217;s internet service providers. This is, of course, a fully political move. It has very little to do with pornography and a whole lot to do with a government that is slowly but surely moving [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m fairly appalled by todays Orwellian announcement regarding <a href="http://www.guardian.co.uk/society/2011/oct/11/pornography-internet-service-providers">Cameron&#8217;s push</a> to negotiate pornographic filtering as an opt-out service across the UK&#8217;s internet service providers. This is, of course, a fully political move. It has very little to do with pornography and a whole lot to do with a government that is slowly but surely moving to violate net neutrality. They&#8217;ve chosen a contraband which, by its very nature, people are unlikely to protest. And they&#8217;ve done so under the guise of a moral obligation to young citizens.</p>
<p>The entire situation brings <a href="http://blog.ted.com/2011/05/02/beware-online-filter-bubbles-eli-pariser-on-ted-com/">Eli Pariser&#8217;s</a> talk on filter bubbles back into focus. It&#8217;s a wonderful presentation that really helps to personalise the net neutrality issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/10/net-neutrality/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gibs!</title>
		<link>http://nial.me/2011/09/gibs/</link>
		<comments>http://nial.me/2011/09/gibs/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 17:31:13 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=330</guid>
		<description><![CDATA[A good friend of mine recently tweeted that graphic artists often think that the only thing that needs to go into a game is good art. As someone who writes code for a living, it&#8217;s always interesting to see the disconnect between aesthetic and application. What people see versus what people fail to consider. I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>A good friend of mine recently <a href="https://twitter.com/#!/____________g/status/116171095647862784">tweeted</a> that graphic artists often think that the only thing that needs to go into a game is good art. As someone who writes code for a living, it&#8217;s always interesting to see the disconnect between aesthetic and application. What people <em>see</em> versus what people fail to <em>consider</em>.</p>
<p>I&#8217;m in the process of writing a hobby game for the iPad that&#8217;s fairly far along in terms of development, but still an infant where aesthetics are concerned. It&#8217;s full of programmer art and debugging messages and generally things people don&#8217;t attribute to a polished product. So today I thought it would be interesting to document just how much work goes into a seemingly simple detail: handling player death and giving visual feedback.</p>
<p>In video games when players meet a grisly end their bodies are often <em>gibbed</em>. A gib, in this case, can be thought of as a chunk of meat or an appendage. In other words: generally stuff you want to keep about your person. Duke Nukem 3D was famous for its elaborate gib sprites (including everything from eyeballs to ribcages and, of course, the ultra-rare testicles).</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/dukegibs.jpg" alt="" title="Gibs, baby!" width="600" height="376" class="aligncenter size-full wp-image-335" /></p>
<p>Fortunately, the game I&#8217;m putting together isn&#8217;t 3D (or even faux-3D). In fact, it borrows more from the older generation of side-scrollers and platformers. So when it came to adding gibs to our game, I looked to more recent examples, such as the gore-heavy Super Meat Boy. </p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/1269147478.jpg" alt="" title="Super Meat Boy" width="600" height="338" class="aligncenter size-full wp-image-338" /></p>
<p>Jetpack Janitor (as I&#8217;ve affectionately nicknamed it) sees players navigating a variety of levels as a jetpack-clad janitor. You&#8217;ll move through various levels in a bid to return power to the ship you watch over, avoiding obstacles and hazards as well as solving various physics-based puzzles. Here&#8217;s a rough snapshot of a test level featuring a few keys, a closed airlock, and a wall of buzzsaws. You&#8217;ll have to excuse the programmer art.</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss1.jpg" alt="" title="Introducing the Janitor" width="600" height="450" class="aligncenter size-full wp-image-340" /></p>
<p>When Stan (that&#8217;s our janitor) hits a buzzsaw, he is killed immediately. What we want to do today is not only kill Stan, but also have his body cut into ten or so meaty chunks and distributed about the level.</p>
<p>The Jetpack Janitor engine has been built from the ground up to integrate with the box2d physics engine. This means that every entity (object on screen) is represented by a physics-enabled object. The graphics you&#8217;re seeing, from the tilemap that makes up the level, to the player sprite and particle effects, are simple graphical representations that are updated by the physics simulation at regular intervals.</p>
<p>To get the ball rolling, I went ahead and created a <code>Gib</code> class. Because we wanted our gibs to roll around the ground after landing on a surface, I modelled each <code>Gib</code> instance as a circular dynamic body. By turning on debug rendering, you can see that now, when Stan explodes, his body is replaced by three <code>Gib</code> instances (shown here above the buzzsaws):</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss2.jpg" alt="" title="Physics bodies" width="600" height="450" class="aligncenter size-full wp-image-341" /></p>
<p>Unfortunately, while the <code>Gib</code> instances behaved as expected, something felt a little off. I spent a while tweaking their restitution and friction before reaching a point where things felt &#8216;right&#8217;. Finally, I increased the number of <code>Gib</code> instances spawned on death and made the radius of each <code>Gib</code> randomly decided upon instantiation.</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss3.jpg" alt="" title="Oh, balls!" width="600" height="450" class="aligncenter size-full wp-image-345" /></p>
<p>With the <code>Gib</code> instances behaving nicely within the physics simulator it was time to up the gore level slightly by allowing each instance to create a finite number of decals. A decal is created each time a <code>Gib</code> collides with a static physical body (such as a wall). In this case, each decal represents a bloody stain that gets painted onto the level geometry.</p>
<p>The plan here was to use a single decal sprite which would then be rotated programatically to fit against the surface it had collided with. As you can see from my initial tests, the method I had hoped to use as a means of calculating decal rotation didn&#8217;t quite make the grade. You&#8217;ll notice some blood smears towards bottom of the screen are incorrectly rotated.</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss4.jpg" alt="" title="Stains" width="600" height="450" class="aligncenter size-full wp-image-348" /></p>
<p>There are, of course, far more bullet-proof means of calculating the angle and position of such decals. But for our purposes, a simple check against the point of collision versus the relative position of our body seemed to suffice.</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss5.jpg" alt="" title="Blood bath" width="600" height="450" class="aligncenter size-full wp-image-353" /></p>
<p>With decals working nicely, it was time to work on the actual <code>Gib</code> rendering code. This was a fairly simple case of scaling the meatwad graphic based on the randomly chosen <code>Gib</code> radius. Below I&#8217;ve included three screenshots of Stan meeting an untimely end:</p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss8.jpg" alt="" title="Look out!" width="600" height="450" class="aligncenter size-full wp-image-359" /></p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss9.jpg" alt="" title="Ouch!" width="600" height="450" class="aligncenter size-full wp-image-360" /></p>
<p><img src="http://nial.me/wp-content/uploads/2011/09/ss10.jpg" alt="" title="Splat!" width="600" height="450" class="aligncenter size-full wp-image-361" /></p>
<p>So what&#8217;s next? Before this code can be considered final, it&#8217;s now time to hand it over to <a href="http://iamglynnsmith.com">Glynn</a> for an art and sound pass. As a result, the code I&#8217;ve written is likely to change to encompass the following requirements:</p>
<ul>
<li>A random variety of splatter decals and gib sprites</li>
<li>Particle effects during the players initial &#8216;explosion&#8217;</li>
<li>Particle emitters tied to each <code>Gib</code> instance</li>
<li>And finally, the ability for <code>Gib</code> instances to generate squishy sound effects upon collision with other entities</li>
</ul>
<p>Hopefully this post has given an interesting insight into the amount of work that goes into even a simple game element.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/09/gibs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Now you see me&#8230;</title>
		<link>http://nial.me/2011/08/now-you-see-me/</link>
		<comments>http://nial.me/2011/08/now-you-see-me/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 19:41:18 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://nial.me/?p=319</guid>
		<description><![CDATA[About a week ago I released a small Mac menubar application that&#8217;s designed to help you stay focused and keep your desktop clutter free. It&#8217;s called Houdini and it works by hiding applications which have been inactive for a certain amount of time. It was heavily inspired by Drikin&#8217;s Spirited Away but has some fundamental [...]]]></description>
			<content:encoded><![CDATA[<p>About a week ago I released a small <a href="http://uglyapps.co.uk/houdini" title="Houdini">Mac menubar application</a> that&#8217;s designed to help you stay focused and keep your desktop clutter free. It&#8217;s called Houdini and it works by hiding applications which have been inactive for a certain amount of time. It was heavily inspired by Drikin&#8217;s <a href="http://drikin.com/" title="Spirited Away">Spirited Away</a> but has some fundamental differences. For one, Spirited Away works for a fixed timeout for all applications, whereas Houdini will work on a per-application basis.</p>
<p>It was the first Mac application that I&#8217;ve realised in a personal capacity and it&#8217;s been very rewarding to hear that people are finding it useful. It&#8217;s been mentioned and reviewed in a <a href="http://www.macupdate.com/app/mac/39692/houdini">couple</a> of <a href="http://translate.google.com/translate?js=n&#038;prev=_t&#038;hl=en&#038;ie=UTF-8&#038;layout=2&#038;eotf=1&#038;sl=auto&#038;tl=en&#038;u=http%3A%2F%2Fwww.winmacsofts.com%2F2011%2F08%2Fhoudini-cachez-les-applications-inactives-comme-par-magie-sous-mac%2F">different </a> <a href="http://mosx.tumblr.com/post/8567254878/houdini-to-replace-spirited-away">places</a> and seems to be doing pretty well for itself.</p>
<blockquote><p>Really useful app! This is already improving my concentration and workflow. Very, very useful and well-done app. I&#8217;d pay for this on the MAS.</p></blockquote>
<blockquote><p>The app looks good and has a couple of nice settings. Despite the author claiming the app is ugly, it’s quite useful.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/08/now-you-see-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimizing CoreData full-text queries</title>
		<link>http://nial.me/2011/07/optimizing-coredata-full-text-queries/</link>
		<comments>http://nial.me/2011/07/optimizing-coredata-full-text-queries/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 22:25:43 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://nial.me/?p=307</guid>
		<description><![CDATA[Given that the CoreData documentation describes a 10,000 object collection as a fairly small data set, I was surprised to find a simple NSFetchRequest being responsible for massive resource spikes in a recent Mac application I&#8217;ve been working on. The NSFetchRequest in question uses an NSPredicate to fetch Files entities with a given path. As [...]]]></description>
			<content:encoded><![CDATA[<p>Given that the CoreData documentation describes a 10,000 object collection as a fairly small data set, I was surprised to find a simple <strong>NSFetchRequest</strong> being responsible for massive resource spikes in a recent Mac application I&#8217;ve been working on.</p>
<p>The <strong>NSFetchRequest</strong> in question uses an <strong>NSPredicate</strong> to fetch <strong>Files</strong> entities with a given path. As can be seen from the original query, I&#8217;m performing a case-insensitive comparison of each records <strong>path</strong> attribute with a <strong>receivedPath</strong> string.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="objc"><pre class="de1"><span class="kw5">NSPredicate</span> <span class="sy0">*</span>predicate <span class="sy0">=</span> <span class="br0">&#91;</span><span class="kw5">NSPredicate</span> predicateWithFormat<span class="sy0">:</span><span class="co3">@</span><span class="st0">&quot;path ==[c] %@&quot;</span>, receivedPath<span class="br0">&#93;</span>;
&nbsp;
<span class="kw9">NSEntityDescription</span> <span class="sy0">*</span>entity <span class="sy0">=</span> <span class="br0">&#91;</span><span class="kw9">NSEntityDescription</span> entityForName<span class="sy0">:</span><span class="co3">@</span><span class="st0">&quot;Files&quot;</span> inManagedObjectContext<span class="sy0">:</span>self.moc<span class="br0">&#93;</span>;
<span class="kw9">NSFetchRequest</span> <span class="sy0">*</span>request <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="kw9">NSFetchRequest</span> alloc<span class="br0">&#93;</span> init<span class="br0">&#93;</span>;
<span class="br0">&#91;</span>request setEntity<span class="sy0">:</span>entity<span class="br0">&#93;</span>;</pre></div></div></div></div></div></div></div>


<p>While I had indexed the <strong>path</strong> attribute and ensured that I was using an <strong>NSSQLiteStoreType</strong> backing store, I hadn&#8217;t considered exactly how CoreData would treat the case-insensitive modifier internally. By passing my debug build the <strong>-com.apple.CoreData.SQLDebug</strong> argument, I was able to ascertain that the comparison makes use of a custom CoreData SQLite function: <strong>NSCoreDataStringCompare</strong>.</p>
<p>Essentially this meant that SQLite was boiling the string comparison down to a fairly costly LIKE statement, meaning my index was being overlooked completely. To solve the issue I simply created a secondary attribute: <strong>lowercasePath</strong>, ensured it too was indexed, and used a direct string comparison, like so:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="objc"><pre class="de1"><span class="kw5">NSPredicate</span> <span class="sy0">*</span>predicate <span class="sy0">=</span> <span class="br0">&#91;</span><span class="kw5">NSPredicate</span> predicateWithFormat<span class="sy0">:</span><span class="co3">@</span><span class="st0">&quot;path == %@&quot;</span>, <span class="br0">&#91;</span>receivedPath lowercaseString<span class="br0">&#93;</span><span class="br0">&#93;</span>;</pre></div></div></div></div></div></div></div>


<p>The results were staggering. The function in question is no longer significant enough to even register during profiling runs.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/07/optimizing-coredata-full-text-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Glyphs</title>
		<link>http://nial.me/2011/07/glyphs/</link>
		<comments>http://nial.me/2011/07/glyphs/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 06:15:26 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Icons]]></category>
		<category><![CDATA[Resources]]></category>

		<guid isPermaLink="false">http://nial.me/?p=302</guid>
		<description><![CDATA[A lovely set of free social media glyphs by GSIX Corp, Inc. Left here more for my own record. But please feel free to check them out. Via 9-Bits.]]></description>
			<content:encoded><![CDATA[<p><img src="http://nial.me/wp-content/uploads/2011/07/tumblr_lo09ax0ukb1qz7ywoo1_500.png" alt="" title="tumblr_lo09ax0ukb1qz7ywoo1_500" width="500" height="349" class="aligncenter size-full wp-image-303" /></p>
<p>A lovely set of free <a href="http://gsixcorp.com/glyphs/" target="_blank">social media glyphs</a> by GSIX Corp, Inc. Left here more for my own record. But please feel free to check them out. </p>
<p>Via <a href="http://9-bits.com/post/7465960235/some-free-vector-social-glyphs-from-gsix-corp" target="_blank">9-Bits</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/07/glyphs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Episodes v1.1</title>
		<link>http://nial.me/2011/02/episodes-v1-1/</link>
		<comments>http://nial.me/2011/02/episodes-v1-1/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 16:58:24 +0000</pubDate>
		<dc:creator>Nial Giacomelli</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nial.me/?p=291</guid>
		<description><![CDATA[Part of the fun of releasing applications is pushing out new and exciting features. Unfortunately before you can do that you need to solve outstanding issues. Thankfully with two bugfix releases behind us (v1.0.1 and v1.0.2), Ben and I are now looking to improve the application in some exciting (and hopefully unexpected) ways. Here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>Part of the fun of releasing applications is pushing out new and exciting features. Unfortunately before you can do that you need to solve outstanding issues. Thankfully with two bugfix releases behind us (v1.0.1 and v1.0.2), Ben and I are now looking to improve the application in some exciting (and hopefully unexpected) ways.</p>
<p>Here&#8217;s a quick list of the changes we&#8217;re hoping to roll-out later this week:</p>
<ul>
<li>Within your Watchlist, the Upcoming section will now show the next episode of a series that is due to air. We think this one will make a lot of people very happy.</li>
<li>We&#8217;re looking to introduce the ability to mark historic episodes as being seen/unseen. Making your way through an old Mad Men boxset? Not a problem. Tick episodes off as you watch them.</li>
<li>Finally, we&#8217;re making it possible for users to allow friends to see what&#8217;s on their watchlist. The service is totally free, and it&#8217;s opt-in. You can see an example of a public watchlist <a href="http://episodesapp.com/v/99udig">here</a> (note: still very much a work in progress).</li>
<li>A number of UI tweaks and fixes to customise and polish certain native behaviours we weren&#8217;t very happy with.</li>
</ul>
<p>Look out for Episodes v1.1 in the near future.</p>
]]></content:encoded>
			<wfw:commentRss>http://nial.me/2011/02/episodes-v1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  nial.me/feed/ ) in 0.14635 seconds, on Feb 4th, 2012 at 5:18 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 4th, 2012 at 6:18 pm UTC -->
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- Quick Cache Is Fully Functional :-) ... A Quick Cache file was just served for (  nial.me/feed/ ) in 0.00040 seconds, on Feb 4th, 2012 at 5:55 pm UTC. -->
