<?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>Orange Juice Liberation Front</title>
	<atom:link href="http://orangejuiceliberationfront.com/feed/?cat=-303" rel="self" type="application/rss+xml" />
	<link>http://orangejuiceliberationfront.com</link>
	<description>Uli&#039;s citrussy fresh thoughts on technical stuff</description>
	<lastBuildDate>Mon, 13 May 2013 20:59:10 +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>
		<item>
		<title>Blocks and block lists</title>
		<link>http://orangejuiceliberationfront.com/blocks-and-block-lists/</link>
		<comments>http://orangejuiceliberationfront.com/blocks-and-block-lists/#comments</comments>
		<pubDate>Wed, 08 May 2013 13:35:26 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Common Cocoa Coding Patterns]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=585</guid>
		<description><![CDATA[When I first heard about blocks, I was horrified. All the un-clean code structure of huge ten-page functions, plus the loss of self-documenting function names. Why would someone want anonymous functions? And even worse, anonymous functions that can cause retain circles because they automatically retain objects you reference, because they have access to the scope &#8230;  <a href="http://orangejuiceliberationfront.com/blocks-and-block-lists/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://orangejuiceliberationfront.com/wp-content/uploads/2013/05/doctor_who_blocks.jpg"><img class="aligncenter size-full wp-image-606" alt="doctor_who_blocks" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/05/doctor_who_blocks.jpg" width="480" height="360" /></a></p>
<p>When I first heard about blocks, I was horrified. All the un-clean code structure of huge ten-page functions, plus the loss of self-documenting function names. Why would someone want anonymous functions? And even worse, anonymous functions that can cause retain circles because they automatically retain objects you reference, because they have access to the scope of the surrounding function, like nested functions?</p>
<p>Then, at one NSConference, someone pointed out that they are really good for making asynchronous code look more synchronous. Who would have thought that blocks, carefully used, could actually improve readability of code?</p>
<p>Imagine you are using an NSURLConnection to retrieve a JSON file from a server and extract information from it. In synchronous pseudocode:</p>
<pre>-(void) showInfo
{
    NSString* myJSON = [NSString stringWithContentsOfURL: @"http://example.com/data.json"];
    if( myJSON == nil )
    {
        [self reportError];
        return;
    }
    NSString* userText = [self prettyPrintJSON: myJSON];
    [self showPanelWithText: userText button: @"OK"];
}</pre>
<p>Minimal code for doing this asynchronously and avoid blocking the user interface and spinning the beach ball when the connection is slow includes creating an <tt>NSURLConnection</tt>, setting yourself as its delegate then displaying any error you get from one delegate method, or when the request completes and a second is called, to actually process the request. So the above code turns into pseudocode:</p>
<pre>-(void) showInfo
{
    self.connection = [[NSURLConnection alloc] initWithURL: @"http://example.com/data.json"];
    myConnection.delegate = self;
    [myConnection start];
}

-(void) connection: (NSURLConnection*)sender didFinishLoading: (NSString*)myJSON
{
    NSString* userText = [self prettyPrintJSON: myJSON];
    [self showPanelWithText: userText button: @"OK"];
    self.connection = nil;
}

-(void) connectionDidFailLoading: (NSURLConnection*)sender
{
    [self reportError];    
}</pre>
<p>Notice how 5 straightforward lines have turned into a spaghetti of three methods? Now imagine you had to chain several requests. You&#8217;d have to create separate delegate objects for each request, or key off the &#8216;sender&#8217; parameter and handle the OK case for all requests together in one delegate method, and the error cases together in another.</p>
<p>Now how does that look with blocks (still pseudocode)?</p>
<pre>-(void) showInfo
{
    [NSURLConnection sendAsynchronousRequest: @"http://example.com/data.json" completionHandler: ^( NSURLRequest req, NSString* myJSON, NSError* error )
        {
            if( error )
            {
                [self reportError];
                return;
            }
            NSString * userText = [self prettyPrintJSON: myJSON];
            [self showPanelWithText: userText button: @"OK"];
        }];
}</pre>
<p>Shockingly, that almost looks like our original, synchronous code. Now to be fair, if someone at Apple had added a delegate method to <tt>NSURLConnection</tt> that combined the error case and the success case like the above block does, the original example would be a tad simpler as well. But performing several requests in sequence would still split the actual requests from their replies, and group them by request or reply.</p>
<p>With blocks, on the other hand, two requests in sequence would look almost like the synchronous code would, with nested ifs:</p>
<pre>-(void) showInfo
{
    [NSURLConnection sendAsynchronousRequest: @"http://example.com/data.json" completionHandler: ^( NSURLRequest* req, NSString* myJSON, NSError* error )
    {
        if( error != nil )
        {
            [self reportError];
            return;
        }

        NSString* userText = [self prettyPrintJSON: myJSON];
        [self showPanelWithText: userText button: @"OK"];

        [NSURLConnection sendAsynchronousRequest: @"http"//example.com/data2.json" completionHandler: ^( NSURLRequest* req2, NSString* myJSON2, NSError* error2 )
        {
            if( error2 != nil )
            {
                [self reportError];
                return;
            }

            NSString * userText2 = [self prettyPrintJSON: myJSON2];
            [self showPanelWithText: userText2 button: @"Done"];
        }];
    }];
}</pre>
<p>You&#8217;re probably already seeing where our problem is, though. Since every block adds one level of brackets and depth, it becomes pretty hard to re-order requests. You&#8217;d have to cut the inner request out, then wrap it around the outer request so it only triggers the other request on success.</p>
<p>But here is where it comes in handy that blocks aren&#8217;t just nested functions. Blocks are actually real Objective-C objects. So, we can keep an array of blocks:</p>
<pre>-(void) showInfo
{
    NSMutableArray * steps = [NSMutableArray array];
    [steps addObject: ^( NSMutableArray * steps )
    {
        // First request start:
        [NSURLConnection sendAsynchronousRequest: @"http://example.com/data.json" completionHandler: ^( NSURLRequest* req, NSString* myJSON, NSError* error )
        {
            if( error != nil )
            {
                [self reportError];
                return;
            }

            NSString* userText = [self prettyPrintJSON: myJSON];
            [self showPanelWithText: userText button: @"OK"];
            // First request end.

            [[steps[0] retain] autorelease]; // Make sure we don't go away.
            [steps removeObjectAtIndex: 0];
            steps[0]( steps );
        }];
    }];
    [steps addObject: ^( NSMutableArray * steps )
    {
        // Second request start:
        [NSURLConnection sendAsynchronousRequest: @"http://example.com/data2.json" completionHandler: ^( NSURLRequest* req2, NSString* myJSON2, NSError* error2 )
        {
            if( error2 != nil )
            {
                [self reportError];
                return;
            }

            NSString* userText2 = [self prettyPrintJSON: myJSON2];
            [self showPanelWithText: userText2 button: @"OK"];
            // First request end.

            [[steps[0] retain] autorelease]; // Make sure we don't go away.
            [steps removeObjectAtIndex: 0];
            steps[0]( steps );
        }];
    }];
    [steps addObject: ^( NSMutableArray * steps )
    {
        // Done.
    }];
    steps[0]( steps ); // Kick off execution
}</pre>
<p>So, we add the blocks to an array with 3 <tt>-addObject:</tt> calls, then at the bottom run the first block in the array. When each block is done, it removes itself from the array, and runs the next block in the array (except for the last block, which is simply there so the second-to-last block has someone after it to call &#8212; we could also just check whether the array is empty before trying to call the next block). This looks a little more complicated than it should, but if wrapped in an ObjC class with a <tt>-next</tt> method is very readable.</p>
<p>Now, if you want to re-order two requests, you simply re-order the <tt>-addObject:</tt> calls. Since none of the blocks care which block follows them, you don&#8217;t need to wrap anything around anything else.</p>
<p>You can now read all requests in sequence (hence I call these things block sequences), ignoring the spots at which control is given up to the system for a while, and re-arrange them as you please. Neat, huh?</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/blocks-and-block-lists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why Cocoa programmers can&#8217;t have nice things</title>
		<link>http://orangejuiceliberationfront.com/why-cocoa-programmers-cant-have-nice-things/</link>
		<comments>http://orangejuiceliberationfront.com/why-cocoa-programmers-cant-have-nice-things/#comments</comments>
		<pubDate>Sat, 04 May 2013 13:27:48 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Language Design]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=603</guid>
		<description><![CDATA[Amy Worrall pointed me at a nice post on the technical feasibility of using exceptions for more than programming errors in Cocoa by Hari Karam Singh. Even though he is misled by some Mac documentation into thinking iOS didn&#8217;t have zero-cost exceptions and then disproves that documentation by disassembly, he draws lots of valid conclusions. &#8230;  <a href="http://orangejuiceliberationfront.com/why-cocoa-programmers-cant-have-nice-things/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><img src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/05/IMG_0315.jpg" alt="IMG_0315" width="480" height="359" class="aligncenter size-full wp-image-611" /><br />
Amy Worrall pointed me at <a href="http://club15cc.com/code/objective-c/dispelling-nsexception-myths-in-ios-can-we-use-try-catch-finally" target="_blank">a nice post on the technical feasibility of using exceptions for more than programming errors</a> in Cocoa by Hari Karam Singh. Even though he is misled by some Mac documentation into thinking iOS didn&#8217;t have zero-cost exceptions and then disproves that documentation by disassembly, he draws lots of valid conclusions.</p>
<p>However, the problem is not one of technology. The problem is one of the sheer size of Apple&#8217;s Cocoa codebase, which would have to be updated to survive having an exception thrown through it. Apple would have to add @trys in every location where they call a <tt>SEL</tt>, after all, since they don’t know which of them may be user-provided and throw.</p>
<p>Since they’re not doing that, a user who decides to use exceptions anyway would have to add @trys to every method that might ever be called by the framework. That means you can’t catch exceptions thrown by that method when <em>you</em> call it, though, because it swallows them itself. So if you want to handle errors from that method, you either split it up into <tt>okButtonClickedThrows:</tt> and <tt>okButtonClicked:</tt>, duplicating every method and working in parallel with two error handling schemes, or you give up, like Apple, and just use one non-exception error handling scheme.</p>
<p>I love exceptions, but I don’t think my Cocoa code will be cleaner and error handling nicer if I put a try block at the top of every action and delegate method. <a href="http://orangejuiceliberationfront.com/common-cocoa-coding-patterns-nserror-returns/" target="_blank">NSError is less dangerous</a>, because if an object returns <tt>nil</tt> and gives an error (and you don’t look at the returned error), the method call will simply collapse (call to NIL is a no-op) so nothing much will happen. Since I can’t put up an error dialog from drawing code or table delegate callbacks like numberOfSections, there’s not much difference there. The code is actually cleaner, because with <tt>NSError</tt> and <tt>nil</tt> returns I can just ignore errors, while with exceptions in an exception-unsafe Cocoa, I <em>must</em> catch here or I’ll risk throwing through Cocoa.</p>
<p>C++ also has an advantage when working with exceptions over Objective-C because it uses &#8220;Resource Acquisition Is Initialization&#8221; (or RAII for short). Locks, allocations, even changes of a global boolean can be implemented as stack objects using RAII to set themselves up when created and clean up behind themselves in their destructor. You don’t even have a ‘finally’ block in the language. OTOH, every method you write in an exception-handling ObjC would need an @finally block, even if it doesn’t care about the errors, just to clean up behind itself.</p>
<p>ARC, <tt>@autoreleasepool</tt> and <tt>@synchronized</tt> can help a little with clean-up of memory and locks these days, as they’ll get triggered on an exception anyway. But as Cocoa and Apple&#8217;s frameworks currently stand, using exceptions effectively doubles your work.</p>
<p>The same applies to existing code. Nobody wants to have to completely rewrite their apps for 10.9 just to adopt a new error handling scheme when their code already has working error handling with <tt>NSError</tt>. Apple understands that their developers want a certain degree of backward compatibility. That’s the reason why only iOS got the new runtime on 32-bit: There was no code that relied on the old runtime there, it was a new platform. But all existing Mac applications would have been broken if the system had suddenly no longer guaranteed instance variable layouts and method lookup-tables. However, since 64-bit required changes to pointer sizes and data structures anyway, nobody complained when Apple introduced the new runtime for 64 bit on the Mac. They had to re-test and update their applications anyway.</p>
<p>All that said, I would love a new Objective-C framework that uses exceptions and is exception-safe for new projects to be built against. It just doesn’t seem like something Apple can retrofit at a whim.</p>
<p>At best, they can slowly make each framework exception-safe, and then in every spot where there can be an error, instead of returning it, look at an “app supports exception handling”-flag and throw their errors if that is set. That way, existing applications will keep working, while new applications can be written exception-safe. And once the majority of applications have moved to exceptions, Apple can switch to using exceptions themselves (see above — you don’t want 2 versions, exception-safe and unsafe, of every method), and tell the stragglers to please make <em>their</em> code exception-safe.</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/why-cocoa-programmers-cant-have-nice-things/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Setting up Jenkins for Github and Xcode, with Nightlies</title>
		<link>http://orangejuiceliberationfront.com/setting-up-jenkins-for-github-and-xcode-with-nightlies/</link>
		<comments>http://orangejuiceliberationfront.com/setting-up-jenkins-for-github-and-xcode-with-nightlies/#comments</comments>
		<pubDate>Sat, 06 Apr 2013 13:23:35 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=586</guid>
		<description><![CDATA[Jenkins? What? Why? When you work alone on a several projects that share code, it&#8217;s easy to unnoticeably break the build of one project with a change for the other, or introduce some specific dependency on a quirk of your main work Mac, or lose data by referencing a file outside the repository instead of &#8230;  <a href="http://orangejuiceliberationfront.com/setting-up-jenkins-for-github-and-xcode-with-nightlies/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><img src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/IMG_0320.jpg" alt="IMG_0320" width="480" height="359" class="aligncenter size-full wp-image-612" /></p>
<h3>Jenkins? What? Why?</h3>
<p>When you work alone on a several projects that share code, it&#8217;s easy to unnoticeably break the build of one project with a change for the other, or introduce some specific dependency on a quirk of your main work Mac, or lose data by referencing a file outside the repository instead of copying it in. Since that&#8217;s annoying, I decided to set up Jenkins, a <i>continuous integration</i> system, on my Mac mini that serves as my EyeTV DVR, media centre and home server.</p>
<p>It&#8217;s not that hard, but some of the details are a bit fiddly and under-documented, so I thought I&#8217;d write down how I made it work before I forget it (and for when I next have to set it up again). My source code is in a Github repository, and while I was at it, I wanted to set it up that one of my open source projects gets nightly builds FTPed onto its web site (but only when I&#8217;ve actually changed something).</p>
<h3>Initial Install</h3>
<p>Jenkins is a Java application. Since Java no longer comes pre-installed on Mac OS X, if you&#8217;re not using any other Java applications, you should open a Terminal and type in <tt>java</tt>, which will make Mac OS X  notice Java is not yet installed and download it. Also make sure you&#8217;ve installed Xcode on your Mac. The version from the app store is fine, but make sure you install the command line tools under <i>Preferences</i> &gt; <i>Downloads</i> on the <i>Components</i> tab, so Jenkins will be able to find <tt>git</tt>.</p>
<p>Next, you&#8217;ll want to create a dedicated user account that Jenkins will run under. The standard installer does that for you, but it only creates a command-line account, which makes it very hard to set up all the certificates, so go to <i>System Preferences</i>&#8216;s <i>Users &#038; Groups</i> section, and create a new account and name it &#8220;Jenkins&#8221;. Make sure you enter &#8220;Jenkins&#8221; with a capital &#8216;J&#8217; under &#8220;Account name&#8221;. Also, right-click the account in the list on the left and choose &#8220;Advanced Options&#8230;&#8221;. Replace the standard home directory &#8220;/Users/Jenkins&#8221; with &#8220;/Users/Shared/Jenkins&#8221;, which is what the standard installer will use.</p>
<p>Now that all is ready, go to <a href="http://jenkins-ci.org" target="_blank">jenkins-ci.org</a>, and right on the front page you&#8217;ll find a Mac OS X direct download link that gives you a nice Mac installer package. Run that. Jenkins will be installed so it automatically launches at system startup, and it will run on your Mac on Port 8080. So make a note to later forward that port through your router to your Mac so it is accessible from the outside (you will need a dynDNS domain-name connected to it, or a static IP, or Github won&#8217;t be able to notify you of changes). But not yet! First you have to secure Jenkins with a password.</p>
<p>Open your browser and point it at <tt>http://localhost:8080</tt> (your Mac&#8217;s Bonjour name is fine as well, as will be your external domain name or IP, when you later set up the port forward). And after a short wait you&#8217;ll get to Jenkins&#8217; front page. There&#8217;s a breadcrumb bar at the top which pops up a little menu if you mouse over the initial <i>Jenkins</i> breadcrumb:</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/Jenkins-front-page.png" alt="Jenkins front page" title="Jenkins front page.png" border="0" width="600" height="274" /></p>
<p>Under <i>Manage Jenkins</i>, click <i>Configure Global Security</i> and there, check <i>Enable Security</i>, but <b>do not save yet!</b> If you do, Jenkins will happily lock you out. You haven&#8217;t created a user login yet, so you&#8217;ll never be able to get back in again without editing the <tt>config.xml</tt> in the Jenkins user folder and manually deleting the three security-related lines in there.</p>
<p>Next, we&#8217;ll have to set up permissions for the new user login, and then actually create it. So  first tell Jenkins to use <i>Jenkins&#8217;s own user database</i> and <i>Allow users to sign up</i> under <i>Security Realm</i>. Then check <i>Matrix-based security</i> and type whatever user name you want into the little <i>User/group to add:</i> field and click <i>Add</i>. Then make sure that all checkboxes are checked for this user login, all the way to the right, and all are off for &#8220;Anonymous&#8221;.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/Screen-Shot-2013-04-06-at-00.20.36.png" alt="Screen Shot 2013 04 06 at 00 20 36" title="Screen Shot 2013-04-06 at 00.20.36.png" border="0" width="600" height="572" /></p>
<p>Now that that&#8217;s done, you can save. Then click <i>Sign up</i> in the upper right and sign up under the user name you just gave all the permissions to. Yay! We have a valid user! Now go and turn off the <i>Allow users to sign up</i> checkbox again so nobody else makes themselves an account on <i>your</i> server.</p>
<h3>Git support</h3>
<p>By default, Jenkins only does SVN. But it has a nice big list of plug-ins that you can easily install. Go to the menu, <i>Manage Jenkins</i> &gt; <i>Manage Plugins</i> and go on the <i>Available</i> tab. There&#8217;s a boatload of plugins there, but we only care about one for now: <i>Github Plugin</i>. Find it (there are a few with similar names) and install it. Check the box to restart after the installation.</p>
<p>If you&#8217;re curious about a plugin, just click its name. It will show a web site with documentation and setup instructions. Installing a plugin means that its checkboxes and text boxes show up in the <i>Configure System</i> section and each job&#8217;s <i>Configure</i> section. So let&#8217;s go to <i>Configure System</i>.</p>
<p>Take note of the <i>Home directory</i> mentioned at the top. This is where you&#8217;ll later be installing your Github certificates so Jenkins can check out code. Also, since you want your Jenkins externally accessible, scroll down to <i>Jenkins Location</i> and enter your external URL or static IP as the <i>Jenkins URL</i> there.</p>
<p>Between those two is a <i>Git</i> category. Click the lone <i>Git installations&#8230;</i> button there. If you installed the Xcode command line tools as mentioned, you will <i>not</i> see a red error message here and it will have found git in the default location. Otherwise, set up the search paths to point wherever you have git installed.</p>
<p>Now go to <i>Github Web Hook</i> and check <i>Let Jenkins auto-manage hook URLs</i> and enter your username and password in the fields that show up. This is needed so Jenkins can install a script that notifies it whenever a new commit has been pushed, so it&#8217;ll start a build. Click <i>Test Credential</i> to make sure that works.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/GithubWebHook.png" alt="GithubWebHook" title="GithubWebHook.png" border="0" width="600" height="307" /></p>
<h3>Setting up a job</h3>
<p>In Jenkins, everything that is built periodically is represented as a <i>Job</i>. To create a new job, click <i>New Job</i> in the upper left on the Jenkins home page. In  the page that follows, choose a name (but be sure not to use spaces, as this name will be used for the folder in which Jenkins will work, and you&#8217;ll have much less trouble with a shell-script-friendly name), and select &#8220;Build a free-style software project&#8221;.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/JenkinsNewJobPage.png" alt="Jenkins New Job Page" title="JenkinsNewJobPage.png" border="0" width="600" height="364" /></p>
<p>Click <i>OK</i>, and you&#8217;ll get to that job&#8217;s <i>Configure</i> page. Select <i>Git</i> under <i>Source Code Management</i> and enter the URL you see on Github under <i>SSH</i> for your repository twice, once in <i>Github project</i> at the top, and as the <i>Repository URL</i> under <i>Source Code Management</i>:</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/CreateNewJob.png" alt="Creating a new Jenkins Job" title="CreateNewJob.png" border="0" width="600" height="354" /></p>
<p>And finally, check <i>Build when a change is pushed to Github</i> under <i>Build Triggers</i>:</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/Screen-Shot-2013-04-06-at-13.44.07.png" alt="Screen Shot 2013 04 06 at 13 44 07" title="Screen Shot 2013-04-06 at 13.44.07.png" border="0" width="294" height="151" /></p>
<p>Now you&#8217;ve set up Jenkins so it will try to check out your code whenever a change happens. Next, we will have to tell it how to actually build it. We do that in the <i>Build</i> section. Click <i>Add build step</i> and choose <i>Execute shell</i>. You&#8217;ll get a text field in which you can enter a shell script.</p>
<p>This shell script will be run in the folder into which your repository was checked out. This will be a folder named after your job in the <tt>workspace</tt> subfolder of your <tt>jenkins</tt> user&#8217;s home directory. So if your Xcode project file is at the root of the repository, you can just call <tt>xcodebuild</tt> there. If it&#8217;s in a subfolder, you can <tt>cd SubFolderName</tt> and <i>then</i> call <tt>xcodebuild</tt>.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/SetUpJenkinsBuild.png" alt="Set up a Jenkins build" title="SetUpJenkinsBuild.png" border="0" width="600" height="367" /></p>
<p>One problem with Xcode is that it builds into a hardly-predictable folder somewhere in <tt>Library</tt>. Jenkins requires all built files to be inside a job&#8217;s workspace folder, or it won&#8217;t let you archive them. So we need to override it to e.g. build into a <tt>build</tt> folder inside the checkout. To achieve this, we set the <tt>CONFIGURATION_BUILD_DIR</tt> environment variable when we call <tt>xcodebuild</tt>. Note the example screenshot hard-codes the path, while I now use one of Jenkins&#8217; environment variables:</p>
<pre>
BUILD_DEST_PATH=${WORKSPACE}/build
</pre>
<p>The script above, once it is done, grabs the files from the build folder and compresses them into a single archive. This is so we can archive the built file somewhere, for future reference. The actual archiving is done under <i>Post-build Actions</i> where we select <i>Archive the artifacts</i> from the <i>Add post-build action</i> popup. Here again, the path is relative to your job&#8217;s workspace subfolder, so if you want to archive something added to the <tt>build</tt> folder, use a relative path like <tt>build/MySweetApp.tgz</tt>.</p>
<p>Note that Jenkins tries to be helpful and displays red warnings that it can&#8217;t find the file to archive right now. At this point, that&#8217;s OK. There is no checkout, and we&#8217;ve never archived anything. However, later, this can be very helpful in figuring out what&#8217;s gone wrong, if the checkout works, but building fails or so.</p>
<p>Done? Then save. You could also click <i>Build Now</i> on the left (or the little clock with the green &#8220;run&#8221; arrow on it anywhere next to your newly-created job on the home page), but it would fail. Apart from errors in your script, there would likely be two issues, which you can see in the menu that shows up when you hover the mouse over any failed build and click &#8220;Console Output&#8221; in the menu that shows up:</p>
<ol>
<li> Github will complain that you don&#8217;t have permission/are missing certificates</li>
<li> Xcode will complain you haven&#8217;t accepted its license agreement.</li>
</ol>
<p>Remember when you set up access to Github for the first time and you had to create and install certificates? You&#8217;ll have to do that for your Jenkins user, too. Or you could simply copy the hidden <tt>.ssh</tt> folder in your user directory over into the Jenkins user&#8217;s home folder. Note that this isn&#8217;t e.g. <tt>/Users/Shared/Jenkins/Home</tt> like in the standard installation, but actually one folder up, so you want your certificates in <tt>/Users/Shared/Jenkins/.ssh/</tt>.</p>
<p>Note you&#8217;ll have to</p>
<pre>
sudo cp -R ~/.ssh /Users/Shared/Jenkins/
sudo chown -R jenkins /Users/Shared/Jenkins/.ssh
</pre>
<p>to make the folder accessible to the Jenkins user. If you created a real GUI-user for <tt>jenkins</tt>, you can simply run Xcode once and accept the license agreement once. Alternately, as the error message from <tt>xcodebuild</tt> will tell you, you can do</p>
<pre>
sudo -u jenkins -i
xcodebuild -license
exit
</pre>
<p>To view the license. While you&#8217;re in the license screen, you can skip to the end by typing an uppercase <tt>G</tt> (you&#8217;ve already accepted the license agreement when installing the command line tools from inside Xcode, after all), then type in <tt>agree</tt>, as directed.</p>
<p>If you now click <i>Build Now</i> on Jenkins&#8217;s home page, it should work. The job should show up in the <i>Build Queue</i>, the ball at its left should flash for a while, and the similar ball next to the job in the list of jobs on the home page should be blue. If it is red, click the Job&#8217;s name, and in the <i>Build History</i> on the left mouse over it and choose <i>Console Output</i> to see the log and error messages.</p>
<p>If a build was successful, you can view the archived files (&#8220;artifacts&#8221;) by clicking a job on the home page, and then one of the individual build times listed at the bottom of its page.</p>
<h3>Setting up nightly builds</h3>
<p>If you want to make nightly builds and not just have them in Jenkins, but actually upload them to an FTP server somewhere, you will need the <i>FTP Publisher Plugin</i>. Install it, then go into <i>Manage Jenkins</i> &gt; <i>Configure System</i> and scroll to the new <i>FTP repository hosts</i> section. You can create a preset for each server you have. Since Jenkins is publicly accessible, I recommend creating a separate user for Jenkins and restricting it to only a <tt>nightlies</tt> folder on the server, and no CGIs. That way, should Jenkins somehow be hacked, people at least can&#8217;t use the password and login to deface the rest of your server (even though they *can* replace the downloads).</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/FTPServerSettings.png" alt="FTP Server settings" title="FTPServerSettings.png" border="0" width="600" height="320" /></p>
<p>Once you&#8217;ve added your server, create a new job (e.g. <tt>MySweetAppNightly</tt>, but this time check <i>Copy existing Job</i> and type in the name of your regular CI job as the template (e.g. <tt>MySweetAppCI</tt>). Then just add a new action to <i>Post-build Actions</i>, by choosing <i>Publish artifacts to FTP</i> from the <i>Add post-build action</i> popup. Select your server from the <i>FTP site</i> popup and write the relative path name of the TGZ archive you set up in <i>Files to upload</i> (in our example, that would have been <tt>build/MySweetApp.tgz</tt>). Leave the <i>Destination</i>-field empty, unless you want to upload into a subfolder of the folder you set up in <i>System Configuration</i>. If you are building into a subfolder (like in our example <tt>build/MySweetApp.tgz</tt>), you may also want to check <i>Flatten files</i>, or it will upload into a subfolder of the same name on the server.</p>
<p>Now, what this would do right now is upload every change to the FTP server. The server would be strained unnecessarily if your application contains large assets. We want a nightly build. How do we do this? We scroll up to <i>Build Triggers</i>, turn off <i>Build when a change is pushed on Github</i>, and check <i>Poll SCM</i>. Now, we could just pick <i>Build periodically</i>, which is almost identical, but the advantage of <i>Poll SCM</i> is that it won&#8217;t build and upload if nothing has changed since the last build. (It would also be the right option if you host somewhere else than Github and can&#8217;t use the plugin and don&#8217;t want to write your own post-commit hook.</p>
<p>Click the question mark next to the <i>Schedule</i> text field to see the syntax, it is pretty much like cron. I picked 4 AM at night, every day of the week. That&#8217;s a time where I&#8217;m usually not in the middle of a series of check-ins, so chances are this should build.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/BuildTriggersJenkinsNightly.png" alt="Jenkins Build Triggers for Nightlies" title="BuildTriggersJenkinsNightly.png" border="0" width="369" height="277" /></p>
<p>If you hardcoded the path in the <i>Build</i> section, be sure to rename the job in the path there, then save and click <i>Build Now</i> to generate and upload your first nightly build.</p>
<h3>Getting notified</h3>
<p>Of course, all of this would be pretty pointless if we had to check Jenkins after every commit. Luckily, Jenkins can e-mail you. You need an e-mail account somewhere (I recommend creating one dedicated to Jenkins, again for security reasons, but any old Hotmail account would work). Scroll to &#8220;E-Mail Notifications&#8221; in <i>Configure System</i> and click the <i>Advanced</i> button, check <i>Use SMTP Authentication</i>, then enter the same user name, password and SMTP server you would specify to use this account from Mail.app or another e-mail client. Check <i>Use SSL</i> if your mail hoster supports that.</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/04/AdvancedEMailJenkins.png" alt="Advanced E-Mail Notifications" title="AdvancedEMailJenkins.png" border="0" width="576" height="341" /></p>
<p>Then check <i>Test configuration by sending test e-mail</i> and enter whatever e-mail addres you want to send a test e-mail to in <i>Test e-mail recipient</i> and click <i>Test configuration</i>. If you mis-configured something, you&#8217;ll get Java throwing up backtraces in red all over your window. Enjoy.</p>
<p>Now, all that&#8217;s left is adding a <i>E-mail Notification</i> Post-build action to each job. Happy continuous integration, and a happy new year.</p>
<p>I also installed the <i>Twitter plugin</i> and added that as a Post-build action to notify me whether the build is broken. It is pointed at a protected Twitter account that only I can follow. You have to run a little Java command-line app to get the API access tokens needed for Jenkins to talk to Twitter, and paste those into text fields on Jenkins&#8217; <i>System Configuration</i>, but that&#8217;s as complicated as it gets.</p>
<h3>Certificates and DeveloperID Builds</h3>
<p>If you want to build your Mac executables for distribution outside the Mac app store, you will need to log into your Jenkins user and open Xcode, and there go into the <i>Organizer</i>. Click <i>Refresh</i> in the <i>Provisioning Profiles</i> section (click OK in any App Store certificates not existing error messages it may put up if you only want to go outside the MAS, or you work Mac-only and not iOS).</p>
<p>Next, click your team. If it says there are no private certificates across the top, go to a Mac that has all your certificates already set up for development, and in the <i>Organizer</i> choose <i>Editor</i> > <i>Developer Profile</i> > <i>Export Developer Profile&#8230;</i> to export your private keys as a password-protected <tt>.developerprofile</tt> file. Copy that file over to the Jenkins user and double-click it there, and Xcode will ask for the password and install your certificates.</p>
<p>Now, verify that everything works: Open the project you want to build for developer ID. Go into the <i>project</i>&#8216;s build settings and set the <i>Code Signing</i> setting to your <i>Developer ID Application</i> certificate. Build the project, clicking <i>Always allow</i> if Xcode asks for permission to use your private key to sign the application. If the build fails with an error like &#8220;timestamps differ by 205 seconds &#8212; check your system clock Command /usr/bin/codesign failed with exit code 1&#8243;, you probably dawdled too long in the confirmation dialog. Just build again and it should work.</p>
<p>If <tt>codesign</tt> fails trying to sign a file that doesn&#8217;t exist, you probably have a target that doesn&#8217;t produce a file, like a target that runs a shell script to generate a header containing the build number. Since we&#8217;re overriding the code signing setting for the entire project, it will try to sign that nonexistent output file. One way to satisfy it is to add a line like <tt>touch ${CODESIGNING_FOLDER_PATH}</tt> to the end of your script, which will create an empty file for <tt>codesign</tt> to sign.</p>
<p>Now that we know you have code signing set up correctly, we simply modify the call to <tt>xcodebuild</tt> in the job you want to have signed for Developer ID:</p>
<pre>
security unlock-keychain -p 's3kr1tp4ssw0rd' ~/Library/Keychains/login.keychain
xcodebuild CONFIGURATION_BUILD_DIR=$BUILD_DEST_PATH  \
  CODE_SIGN_IDENTITY="Developer ID Application: Joe Shmoe" \
  -configuration Release \
  clean build
</pre>
<p>The first call to <tt>security unlock-keychain</tt> does just that: Give xcodebuild running under Jenkins access to the keychain containing the keys it needs for code signing. Here you need to specify the keychain&#8217;s password, which is not a very secure thing to do, but can&#8217;t really be avoided in this case. At some point, the server *will* need access to your keys to build.</p>
<p>For a tiny bit of extra peace of mind, you might want to change the password of your keychain to be different from the account&#8217;s login password using the <i>Keychain Access</i> application. That way, if someone somehow manages to see this script and the password to the keychain, they still can&#8217;t log into your build tester to actually use it.</p>
<p>Alternately, you could run the Jenkins server that is exposed to the outside and manages the job on a different Mac (or at least as a different user?) than the actual build server. Jenkins allows that, so you can e.g. have one Jenkins web interface to build Mac, Windows and Unix software.</p>
<p>The second call is the same as our previous <tt>xcodebuild</tt> call, with three parameters added:</p>
<ol>
<li>The first one does in script what we did manually for testing in the GUI: It overrides the &#8220;Code Signing:&#8221; build setting with the Developer ID certificate (Insert <i>your</i> name here).</li>
<li>The second one makes sure we don&#8217;t build with whatever configuration was last set, but instead make a release build, with optimizations and such. You could also specify that for other cases, if you wanted, to make sure e.g. stuff you remove from release builds doesn&#8217;t break the debug builds or vice versa.</li>
<li>The third makes sure we clean before we build. This makes sure you don&#8217;t get any leftover files from a previous build (e.g. script-generated header files), but is also slower than an incremental build. You would probably also want to do this for nightly builds, but probably not for a CI build that gets triggered a lot, unless your project is very small.</li>
</ol>
<h3>Including the job number</h3>
<p>For my nightly builds, I wanted to have a monotonically increasing version number. To add this is fairly easy: Just pass a few more settings overrides to <tt>xcodebuild</tt>:</p>
<pre>
  GCC_PREPROCESSOR_DEFINITIONS="BUILD_NUM=${BUILD_NUMBER} BUILD_MEANS=nightly" \
  INFOPLIST_PREPROCESSOR_DEFINITIONS="BUILD_NUM=${BUILD_NUMBER} BUILD_MEANS=nightly" \
</pre>
<p>The first line includes the build number that Jenkins uses for this job as a #defined constant accessible to your source files. The second does the same for projects that you have set to preprocess their Info.plist file (e.g. to include the build number in the CFBundleVersionString). You can also define other constants, separated by spaces, like <tt>BUILD_MEANS</tt> in this example, to e.g. somewhere display that this is a nightly build. You can provide default values for manual builds in a header that you include in those source files that need them, or in a prefix header for your Info.plist:</p>
<pre>
#ifndef BUILD_NUM
#define BUILD_NUM     0
#endif
#ifndef BUILD_MEANS
#define BUILD_MEANS   manual
#endif
</pre>
<p>And this should cover everything you typically need to do on your new continuous integration Mac.</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/setting-up-jenkins-for-github-and-xcode-with-nightlies/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Universal Procedure Pointers</title>
		<link>http://orangejuiceliberationfront.com/universal-procedure-pointers/</link>
		<comments>http://orangejuiceliberationfront.com/universal-procedure-pointers/#comments</comments>
		<pubDate>Sun, 31 Mar 2013 10:19:15 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=518</guid>
		<description><![CDATA[When Apple announced they&#8217;d be switching from PowerPC to Intel CPUs in 2005, many existing Mac developers were looking at the prospect more calmly than newer arrivals to the platform. After all, Apple had done something similar before, successfully, in the mid-nineties: The switch from the 68000 CPU to the PowerPC CPU. One of the &#8230;  <a href="http://orangejuiceliberationfront.com/universal-procedure-pointers/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>When Apple announced they&#8217;d be switching from PowerPC to Intel CPUs in 2005, many existing Mac developers were looking at the prospect more calmly than newer arrivals to the platform. After all, Apple had done something similar before, successfully, in the mid-nineties: The switch from the 68000 CPU to the PowerPC CPU.</p>
<p>One of the differences to 2005&#8242;s switch, however, was that Apple permitted mixing of PowerPC and 68000 code <i>within the same application</i>. To achieve that, a new &#8220;Mixed Mode Manager&#8221; was introduced, that took care of switching between executing raw PowerPC code and emulating 68000 CPU instructions. The linchpin of this manager were <i>Universal Procedure Pointers</i>, or UPPs, for short (sometimes also called <i>Routine Descriptors</i>).</p>
<h3>Universal Procedure Pointers</h3>
<p>A UPP was a simple data structure that described the calling conventions and location of a PowerPC function in RAM, and started with a 68000 instruction. This data structure could be handed to any system function where it expected a callback, and could be executed by 68000 code just like a function pointer.</p>
<p>The instruction at the start of the UPP simply contained a jump (think function call, or <tt>goto</tt>) to a function that recorded the address of the UPP and stopped/started the 68000 emulator.</p>
<p>This meant that Apple only had to port the very foundations of the operating system to PowerPC for the initial roll-out. Applications like the <i>Finder</i>, or <i>window/control definition functions</i> (WDEFs and CDEFs, little code modules that took care of drawing the frame around a window or custom views) could remain 68000 code, and could be ported selectively as needed.</p>
<p>This also meant that plug-ins written for a 68000 application could be loaded and launched by a PowerPC application. All it had to do was, instead of calling the plug-in&#8217;s main function directly (which would crash, because it contained 68000 instructions, not PowerPC instructions), it would call the <tt>CallUniversalProc</tt> function.</p>
<p>The <tt>CallUniversalProc</tt> function would look at the start of the function pointer given. PowerPC plug-ins effectively contained a UPP at the start. From the address of the function it jumped to, the Mixed Mode Manager could see that this was already PowerPC, and just jump over the UPP to where the PowerPC code lay, without having to load and run the 68000 emulator, which only got chosen if the function didn&#8217;t begin with a UPP.</p>
<p>Also, a 68000 application running in emulation on a PowerPC Mac was able to load a PowerPC plugin. It would simply try to execute the UPP, whose first bytes were the jump instruction telling the Mixed Mode Manager to switch back to PowerPC and run it directly.</p>
<h3>Fat binaries &#8211; universal apps before universal apps</h3>
<p>It was trivial to create an application where the same file ran both on old and new Macs: 68000 executables contained their code in &#8216;CODE&#8217; resources in their resource fork. PowerPC applications had their code in the data fork of the application file, plus a &#8216;cfrg&#8217; (&#8220;code fragment&#8221;) resource with some information about the code (e.g. an offset, so you could have other data in the data fork besides code, which especially games on 68000 liked to do). So a 68000 Mac would simply ignore the data fork and &#8216;cfrg&#8217; resource, while an PowerMac would look for it, and only if it failed to find one start the emulator and run the 68000 code.</p>
<p>This meant that, in those days, compilers simply built a 68000 and a PowerPC version of the application, then copied the &#8216;CODE&#8217; resources from the 68000 application into the PowerPC application. Presto! Fat binary for both architectures!</p>
<p>But that wasn&#8217;t all: It was also possible to create UPPs (and thus plug-ins) that were &#8220;fat&#8221;: They contained both PowerPC and 68000 code. Depending on what architecture you were running under, the Mixed Mode Manager would simply jump to the right offset in your plug-in resource, which contained both versions of your code.</p>
<p>Of course, all this mucking about with UPPs meant that you had to allocate/free memory for a UPP for each function you wanted to pass to a system API. And you had to keep that memory around as long as that system call needed it.</p>
<p>For plug-ins, this involved some additional management, as often plug-ins would be dynamically loaded and unloaded during the life of an application. For functions in your application, you usually just stashed the result of <tt>NewRoutineDescriptor</tt> in a global variable and never bothered calling <tt>DisposeRoutineDescriptor</tt>.</p>
<h3>Why no UPPs for Intel?</h3>
<p>So why didn&#8217;t Apple choose to do UPPs again for the Intel switch? Well, apart from political reasons (back then, many application vendors, not just Apple, dragged their feet porting their Mac applications to PowerPC, meaning Macs spent most of their cycles emulating old code instead of overtaking the competition), PowerPC and Intel differed in the way they stored numbers in memory.</p>
<p>The PowerPC CPU actually supported running both in <i>big endian</i> like the 68000 and <i>little endian</i> like Intel CPUs. This came in handy when switching from 68000, because the PowerPC CPU was simply told to run big endian, and both PowerPC and 68000 code now stored their data the same way.</p>
<p>But of course the Intel CPU didn&#8217;t have that switch. And since an emulator only knows about raw bytes, the PowerPC emulator (&#8220;Rosetta&#8221;) in Intel Macs could not transparently convert the stored bytes. So it was decided to not allow mixing of PowerPC or Intel code at all. There would only be a tiny bit of translation at the point when a PowerPC application called into the system.</p>
<p>If an application had plug-ins that might still be written in PowerPC code, it could not load them. You had to run a PowerPC version of the application to run your PowerPC plug-ins in, or the Intel version to run your Intel plug-ins (Of course, there were universal binaries that packaged those two versions up in the same file).</p>
<p>Though the QuickTime media playback library found a nice workaround for this during another switch, from 32-bit to 64-bit: It simply launches a separate, hidden background process that is 32 bit. That process can load any old legacy plug-ins, QuickTime running in a 64-bit application can pipe the data to be en-/decoded to that process, and that process sends it back when it&#8217;s done. This is not optimal, but can be surprisingly fast because it uses Unix shared memory and Mach messages.</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/universal-procedure-pointers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Common Cocoa Coding Patterns: NSError returns</title>
		<link>http://orangejuiceliberationfront.com/common-cocoa-coding-patterns-nserror-returns/</link>
		<comments>http://orangejuiceliberationfront.com/common-cocoa-coding-patterns-nserror-returns/#comments</comments>
		<pubDate>Sun, 24 Mar 2013 14:19:25 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Common Cocoa Coding Patterns]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=580</guid>
		<description><![CDATA[Error reporting wasn&#8217;t something Cocoa did in much detail in the early days. There were nil return values instead of objects, or a BOOL that was YES on success. C didn&#8217;t have exceptions, and by the time ObjC got &#8220;fake&#8221; exceptions based on the longjmp() mechanism, all wrapped up nicely in NSException and NS_DURING/NS_HANDLER/NS_ENDHANDLER macros, &#8230;  <a href="http://orangejuiceliberationfront.com/common-cocoa-coding-patterns-nserror-returns/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://orangejuiceliberationfront.com/wp-content/uploads/2013/03/SadiMac.jpg"><img src="http://orangejuiceliberationfront.com/wp-content/uploads/2013/03/SadiMac.jpg" alt="A sad iMac" width="480" height="359" class="aligncenter size-full wp-image-582" /></a></p>
<p>Error reporting wasn&#8217;t something Cocoa did in much detail in the early days. There were <tt>nil</tt> return values instead of objects, or a <tt>BOOL</tt> that was <tt>YES</tt> on success.</p>
<p>C didn&#8217;t have exceptions, and by the time ObjC got &#8220;fake&#8221; exceptions based on the <tt>longjmp()</tt> mechanism, all wrapped up nicely in <tt>NSException</tt> and <tt>NS_DURING</tt>/<tt>NS_HANDLER</tt>/<tt>NS_ENDHANDLER</tt> macros, most of the framework API had already been written and it would have been too much work to make all of it work with exceptions and adapt all applications to watch for exceptions in error situations. So they were reserved mostly for <i>Distributed Objects</i> (where an additional error return wasn&#8217;t possible) and programming errors.</p>
<p>But with the release of Safari and WebKit in 2003, someone at Apple realized they needed more detailed and standardized error information, and introduced the <tt>NSError</tt> class. <tt>NSError</tt> is a simple container object for any error code you might encounter on your Apple device, plus a dictionary for any other info like an error message.</p>
<p>Error codes are not unique across all the libraries, frameworks and system services that are on your device, so each error <tt>code</tt> is also identified by its <tt>domain</tt>, an arbitrary string constant. For example, Mac OS X offers the <tt>NSCocoaErrorDomain</tt>, <tt>NSOSStatusErrorDomain</tt>, <tt>NSPOSIXErrorDomain</tt> and <tt>NSMachErrorDomain</tt> error domains, which let you wrap Cocoa framework error codes, Carbon/CoreServices error codes, standard Unix error codes and kernel errors unambiguously, all by wrapping them in an <tt>NSError</tt>. And you can make up your own for your application, library, and even for a single class. Whatever logical unit of encapsulation makes the most sense.</p>
<p>Most <tt>NSError</tt>s are returned as a <i>return parameter</i>. This has the advantage that methods that already have a return value can still be implemented as they were before the arrival of <tt>NSError</tt>, and can return <tt>nil</tt> to have an entire chained expression collapse. E.g., a fictional</p>
<pre>
NSError    theErr = nil;
ULIObject  obj = [[[ULIObject allocGivingError: &#038;theErr] initGivingError: &#038;theErr] autoreleaseGivingError: &#038;theErr];
</pre>
<p>can fail at any of the three calls and return <tt>nil</tt>, and none of the subsequent messages will be sent, nor will they touch <tt>theErr</tt>.</p>
<p>However, one thing Apple tells us is that we shouldn&#8217;t look at <tt>theErr</tt> above unless <tt>obj</tt> is <tt>nil</tt>. Why is that? Well, imagine a possible implementation of our fictional <tt>autoreleaseGivingError:</tt>:</p>
<pre>
-(id) autoreleaseGivingError: (NSError**)outError
{
    ULIAutoreleasePool* currentPool = [ULIAutoreleasePool _currentPoolGivingError: outError];
    if( currentPool == nil )
        currentPool = [NSAutoreleasePool _createBottomPool];
    if( currentPool == nil )    // Still couldn't create?
    {
        // Hand on whatever error _currentPoolGivingError: had.
        return nil;
    }
    
    [currentPool addObject: self];
    return self;
}
</pre>
<p>Our fictional internal <tt>_currentPoolGivingError:</tt> method here might return <tt>nil</tt> and give us an <tt>NSError</tt> when there is no pool in place yet.</p>
<p>But in the most common case, we will be able to recover from this error by creating the pool <a href="#poolFootnote"><sup><font size="-1">1</font></sup></a>.</p>
<p>So in most cases, we&#8217;ll just create the pool and add the object to it. If callers look at <tt>theErr</tt> in such a situation, they will see the error object put there by <tt>_currentPoolGivingError:</tt>, from which we recovered. So they will see an error where none occurred.</p>
<p>And that, kids, is why you always check the return value, and not just the error parameter.</p>
<p><font size="-1"><a name="poolFootnote"><sup><font size="-1">1</font></sup></a>) This is nonsense in real life, because nobody would ever release this bottom pool and we&#8217;d have a quiet leak, but let&#8217;s just assume in our example&#8217;s world <tt>ULIRunLoop</tt> will release this bottom pool once it regains control, as part of a lazy-allocation-of-pools scheme.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/common-cocoa-coding-patterns-nserror-returns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WWDC 2012 predictions</title>
		<link>http://orangejuiceliberationfront.com/wwdc-2012-predictions/</link>
		<comments>http://orangejuiceliberationfront.com/wwdc-2012-predictions/#comments</comments>
		<pubDate>Sat, 09 Jun 2012 16:26:28 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=559</guid>
		<description><![CDATA[Now, I don&#8217;t have any clue about anything, nor inside knowledge, and I have a terrible track record at predicting Apple&#8217;s actions, but because it&#8217;s fun and almost a tradition, here&#8217;s my predictions for WWDC: Mac OS X 10.8 &#8211; Pretty much as you&#8217;d expect, no big new stuff. iOS 6 &#8211; The poster&#8217;s been &#8230;  <a href="http://orangejuiceliberationfront.com/wwdc-2012-predictions/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://orangejuiceliberationfront.com/wp-content/uploads/2012/06/phil_schiller_mac_pro.jpg"><img class="aligncenter size-full wp-image-607" alt="phil_schiller_mac_pro" src="http://orangejuiceliberationfront.com/wp-content/uploads/2012/06/phil_schiller_mac_pro.jpg" width="480" height="360" /></a></p>
<p>Now, I don&#8217;t have any clue about anything, nor inside knowledge, and I have a terrible track record at predicting Apple&#8217;s actions, but because it&#8217;s fun and almost a tradition, here&#8217;s my predictions for WWDC:</p>
<ul>
<li>Mac OS X 10.8 &#8211; Pretty much as you&#8217;d expect, no big new stuff.</li>
<li>iOS 6 &#8211; The poster&#8217;s been leaked. I have no clue what&#8217;s in it.</li>
<li>No product-line-wide Mac revision. Maybe individual ones, but not all of them at once. <span style="text-decoration: line-through;">My guess is the Mac Pro will die (but not at WWDC, that&#8217;s too many Mac pro users in one place), and iMac and Mac mini will get beefed up now that they can&#8217;t cannibalize Mac Pro sales anymore and Thunderbolt can be a replacement for most expansion slot devices. If it&#8217;s the MacBook (Pro) and MacBook Air, the lines will be unified into flat notebooks without optical drives.</span></li>
<li><span style="text-decoration: line-through;">App Store and SDK for the Apple TV.</span></li>
<li>No new iPhone. The 4S is only 8 months old.</li>
</ul>
<p>Feel free to leave your counter-arguments, predictions, links to your prediction list on your blog etc. in the comments.</p>
<p><b>Update:</b> Struck through the things that didn&#8217;t happen.</p>
<ul>
<li>Yes, the whole product line wasn&#8217;t revised, and, yes, the new MacBook Pro became a MacBook Air as predicted, but the old MacBook Pros are still there, and Apple actually announced a new Mac Pro for next year, and slightly speed-bumped the current ones. I think the general road map I devised for the Mac Pro will still happen, but I obviously didn&#8217;t get it right.</li>
<li>Nothing Apple TV related at all. <i>sniff!</i></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/wwdc-2012-predictions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iPhone 4 3G prepaid data plan for WWDC</title>
		<link>http://orangejuiceliberationfront.com/iphone-4-3g-prepaid-data-plan-for-wwdc/</link>
		<comments>http://orangejuiceliberationfront.com/iphone-4-3g-prepaid-data-plan-for-wwdc/#comments</comments>
		<pubDate>Tue, 05 Jun 2012 07:59:48 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Indie Life]]></category>
		<category><![CDATA[Travel and Linguistics]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=449</guid>
		<description><![CDATA[So, you&#8217;re going to WWDC and you want to have data on your iPhone 4. What to do? Go to an AT&#38;T store, and tell them you want one of their GoPhone pre-paid plans (Type in an SF ZIP code, e.g. 94133, to get to the actual page) There are two monthly (i.e. 1 month, &#8230;  <a href="http://orangejuiceliberationfront.com/iphone-4-3g-prepaid-data-plan-for-wwdc/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><img style="display: block; margin-left: auto; margin-right: auto;" title="SimCard.jpg" src="http://orangejuiceliberationfront.com/wp-content/uploads/2011/06/SimCard.jpg" border="0" alt="SimCard" width="480" height="359" /></p>
<p>So, you&#8217;re going to WWDC and you want to have data on your iPhone 4. What to do?</p>
<ul>
<li>Go to an AT&amp;T store, and tell them you want one of their <a href="http://www.wireless.att.com/cell-phone-service/cell-phone-plans/pyg-cell-phone-plans.jsp">GoPhone pre-paid plans</a> (Type in an SF ZIP code, e.g. 94133, to get to the actual page) There are two monthly (i.e. 1 month, pay again if you need another month) plans that you can get that allow data: the $25 and the $50 monthly plan. You&#8217;ll also need a data package &#8211; they offer 50MB ($5), 200MB ($15) or 1GB ($25). They will want to see some form of ID, make sure you have it.<br/>&nbsp;</li>
<li>Do <em>not</em> tell them it&#8217;s for an iPhone. If your conscience permits, say you don&#8217;t know what phone it is, you&#8217;re getting a hand-me-down from a friend later in the day, or it&#8217;s for an Android phone, or whatever. They will warn you it won&#8217;t work for an iPhone. <strong>Disclaimer: AT&amp;T give no refunds, so if you buy the card and it really doesn&#8217;t work, it&#8217;s on your own head if that should be true one day.</strong><br/>&nbsp;</li>
<li>They will give you an orange, regular-size SIM. Get a ruler, a soft pencil (HB will do), and a pair of scissors. Grab this fantastic template (the PDF link is broken, grab the JPEG that you can click to zoom in and print at 110%): <a href="http://my-iphone-ipad-blog.blogspot.com/2010/08/convert-sim-to-micro-sim.html">My iPhone iPad blog: Convert SIM to micro-SIM</a>. Then mark the lines on your SIM card with the pencil and the ruler and cut them using the scissors. It&#8217;s fairly easy, the chip has gotten smaller with the newer SIM cards. Don&#8217;t cut the chip! <strong>Again, if you break your card doing this, that&#8217;s your problem.
<p></strong> </li>
<li>If you put in the card now (you&#8217;ll need a paperclip or so to open the SIM tray), it should already be recognized. I haven&#8217;t actually verified it myself, but the site above says that internet won&#8217;t work (and that&#8217;s what the shop guy says as well). So now you&#8217;ll have to point your iPhone&#8217;s browser at a special web site and <a href="http://www.unlockit.co.nz/">create the proper APN settings file</a> for it and activate that. You&#8217;ll need hotel Wi-Fi or so to do that part. Alternately, you can use the iPhone configuration tool from Apple and create a .mobileconfig file with the APN <tt>wap.cingular</tt>, APN user name <tt>wap@cingulargprs.com</tt> and password <tt>CINGULAR1</tt>.</li>
</ul>
<p>Once I did that, it worked fine for me. Again, I make no warranties. If you break the card, nuke your credit, fry your iPhone or get sued by Lodsys for doing this, that&#8217;s your own risk.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/iphone-4-3g-prepaid-data-plan-for-wwdc/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>View-based NSTableViews: Row 1 should be in the valid visible section</title>
		<link>http://orangejuiceliberationfront.com/view-based-nstableviews-row-1-should-be-in-the-valid-visible-section/</link>
		<comments>http://orangejuiceliberationfront.com/view-based-nstableviews-row-1-should-be-in-the-valid-visible-section/#comments</comments>
		<pubDate>Wed, 14 Mar 2012 09:11:29 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=554</guid>
		<description><![CDATA[With Mac OS X 10.7 &#8220;Lion&#8221;, Apple added a second &#8220;content mode&#8221; to NSTableView: View-based table views. This allows you to simply create your list items as separate views that get reused and reshuffled to simulate scrolling, instead of using the classic approach of &#8220;rubber stamping&#8221; a more lightweight NSCell repeatedly into the window. If &#8230;  <a href="http://orangejuiceliberationfront.com/view-based-nstableviews-row-1-should-be-in-the-valid-visible-section/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><i>With Mac OS X 10.7 &#8220;Lion&#8221;, Apple added a second &#8220;content mode&#8221; to <tt>NSTableView</tt>: View-based table views. This allows you to simply create your list items as separate views that get reused and reshuffled to simulate scrolling, instead of using the classic approach of &#8220;rubber stamping&#8221; a more lightweight <tt>NSCell</tt> repeatedly into the window. If you&#8217;ve programmed for iOS before, this is essentially like <tt>UITableView</tt> works, just for the Mac.</i></p>
<p>While this works fairly well most of the time, as of this writing it has one severe bug: Occasionally, a view-based <tt>NSTableView</tt>&#8216;s view hierarchy gets corrupted in some odd way, causing it to hit an assertion and throw an exception. The main message you see in that case is:</p>
<pre>
Row 1 should be in the valid visible section.
</pre>
<p>I don&#8217;t know what exactly happens, but it happens if you call <tt>-reloadData</tt> on your table view too early. Now &#8220;too early&#8221; may sound a little weird, as cell-based <tt>NSTableView</tt>s work just fine, but for example the view-based content mode doesn&#8217;t like getting a <tt>-reloadData</tt> from the <tt>-awakeFromNib</tt> method of the controller that loaded it with its NIB/XIB file.</p>
<p>Doing this early on makes sure that your table view breaks, even if it still seems fine afterwards as long as it is empty. As soon as you add items, however, it croaks. Also, sometimes you don&#8217;t need to call the method directly. Just get someone else to call it for you, e.g. by setting the <tt>automaticallyPreparesContent</tt> property on an <tt>NSArrayController</tt>.</p>
<p><font size="-1"><b>Thanks to:</b><br />
brettper, <i>who filed a reproducible case in Apple&#8217;s bugreporter and posted it on <a href="http://www.openradar.me/10925941" target="_blank">OpenRadar</a>.</i><br />
Jacob Gorban, <i>who made the connection to the NSArrayController issue.</i></font></p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/view-based-nstableviews-row-1-should-be-in-the-valid-visible-section/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A proposal: Categories for C++</title>
		<link>http://orangejuiceliberationfront.com/a-proposal-categories-for-c/</link>
		<comments>http://orangejuiceliberationfront.com/a-proposal-categories-for-c/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 09:37:53 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Language Design]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=541</guid>
		<description><![CDATA[Categories? One of the most useful features I&#8217;ve used in object-oriented programming languages is the &#8220;category&#8221;. A category is a way of adding methods to a class dynamically. Take, for example Objective C&#8217;s &#8220;NSAttributedString&#8221; class. As defined in the Foundation framework, it is simply a string where you can attach key-value pairs to a range &#8230;  <a href="http://orangejuiceliberationfront.com/a-proposal-categories-for-c/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<h2>Categories?</h2>
<p>One of the most useful features I&#8217;ve used in object-oriented programming languages is the &#8220;category&#8221;. A category is a way of adding methods to a class dynamically. Take, for example Objective C&#8217;s &#8220;NSAttributedString&#8221; class. As defined in the Foundation framework, it is simply a string where you can attach key-value pairs to a range of it.</p>
<p>Only a category in the GUI framework AppKit actually defines the methods and constants that define what key to use for &#8220;bold&#8221;, and let you draw such a string to the screen. Yet in everyday use with AppKit, these two disparate parts feel like one homogeneous part. And, more importantly, anyone who wants to write a text-processing command line tool can use NSAttributedString without having to drag in all that unneeded drawing code.</p>
<h2>How C++ objects work</h2>
<p>But C++ does not have this feature. So let&#8217;s come up with an implementation of this concept that a compiler vendor could implement, and that stays true to the core of C++, mainly it&#8217;s compile-time determination of as much as possible. But of course we want to be able to add a category to a system class or a class in another module, and want to define virtual methods in a category, and override them in a category on a subclass. So, of course we want to end up at something that looks like this in C++:</p>
<pre>
category BarSupport : MyObject // extend class MyObject with some methods.
{
    void doBar( MyObject baz );
};
</pre>
<p>and can be called just like any other method on MyObject, e.g.</p>
<pre>
MyObject foo, dodo;
foo.doBar( dodo );
</pre>
<p>If we didn&#8217;t have to support virtual methods, things would be trivial. A non-virtual method call like</p>
<pre>MyObject foo;
foo.doBar(baz);</pre>
<p>compiles to something like</p>
<pre>MyObject_doBar( foo, baz );</pre>
<p>Where the <tt>this</tt> pointer is simply passed in as the first parameter before the first parameter you defined. So all we&#8217;d have to do is tell the parser about these new methods, compile the functions that implement them, and call them.</p>
<p>But virtual methods work differently. First, there is a virtual function table, something like this:</p>
<pre>struct MyObjectVTable
{
    void (*doFoo)( struct MyObject* this ); // defined by user as doFoo(void).
};</pre>
<p>And whenever you define a new class, what it actually does is add a hidden instance variable at the start:</p>
<pre>struct MyObject
{
    struct MyObjectVTable *vtable;
    int                   firstInstanceVariable;
};</pre>
<p>And it declares a global variable containing the vtable once, for all objects created with this class, and stashes it in each new object&#8217;s <tt>vtable</tt> instance variable:</p>
<pre>struct MyObjectVTable gMyObjectSharedVTable = { MyObject_doFoo };

...

// Equivalent code to MyObject* foo = new MyObject :
struct MyObject* foo = malloc(sizeof(struct MyObject));
foo->vtable = &#038;gMyObjectSharedVTable;
MyObject_Constructor( foo );</pre>
<p>Here, <tt>MyObject_doFoo()</tt> is a function just like our
<pre>MyObject_doBar()</pre>
<p> above. But when a virtual method is called, it is done slightly differently:</p>
<pre>foo.vtable->doFoo( &#038;foo );</pre>
<p>This means that a subclass that wants to override <tt>doFoo()</tt> can provide its own <tt>gMySubclassSharedVTable</tt> that is also a <tt>struct MyObjectVTable</tt>, but contains a pointer to MySubclass_doFoo instead, and thus overrides the behaviour of <tt>doFoo()</tt> for all MySubclass objects. And if it wants to define additional virtual methods in its subclass, it can simply declare a <tt>struct MySubclassVTable</tt> that starts with the same fields in the same order as <tt>struct MyObjectVTable</tt>, and contains the additional methods after that. That way, anyone who expects an object for the base class doesn&#8217;t even have an inkling that there is more stuff after the methods it knows.</p>
<h2>Applying that to Categories</h2>
<p>Our categories also want to add methods, but the problem is we can&#8217;t just add new fields to the struct. The system classes like std::string have already been compiled, and we can&#8217;t just change their code to add these ivars. But what we can do is declare a parallel class hierarchy for our categories. So, first we declare a struct for our category:</p>
<pre>struct MyObject_BarSupportVTable
{
    void (*doBar)( struct MyObject* this, struct MyObject* baz );
};</pre>
<p>Then we extend the vtable to list categories:</p>
<pre>struct CategoryEntry
{
    MyObject_BarSupportVTable* catVTable; // Simplified, each category's vtable is really a different struct.
};

struct MyObjectVTable
{
    struct CategoryEntry *cattable;
    void (*doFoo)( struct MyObject* this ); // defined by user as doFoo(void).
};</pre>
<p>When a class is first built, the <tt>cattable</tt> array is empty, but as soon as someone declares a category, it gets added to that list. We just add some initialization code at the start of main() that mallocs the list. But how do we look up the vtable for a category? We could store its name, but then we&#8217;d have to loop over this list on each call and compare category names until we find it. How can we make that more efficient?</p>
<p>Simple: When we add the category to the class, we remember the index into the array where we added this category in the list, cache it in a global variable <tt>int gMyObject_BarSupport_Index;</tt> and then we can call a virtual method in a category like:</p>
<pre>foo.vtable->cattable[gMyObject_BarSupport_Index].catVTable->doBar( &#038;foo, baz );</pre>
<p>Again, a subclass-category that overrides this method can just provide its own doBar method in the <tt>struct MyObject_BarSupportVTable</tt>.</p>
<h2>The cost of categories</h2>
<p>Of course this means that, just like with C++ virtual methods, and a bit more so, you pay a price for calling a virtual method in a category. You also pay with a little bit of overhead at startup, when the categories are added to the base class vtable. And just like with C++ virtual methods, to override a category method in a subclass, you have to know that the category exists on the base class. And if your program uses threads and you load a dynamic library that contains a category on a system class, bad things could happen while the category lists change under your running code&#8217;s rear.</p>
<p>Another gotcha with this approach is that the category list has to be built from the base class to the subclasses, because once a subclass locks down an index in the table for its first category vtable, you can&#8217;t add another category to the base class (it would have the index of the subclass&#8217;s category). But even that can be fixed:</p>
<p>We can just give every subclass its own categories table. So it only deals with the base class table when it wants to call a method inherited from the base class. E.g.:</p>
<pre>struct MySubclassVTable
{
    <span style="color: blue;">struct CategoryEntry *cattable;</span>
    void (*doFoo)( struct MyObject* this ); // defined by user as doFoo(void).
    <span style="color: blue;">struct CategoryEntry2 *cattable2;</span>
    void (*doBar)( struct MyObject* this, struct MyObject baz ); // defined by user as doBar( MyObject baz ).
};</pre>
<p>And now, calling a method in a category specific to the subclass simply goes through the cattable2.</p>
<p>Thoughts, suggestions, additional runtime geekery?</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/a-proposal-categories-for-c/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How to build a good restaurant web site</title>
		<link>http://orangejuiceliberationfront.com/how-to-build-a-good-restaurant-web-site/</link>
		<comments>http://orangejuiceliberationfront.com/how-to-build-a-good-restaurant-web-site/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 11:24:28 +0000</pubDate>
		<dc:creator>uliwitness</dc:creator>
				<category><![CDATA[Usability]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://orangejuiceliberationfront.com/?p=532</guid>
		<description><![CDATA[The typical restaurant web site, I&#8217;ve found, is completely useless and a waste of money. Here&#8217;s a short list why: Most of them are 100% Flash. Nobody who owns a smart phone can view them. At all. So if I&#8217;m on the road and want to know whether your restaurant is open, I can&#8217;t see &#8230;  <a href="http://orangejuiceliberationfront.com/how-to-build-a-good-restaurant-web-site/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>The typical restaurant web site, I&#8217;ve found, is completely useless and a waste of money. Here&#8217;s a short list why:</p>
<ul>
<li>Most of them are 100% Flash. Nobody who owns a smart phone can view them. At all. So if I&#8217;m on the road and want to know whether your restaurant is open, I can&#8217;t see that, just because you wanted a photo slideshow with crossfades.<br />&nbsp;</li>
<li>Most of them are missing the opening hours and/or the address. Those that have them often hide them in lots of prose. Someone on the road with their phone will want to know that information first.<br />&nbsp;</li>
<li>Most of them are missing the menus. While some of them have the permanent menu, particularly the daily lunch deals or weekly changing menus are why a prospective customer might come back to your web site.<br />&nbsp;</li>
</ul>
<p>Of course, everyone can moan and complain, so here&#8217;s my short and sweet summary of how to make a <strong>good</strong> web site for a restaurant:</p>
<ul>
<li>Put the following on your front page: Your <strong>address</strong> (including the <em>city</em> and <em>country</em>, this is the <em>inter</em>net, after all!), your <strong>opening hours</strong>, and a <strong>tag line</strong> like &#8220;Greek taverna&#8221; or &#8220;Italian kitchen&#8221; or &#8220;exclusive 4-course dining in separés&#8221; or something else that helps a first-time visitor immediately get an idea of your restaurant.<br />&nbsp;<br />And no, your address as the &#8220;legally responsible party&#8221; on your web site&#8217;s imprint page doesn&#8217;t count. That could be an office building for a restaurant chain. Make sure it&#8217;s clear where to go. Put a small picture of your front entrance on there so they recognize it.<br />&nbsp;</li>
<li><strong>Don&#8217;t use Flash.</strong> People on cell phones can&#8217;t see Flash, they just get a lego brick icon and that&#8217;s it.<br />&nbsp;<br />If someone is in your general area and wants to know where to go, they will call up your site on their smart phone to check the opening hours. Make it easy for them. You&#8217;re wasting money if half your interested customers can&#8217;t see your site.<br />&nbsp;</li>
<li><strong>Put your daily menu and specials on the site.</strong> This is easier than it sounds. You don&#8217;t have to pay a web designer every time. Pay them to make you <em>one</em> editable page where you can just log in with a password and edit the text from any browser. You probably already type up the daily menu and print it every day. Just copy it over there, click &#8220;Save&#8221; and anyone on the internet (potential customers sitting at work thinking where to go for lunch together, for instance) can immediately see what you have to offer.<br />&nbsp;<br />Your permanent menu is nice, but people who&#8217;ve been at your place a couple times probably have a general idea what&#8217;s on it already. The specials change daily or weekly, <em>everyone</em> has to look those up.<br/>&nbsp;</li>
<li><strong>Bonus points:</strong> Include a phone number (or even better, a web form) where people can make reservations. Ideally they&#8217;d be hooked up to your reservation system and immediately give feedback. Otherwise, make sure you check your e-mail often and confirm reservations in a timely manner.<br />&nbsp;<br/>If you want to provide prose or an image gallery, put them on extra pages, so cell phone visitors don&#8217;t have to download all of that over a mobile connection.<br />&nbsp;<br />And finally: Pay for a professional web designer and professional photographer. It will show in the end result.</li>
</ul>
<p>That&#8217;s my short list of how to make a good, useful restaurant web site. I hope it will help restaurant owners get the right thing from their web designers.</p>
]]></content:encoded>
			<wfw:commentRss>http://orangejuiceliberationfront.com/how-to-build-a-good-restaurant-web-site/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

 Served from: orangejuiceliberationfront.com @ 2013-05-20 05:47:19 by W3 Total Cache -->