<?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>nvie.com &#187; Objective-C</title>
	<atom:link href="http://nvie.com/archives/category/objective-c/feed" rel="self" type="application/rss+xml" />
	<link>http://nvie.com</link>
	<description>Anything that interests me.</description>
	<lastBuildDate>Tue, 24 Aug 2010 11:21:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Auto-generate classes for your Core Data data model, revisited</title>
		<link>http://nvie.com/archives/310</link>
		<comments>http://nvie.com/archives/310#comments</comments>
		<pubDate>Mon, 19 Oct 2009 22:20:32 +0000</pubDate>
		<dc:creator>Vincent Driessen</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mogenerator]]></category>

		<guid isPermaLink="false">http://nvie.com/?p=310</guid>
		<description><![CDATA[A few months ago, I wrote about automatically generating classes for your Core Data entities and how to automate Xcode using users scripts, such that, when your model changed, you only needed to run your custom script again and your intermediate model files would reflect the new situation. Well, the guys from the mogenerator project [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, I wrote about <a title="Automatically generate classes for your Core Data data model" href="/archives/263">automatically generating classes for your Core Data entities</a> and how to automate Xcode using users scripts, such that, when your model changed, you only needed to run your custom script again and your intermediate model files would reflect the new situation.</p>
<p>Well, the guys from the <a title="mogenerator project at Github" href="http://github.com/rentzsch/mogenerator">mogenerator</a> project have come up with a far superior solution in the mean time. The newest version of mogenerator comes with an Xcode plugin named Xmo&#8217;d, which monitors your *.xcdatamodel file for changes and, as soon as it changes, regenerates all of the neccessary files.</p>
<p><strong>This means that there is officially no more reason not to use mogenerator.</strong></p>
<p>To set it up, download the installer package from their (improved) <a title="mogenerator project home page" href="http://rentzsch.github.com/mogenerator/">project website</a> and install it. (Before installing, please read the important release note about the renamed method <code>+newInManagedObjectContext:</code>.)</p>
<p>When installed, all you need to do is Command-click your *.xcdatamodel file, click Get Info, switch to the Comments tab and add the string &#8220;xmod&#8221; to the comment field. This is the trigger for Xmo&#8217;d to start (re)generating your machine-classes (the underscored class files) when the data model changes. Brilliant!</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/10/comment-field.png"><img class="alignnone size-full wp-image-311" title="Adding the trigger to the comment field." src="http://nvie.com/wp-content/uploads/2009/10/comment-field.png" alt="Adding the trigger to the comment field." width="381" height="545" /></a></p>
<p>Oh, the default location at which the generated files will be emitted, is in a folder named after your project, right next to where your *.xcdatamodel already sits:</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/10/emission-location.png"><img class="alignnone size-medium wp-image-314" title="Location where output files are generated" src="http://nvie.com/wp-content/uploads/2009/10/emission-location-300x239.png" alt="Location where output files are generated" width="300" height="239" /></a></p>
<p>Enjoy it and spread the word!</p>
]]></content:encoded>
			<wfw:commentRss>http://nvie.com/archives/310/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically generate classes for your Core Data data model</title>
		<link>http://nvie.com/archives/263</link>
		<comments>http://nvie.com/archives/263#comments</comments>
		<pubDate>Thu, 30 Jul 2009 22:20:34 +0000</pubDate>
		<dc:creator>Vincent Driessen</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[User scripts]]></category>
		<category><![CDATA[Xcode]]></category>
		<category><![CDATA[mogenerator]]></category>

		<guid isPermaLink="false">http://nvie.com/?p=263</guid>
		<description><![CDATA[When designing a Core Data data model for your Xcode projects, you can choose to create Objective-C object wrappers for your entities, so that you can profit from type-safe code. The normal, tedious, workflow for this is that you select each entity from the model designer, select all of its attributes and relationships, Ctrl-click it [...]]]></description>
			<content:encoded><![CDATA[<p>When designing a Core Data data model for your Xcode projects, you can choose to create Objective-C object wrappers for your entities, so that you can profit from type-safe code. The normal, tedious, workflow for this is that you select each entity from the model designer, select all of its attributes and relationships, Ctrl-click it and from the contextual menu first select &#8220;Copy Obj-C 2.0 Method Declarations To Clipboard&#8221;, paste it into the appropriate class header file, then do the same thing for the method implementations in the class implementation file. Waaaaaay too much work. Not to mention the manual copy-pastes are really hard to keep in sync once you start adding functionality to these class files, since you don&#8217;t want to overwrite those additions, but you want to keep replacing everything else.</p>
<h3>Meet mogenerator</h3>
<p>Fortunately, there is a great way for automating this process, using mogenerator. The tool can be downloaded as a <a href="http://aralbalkan.com/2152">DMG installer</a> (Aral Balkan&#8217;s blog mentions a workaround for older Xcode versions, but for Xcode 3.1.3 it worked out of the box for me), or you can checkout the sources from <a href="http://github.com/rentzsch/mogenerator/">github</a> and build it yourself.</p>
<p>The mogenerator command line tool eases this generation process by reading the *.xcdatamodel file and generating both class files and intermediate class files for each entity. The intermediate classes (called <em>machine</em> classes) are continuously overwritten by subsequent regenerations, so you should never edit the contents of these files. The actual model object classes (called <em>human</em> classes) inherit from those intermediate classes with a default empty implementation, allowing for all manual extensions.</p>
<p>For example, when you design a model with two entities Foo and Bar, mogenerator can be invokes as follows:</p>
<pre>mogenerator -m MyDocument.xcdatamodel -M Entities -H Model</pre>
<p>The flag -m sets the input model file, while -M and -H specify the output directories where the machine and human classes should be generated respectively.</p>
<p>This does a few things:</p>
<ul>
<li>In the Entities subdirectory, there will be generated header and implementation files for NSManagedObject subclasses called _Foo and _Bar;</li>
<li>In the Model subdirectory, there will be generated classes called Foo and Bar—respective subclasses of _Foo and _Bar. These are only created if not available yet. Otherwise, they are left as is.</li>
</ul>
<h3>Wrapping it up</h3>
<p>The trick of how mogenerator works is that you can run the script as often as you want. After every change in your model, you&#8217;ll want to re-run the generation again to update the machine classes. You could easily leave Xcode, switch over to Terminal and issue the command above. But you&#8217;ll get quite tired of that after a few times.</p>
<p>Therefore, I&#8217;ve written a custom user script that can be added to Xcode (see figure), which does the following:</p>
<ul>
<li>You can configure the output directories in the first lines of the script. There is no per-project configuration, so choose them as you would like to use them with all your projects;</li>
<li>Mind that these generated files are not automatically included in your Xcode project. Drag them there once and ideally put the machine generated classes into a group under &#8220;Other resource&#8221;, so you never have to see them again. Whenever you add a new class to your model, new files will be generated, so again you must drag the new files to reference those, of course!</li>
<li>The script can be run with any file in the project opened. It starts out with that file and walks up the directory tree to search for your Xcode project. If found, it executes all the rest from your project directory. (Suggestions are welcome, I could not find a better implementation since a variable like %%%{PBXProjectPath}%%% does not seem to exist.)</li>
<li>It invokes mogenerator to generate all model classes for the project. It is smart enough to detect whether you are using Brian Webster&#8217;s <a href="http://www.fatcatsoftware.com/blog/2008/per-object-ordered-relationships-using-core-data">BWOrderedManagedObject</a> in your project. If so, your generated machine classes will inherit from BWOrderedManagedObject instead of NSManagedObject.</li>
</ul>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/set-user-script.png"><img class="alignnone size-medium wp-image-291" title="Edit user script window" src="http://nvie.com/wp-content/uploads/2009/07/set-user-script-300x211.png" alt="Edit user script window" width="300" height="211" /></a></p>
<p>To add this script to Xcode, open the menu Scripts (the icon) &gt; Edit User Scripts&#8230; Click the &#8220;+&#8221;-button on the bottom-left and select &#8220;New shell script&#8221;. Set the values for Input, Directory, Output and Errors as in the screenshot above, then copy-paste the script below into the code window. Add a nice keyboard shortcut to this action to top it off :-) I&#8217;ve chosen ^⌥⌘G for this.</p>
<p>Please feel free to leave any comments if this helped you.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">#!/bin/sh
#
# Automatic (re)generation of model classes for all *.xcdatamodel files.
# Written by Vincent Driessen
#
# You are free to use this script in any way.
# The original blog post is http://nvie.com/archives/263
#
&nbsp;
# Define output directories
MACHINE_DIR=&quot;Entities&quot;
MODEL_DIR=&quot;Model&quot;
&nbsp;
# Look for the Xcode project directory for this file
cd `dirname &quot;%%%{PBXFilePath}%%%&quot;`
while [ `ls -d *.xcodeproj 2&amp;gt;/dev/null | wc -l` -eq 0 ]; do
    cd ..
    if [ &quot;`pwd`&quot; = &quot;/&quot; ]; then
        echo &quot;No Xcode project found.&quot;
        exit 1
    fi
done
&nbsp;
echo &quot;Project directory is `pwd`&quot;
&nbsp;
#
# Check to see whether the base class is just a default (NSManagedObject) or maybe
# Brian Webster's excellent BWOrderedManagedObject.
# http://www.fatcatsoftware.com/blog/2008/per-object-ordered-relationships-using-core-data
#
# NOTE:
# The check really is quite arbitrary: if there exists a file called BWOrderedManagedObject.h
# somewhere below the project root directory, we assume that we want to use this as the base
# class for all generated classes.
#
EXTRA_FLAGS=
if [ `find . -name BWOrderedManagedObject.h | wc -l` -gt 0 ]; then
	EXTRA_FLAGS+=&quot;--base-class BWOrderedManagedObject&quot;
fi
&nbsp;
# Generate the model classes using mogenerator
for model in `find . -name '*.xcdatamodel'`; do
	# The output directories have to exist, so create them
    mkdir -p &quot;${MACHINE_DIR}&quot; &quot;${MODEL_DIR}&quot;
    mogenerator ${EXTRA_FLAGS} -m &quot;${model}&quot; -M &quot;${MACHINE_DIR}&quot; -H &quot;${MODEL_DIR}&quot;
done</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://nvie.com/archives/263/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>NSManagedObjectContext extensions</title>
		<link>http://nvie.com/archives/243</link>
		<comments>http://nvie.com/archives/243#comments</comments>
		<pubDate>Tue, 21 Jul 2009 23:32:49 +0000</pubDate>
		<dc:creator>Vincent Driessen</dc:creator>
				<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://nvie.com/?p=243</guid>
		<description><![CDATA[The Core Data framework rules, and its API is really really powerful. But really, why does the Core Data API require us to write so much boilerplate code? Simple things need to be simple. Why is the deletion of a managed object from the NSManagedObjectContext so easy: &#91;context deleteObject:someObject&#93;; Compared to its creation: &#91;NSEntityDescription insertNewObjectForEntityForName:@&#34;someObjectClassName&#34; [...]]]></description>
			<content:encoded><![CDATA[<p>The Core Data framework rules, and its API is really really powerful. But really, why does the Core Data API require us to write so much boilerplate code? Simple things need to be simple.</p>
<p>Why is the deletion of a managed object from the NSManagedObjectContext so easy:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>context deleteObject<span style="color: #002200;">:</span>someObject<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Compared to its creation:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSEntityDescription</span> insertNewObjectForEntityForName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;someObjectClassName&quot;</span>
                              inManagedObjectContext<span style="color: #002200;">:</span>context<span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Extending NSManagedObjectContext</h3>
<p>Add the following category on NSManagedObjectContext to all of your Core Data projects and your pains will be history.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> <span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">&#40;</span>NSManagedObjectContextConvenienceMethods<span style="color: #002200;">&#41;</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>newObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">Class</span><span style="color: #002200;">&#41;</span>entity <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSEntityDescription</span> insertNewObjectForEntityForName<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>entity description<span style="color: #002200;">&#93;</span>
                                         inManagedObjectContext<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>Now, a call to create a new object is as easy as deleting it.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>context newObject<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>someEntity class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Further enhancements of NSManagedObject</h3>
<p>Matt Gallagher has written an <a href="http://cocoawithlove.com/2008/03/core-data-one-line-fetch.html">excellent article</a> about how to further enhance NSManagedObject for adding simple, one-line fetch support. Be sure to check it out.</p>
]]></content:encoded>
			<wfw:commentRss>http://nvie.com/archives/243/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>NSPredicateEditor tutorial</title>
		<link>http://nvie.com/archives/197</link>
		<comments>http://nvie.com/archives/197#comments</comments>
		<pubDate>Mon, 20 Jul 2009 15:22:01 +0000</pubDate>
		<dc:creator>Vincent Driessen</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Cocoa bindings]]></category>
		<category><![CDATA[NSPredicate]]></category>
		<category><![CDATA[NSPredicateEditor]]></category>
		<category><![CDATA[NSPredicateEditorRowTemplate]]></category>
		<category><![CDATA[Sheet programming]]></category>

		<guid isPermaLink="false">http://nvie.com/?p=197</guid>
		<description><![CDATA[Cocoa offers a nice visual editor for editing NSPredicate objects templates, called NSPredicateEditor. The NSPredicateEditor can be set up using code or in Interface Builder, which is preferable for simple use. The setup is fairly easy once you know how to do it. In this tutorial, we&#8217;ll be building a simple predicate editor example which [...]]]></description>
			<content:encoded><![CDATA[<p>Cocoa offers a nice visual editor for editing NSPredicate objects templates, called NSPredicateEditor. The NSPredicateEditor can be set up using code or in Interface Builder, which is preferable for simple use. The setup is fairly easy once you know how to do it. In this tutorial, we&#8217;ll be building a simple predicate editor example which shows the basic functionality of the predicate editor.</p>
<h3>Setting up the AppDelegate</h3>
<p>Begin by creating a new Xcode project (Cmd+Shift+N). Name your project wisely and create a new class in the Classes group, called AppDelegate.</p>
<p>Switch to the header file and declare two IBOutlets for the main window and the sheet on which we&#8217;re going to display the editor in a few minutes. Also, add two IBActions called -openEditor: and -closeEditor:. Finally, add an ivar that holds the NSPredicate we&#8217;re going to be editing.</p>
<p><img class="alignnone size-full wp-image-202" title="Your project should look like this" src="http://nvie.com/wp-content/uploads/2009/07/appdelegate1.png" alt="Your project should look like this" width="678" height="557" /></p>
<p>Next, we&#8217;re going to fire up Interface Builder to build the UI. Double click on the MainMenu.xib file under the Resources group.</p>
<p>Drag an NSObject object from the Library into the XIB and call it App Delegate. Hit Cmd+6 and make it a subclass of the AppDelegate class we just created. Then, hook it up to the delegate property of the File&#8217;s Owner.</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/choose-delegate.png"><img class="alignnone size-medium wp-image-204" title="Make the object a subclass of the just-defined AppDelegate class" src="http://nvie.com/wp-content/uploads/2009/07/choose-delegate-257x300.png" alt="Make the object a subclass of the just-defined AppDelegate class" width="257" height="300" /></a><a href="http://nvie.com/wp-content/uploads/2009/07/hookup-appdelegate.png"><img class="alignnone size-medium wp-image-203" title="Hooking up the AppDelegate to the application" src="http://nvie.com/wp-content/uploads/2009/07/hookup-appdelegate-300x232.png" alt="Hooking up the AppDelegate to the application" width="300" height="232" /></a></p>
<p>Drag a new NSWindow to the XIB-file and call it Sheet. Make sure the checkbox &#8220;Visible At Launch&#8221; is deselected or the sheet will not display properly at runtime. Open the main window and add a NSButton and a NSTextView to it. To the sheet window, drag a NSPredicateEditor and a NSButton. They should look somewhat like this now:</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/Picture-5.png"><img class="alignnone size-medium wp-image-208" title="The main window" src="http://nvie.com/wp-content/uploads/2009/07/Picture-5-300x230.png" alt="The main window" width="300" height="230" /></a><a href="http://nvie.com/wp-content/uploads/2009/07/Picture-4.png"><img class="alignnone size-medium wp-image-209" title="The predicate editor window" src="http://nvie.com/wp-content/uploads/2009/07/Picture-4-300x230.png" alt="The predicate editor window" width="300" height="230" /></a></p>
<p>Now, we can hook up the outlets and actions as usual. Hook up the Edit Predicate button on the main window to -openEditor: and the OK button on the sheet window to closeEditor:. Then hook up the mainWindow and sheet outlets of the AppDelegate class to the respective NSWindow objects.</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/hookup-windows.png"><img class="alignnone size-medium wp-image-216" title="Hooking up the windows" src="http://nvie.com/wp-content/uploads/2009/07/hookup-windows-300x220.png" alt="Hooking up the windows" width="300" height="220" /></a></p>
<h3>Configure the NSPredicateEditor</h3>
<p>Once we have all of the connections between Xcode and Interface Builder set up, we can continue to configure the predicate editor itself, which is actually what this tutorial is all about. An NSPredicateEditor control uses a list of NSPredicateEditorRowTemplate objects that can handle individual (simple) NSPredicate objects. Combining these row templates enables the NSPredicateEditor to edit compound predicates. There is no limitation to the depth of nested compound predicates, although nesting too deep would not be advisable from a usability perspective.</p>
<p>In the edit window, click a few times until the &#8220;name contains&#8221; row template is selected. In this row template, you define which key paths are supported. Supported here means two things:</p>
<ul>
<li><strong>matching</strong>—given an existing predicate with this key path in it on the left-hand side, this row template can be used to alter the predicate;</li>
<li><strong>generation</strong>—when using the editor to create new predicates, adding a new rule for this key path will generate a predicate for this key path.</li>
</ul>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/Picture-10.png"><img class="alignnone size-medium wp-image-221" title="Select the row template" src="http://nvie.com/wp-content/uploads/2009/07/Picture-10-300x230.png" alt="Select the row template" width="300" height="230" /></a><a href="http://nvie.com/wp-content/uploads/2009/07/Picture-13.png"><img class="alignnone size-medium wp-image-220" title="Define the left-hand sides that this row template can handle" src="http://nvie.com/wp-content/uploads/2009/07/Picture-13-163x300.png" alt="Define the left-hand sides that this row template can handle" width="163" height="300" /></a></p>
<h4>Gotcha</h4>
<p>A small gotcha, at least one that initially put me on the wrong foot, is that there is quite a difference between the rows that you see design-time in Interface Builder and the rows that are available run-time. At design-time, you define the NSPredicateEditorRowTemplate objects while at run-time you see instances of them. Hence, the number of rows at design-time is the <em>number of different row templates available</em>. At run-time, however, the number of rows is the number of <em>(simple) predicates within the compound predicate</em> (which each has an associated row template instance that handles it). Subtle difference.</p>
<p>In short, in Interface Builder, <strong>create a row template for <em>each type of match</em> that you want to allow</strong>. Typically, this means for each data type that you want to support. In our example, we have the following setup:</p>
<ul>
<li>Row template #1 is for all string matches. Here, we have defined it for the key paths &#8220;firstname&#8221;, &#8220;lastname&#8221;, &#8220;address.street&#8221; and &#8220;address.city&#8221;. They, per definition, have the same  allowed operators. If we want to have an other set of operators for a specific key path, we need to define a separate row template for it.</li>
<li>Row template #2 is for date matches, i.e. our &#8220;birthdate&#8221; key path.</li>
<li>Row template #3 is for all integer matches, i.e. our &#8220;address.number&#8221; key path.</li>
</ul>
<p>The result looks like this:</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/row-templates-setup.png"><img class="alignnone size-medium wp-image-223" title="Row templates setup" src="http://nvie.com/wp-content/uploads/2009/07/row-templates-setup-300x177.png" alt="Row templates setup" width="300" height="177" /></a></p>
<h3>Using bindings to connect the predicate to the UI</h3>
<p>Next up, we simply connect both the text view from the main window and the predicate editor from the sheet window to the predicate key path using Cocoa bindings. In order to do so, select the NSPredicateEditor (first click the control to select the scroll view, then click again to select the inner NSPredicateEditor), hit Cmd+4. Then, unfold the &#8220;Value&#8221; binding and hook it up to the App Delegate&#8217;s &#8220;predicate&#8221; key path.</p>
<p><a href="http://nvie.com/wp-content/uploads/2009/07/bindings.png"><img class="alignnone size-medium wp-image-224" title="Setting up the Cocoa bindings" src="http://nvie.com/wp-content/uploads/2009/07/bindings-215x300.png" alt="Setting up the Cocoa bindings" width="215" height="300" /></a></p>
<p>Do the same for the text view in the main window, but this time hook it up to the &#8220;predicate.description&#8221; key path (since only strings can be displayed in a text view). When you do this, make sure that the text view is read-only, since the description property of objects should never be set.</p>
<h3>Writing the code to wrap it all up</h3>
<p>Finally, we have only a bit of code to write in our AppDelegate implementation, so let&#8217;s go:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">//</span>
<span style="color: #11740a; font-style: italic;">//  AppDelegate.m</span>
<span style="color: #11740a; font-style: italic;">//  PredicateEditorTest</span>
<span style="color: #11740a; font-style: italic;">//</span>
<span style="color: #11740a; font-style: italic;">//  Created by Vincent on 20-07-09.</span>
<span style="color: #11740a; font-style: italic;">//</span>
&nbsp;
<span style="color: #6e371a;">#import &quot;AppDelegate.h&quot;</span>
&nbsp;
<span style="color: #6e371a;">#define DEFAULT_PREDICATE @&quot;(firstname = 'John' AND lastname = 'Doe') &quot; \</span>
                          <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;OR birthdate &amp;gt; CAST('01/01/1985', 'NSDate') &quot;</span> \
                          <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;OR address.city = 'Chicago' &quot;</span> \
                          <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;AND address.street != 'Main Street' &quot;</span> \
                          <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;OR address.number &amp;gt; 1000&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> AppDelegate
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>init
<span style="color: #002200;">&#123;</span>
	self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		predicate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span>DEFAULT_PREDICATE<span style="color: #002200;">&#93;</span> retain<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> self;
<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>dealloc
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>predicate release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>openEditor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>NSApp beginSheet<span style="color: #002200;">:</span>sheet
	   modalForWindow<span style="color: #002200;">:</span>mainWindow
		modalDelegate<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
	   didEndSelector<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span>
		  contextInfo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</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>IBAction<span style="color: #002200;">&#41;</span>closeEditor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>NSApp endSheet<span style="color: #002200;">:</span>sheet<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>sheet orderOut<span style="color: #002200;">:</span>sender<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>In the -init: method, we initialize the AppDelegate by setting and retaining a reference to a rather complex default predicate. When the XIB is loaded at run-time, the textbox shows exactly this predicate and it can be edited by invoking the edit sheet.</p>
<p>The actual implementation of the -openEditor: and -closeEditor: methods aren&#8217;t too exciting.</p>
<h3>Downloading the source</h3>
<p>You can download the source code for this tutorial as an Xcode project here.</p>
<table border="0">
<tbody>
<tr>
<td align="center"><a href="http://nvie.com/wp-content/uploads/2009/07/PredicateEditorTest.zip"><img class="alignnone size-full wp-image-232" src="http://nvie.com/wp-content/uploads/2009/07/zipfile.png" alt="" width="128" height="128" /></a></td>
</tr>
<tr>
<td align="center"><a href="http://nvie.com/wp-content/uploads/2009/07/PredicateEditorTest.zip"><strong>PredicateEditorTest.zip</strong></a></td>
</tr>
</tbody>
</table>
<p>Have a blast!</p>
]]></content:encoded>
			<wfw:commentRss>http://nvie.com/archives/197/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
