<?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>Light Year Software &#187; Mac</title>
	<atom:link href="http://lightyearsoftware.com/tag/mac/feed/" rel="self" type="application/rss+xml" />
	<link>http://lightyearsoftware.com</link>
	<description></description>
	<lastBuildDate>Thu, 10 May 2012 13:56:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Your Own Free L2TP/IPsec VPN</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F05%2Fyour-own-l2tpipsec-vpn%2F&#038;seed_title=Your+Own+Free+L2TP%2FIPsec+VPN</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F05%2Fyour-own-l2tpipsec-vpn%2F&#038;seed_title=Your+Own+Free+L2TP%2FIPsec+VPN#comments</comments>
		<pubDate>Tue, 08 May 2012 15:52:16 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=982</guid>
		<description><![CDATA[If you have a VPS for web applications, it&#8217;s relatively easy to set up your own L2TP/IPsec VPN for use by Mac OS X or iOS clients. When you&#8217;re away from your home or office on someone else&#8217;s Wi-Fi (at coffee shops or a conference), it&#8217;s a good idea to use a VPN to keep [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a VPS for web applications, it&#8217;s relatively easy to set up your own L2TP/IPsec VPN for use by Mac OS X or iOS clients. When you&#8217;re away from your home or office on someone else&#8217;s Wi-Fi (at coffee shops or a conference), it&#8217;s a good idea to use a VPN to keep your network use secure and private. While there are free VPN services (<a href="http://www.getcloak.com/">Cloak</a> is one), the free plan is time and bandwidth limited. You can pay to lift the time limit, but why pay for another service if you can piggyback on another you already have?<span id="more-982"></span></p>
<p>I said it was relatively easy, but the truth is that it took me several hours to get everything configured properly. There are a few guides out there, but none that succinctly explained everything correctly. This is my attempt to rectify that problem.</p>
<p>This guide also assumes your server is running a Linux distribution and the clients are Mac OS X or iOS. I don&#8217;t have Windows clients, so I can&#8217;t say if this will work for them. I use Debian Linux; adjust package installation and configuration file paths if you use something else. My configuration is typical for &#8220;road warriors,&#8221; meaning clients can connect from any IP address and may be behind a NAT.</p>
<p>Install Openswan (IPsec userspace daemon) and xl2tpd (L2TP daemon):</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ sudo aptitude install openswan xl2tpd</pre></div></div>

<p>Edit <tt>/etc/ipsec.conf</tt>. In the <tt>config setup</tt> section, add an exclusion for your internal network to the <tt>virtual_private</tt> line. Mine looks like <tt>%v4:!192.168.1.0/24</tt>. Unless you&#8217;re on an old kernel, change <tt>protostack</tt> from <tt>auto</tt> to <tt>netkey</tt> to squelch a warning. Then add a connection section. Here is mine:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">conn L2TP-PSK
	authby=secret
	pfs=no
	rekey=no
	keyingtries=3
	dpddelay=30
	dpdtimeout=60
	dpdaction=clear
	compress=yes
	left=%defaultroute
	leftprotoport=udp/1701
	right=%any
	rightprotoport=udp/0
	auto=add</pre></div></div>

<p>This says the IPsec connection will authenticate with a pre-shared key (instead of client certificates). DPD is Dead Peer Detection and is needed because iOS clients don&#8217;t tell the server when they disconnect. My settings send DPD keepalives every 30 seconds, and clear connections that don&#8217;t respond after 60 seconds.</p>
<p>Edit <tt>/etc/ipsec.secrets</tt> and add a line similar to this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">1.2.3.4 %any: PSK &quot;put-your-preshared-key-here&quot;</pre></div></div>

<p>Replace <tt>1.2.3.4</tt> with your VPN server&#8217;s public IP address and put your chosen pre-shared key in quotes. This is the secret shared between the server and your clients.</p>
<p>Next, edit <tt>/etc/xl2tpd.conf</tt>. I added the following to mine.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[global]
access control = no
rand source = dev
&nbsp;
[lns default]
ip range = 192.168.1.120-192.168.1.127
local ip = 192.168.1.1
require chap = yes
refuse pap = no
require authentication = yes
name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tp
length bit = yes</pre></div></div>

<p><tt>ip range</tt> is the range of IP addresses from your internal network that you want clients to get an address from. <tt>local ip</tt> is the internal IP address of your server.</p>
<p>Edit <tt>/etc/ppp/options.l2tp</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">ipcp-accept-local
ipcp-accept-remote
ms-dns 192.168.1.1
noccp
name vpn
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
plugin pppol2tp.so
require-mschap-v2</pre></div></div>

<p><tt>ms-dns</tt> is the address of a DNS server on your internal network. <tt>name</tt> is used in the next file.</p>
<p>Finally, add entries to <tt>/etc/ppp/chap-secrets</tt> to set up individual VPN users:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">username	options-name	&quot;password&quot;	192.168.1.1/24
options-name	username	&quot;password&quot;	192.168.1.1/24</pre></div></div>

<p><tt>username</tt> is the client&#8217;s user name and <tt>options-name</tt> must match the <tt>name</tt> parameter from the previous file, <tt>options.l2tp</tt>. The last parameter is the subnet and mask to match this client. It should be the range of your internal network.</p>
<p>On my server, Openswan didn&#8217;t create the links in <tt>/etc/rc?.d</tt> required to start itself when the server boots. <tt>insserv</tt> addresses that:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ sudo insserv ipsec
$ sudo invoke-rc.d ipsec start</pre></div></div>

<p>Finally, you need to allow incoming connections if your server uses a firewall. iptables rules look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">iptables -A INPUT -m state --state NEW -i eth0 -p udp --dport 500 -j ACCEPT
iptables -A INPUT -m state --state NEW -i eth0 -p udp --dport 4500 -j ACCEPT
iptables -A firewall -p esp -j ACCEPT
iptables -A firewall -m policy --dir in --pol ipsec -p udp --dport 1701 -j ACCEPT
iptables -A firewall -i ppp+ -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT</pre></div></div>

<p>This allows UDP traffic on ports 500 (IPsec) and 4500 (NAT-Traversal) and all ESP (IPsec Encapsulating Security Payload) traffic. Additionally, it allows incoming UDP traffic to port 1701 (L2TP) if it&#8217;s wrapped in IPsec. Finally, PPP interfaces are created to pass traffic and we need a rule to permit that.</p>
<p>You can now create L2TP VPN configurations on your Mac and iOS devices, using the values you chose along the way, and you should have a working VPN.</p>
<p>If I have something wrong (it&#8217;s entirely possible I left something out), get in touch and I&#8217;ll fix the post.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F05%2Fyour-own-l2tpipsec-vpn%2F&#038;seed_title=Your+Own+Free+L2TP%2FIPsec+VPN/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PaintCode</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F04%2Fpaintcode%2F&#038;seed_title=PaintCode</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F04%2Fpaintcode%2F&#038;seed_title=PaintCode#comments</comments>
		<pubDate>Wed, 11 Apr 2012 15:11:44 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=861</guid>
		<description><![CDATA[I am not an artist, but a fact of life when creating apps in 2012 is that Apple&#8217;s standard Cocoa controls don&#8217;t provide everything. is perfect for those times when I need a relatively simple icon that can be composed from shapes and I don&#8217;t have the budget to hire a designer. What makes PaintCode [...]]]></description>
			<content:encoded><![CDATA[<p>I am not an artist, but a fact of life when creating apps in 2012 is that Apple&#8217;s standard Cocoa controls don&#8217;t provide everything. <a href="http://click.linksynergy.com/fs-bin/stat?id=b3l3j6su8PM&offerid=146261&type=3&subid=0&tmpid=1826&RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fapp%252Fid507897570%253FpartnerId%253D30">PaintCode</a> is perfect for those times when I need a relatively simple icon that can be composed from shapes and I don&#8217;t have the budget to hire a designer.<span id="more-861"></span></p>
<p>What makes PaintCode different from most vector drawing apps is that it generates code that can be pasted directly into a project. In the 1.0 release, it could export to a couple of graphic formats, but unfortunately not PNG. The 1.0.1 release addresses this, and now I have the choice of generating a simple icon on-the-fly, using the code generated by PaintCode, or exporting to PNG and bundling the files with my app.</p>
<p>Back in January at CUSEC 2012, Bret Victor presented a talk titled <a href="http://vimeo.com/36579366">Inventing on Principle</a>. One of his main points was that it is important for a developer to see immediate feedback as code is changed. For me, PaintCode serves this purpose: if I have a visual effect in mind, I can play with the shapes, shadows, colors and gradients visually to achieve the effect I want, and then look down to see how to do it in code. This greatly shortens the experimentation cycle time.</p>
<p>PaintCode isn&#8217;t cheap, but the time it saves me when I need it makes it worth every penny.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F04%2Fpaintcode%2F&#038;seed_title=PaintCode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Old iPad + Air Display = Awesome</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F03%2Fold-ipad-air-display-awesome%2F&#038;seed_title=Old+iPad+%2B+Air+Display+%3D+Awesome</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F03%2Fold-ipad-air-display-awesome%2F&#038;seed_title=Old+iPad+%2B+Air+Display+%3D+Awesome#comments</comments>
		<pubDate>Mon, 19 Mar 2012 16:16:18 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=843</guid>
		<description><![CDATA[Here&#8217;s one thing to do with an older iPad if you recently replaced it with the new Retina model: Get on the iOS App Store ($10) and use that older iPad as a second display when you&#8217;re working away from your regular desk. In my office, I&#8217;m used to two good-sized monitors, and I typically [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s one thing to do with an older iPad if you recently replaced it with the new Retina model:</p>
<p>Get <a href="http://click.linksynergy.com/fs-bin/stat?id=b3l3j6su8PM&offerid=146261&type=3&subid=0&tmpid=1826&RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fapp%252Fid368158927%253FpartnerId%253D30">Air Display</a> on the iOS App Store ($10) and use that older iPad as a second display when you&#8217;re working away from your regular desk.<span id="more-843"></span></p>
<p>In my office, I&#8217;m used to two good-sized monitors, and I typically have my editing environment on one side and a browser or documentation on the other. My laptop is a 13&#8243; MacBook Air, and the screen is simply not large enough for that arrangement. With Air Display, it works great.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F03%2Fold-ipad-air-display-awesome%2F&#038;seed_title=Old+iPad+%2B+Air+Display+%3D+Awesome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sold on Homebrew</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F02%2Fsold-on-homebrew%2F&#038;seed_title=Sold+on+Homebrew</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F02%2Fsold-on-homebrew%2F&#038;seed_title=Sold+on+Homebrew#comments</comments>
		<pubDate>Fri, 03 Feb 2012 22:19:00 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Ruby & Rails]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=827</guid>
		<description><![CDATA[I&#8217;ve been a MacPorts user for a very long time, so when I heard about Homebrew, I looked into it, but didn&#8217;t see anything compelling enough to convince me to switch. That changed today. I&#8217;m starting a new Rails project. I want to use Ruby 1.9.3 from the beginning to ease a future upgrade to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been a <a href="http://www.macports.org/">MacPorts</a> user for a very long time, so when I heard about <a href="http://mxcl.github.com/homebrew/">Homebrew</a>, I looked into it, but didn&#8217;t see anything compelling enough to convince me to switch. That changed today.<span id="more-827"></span></p>
<p>I&#8217;m starting a new Rails project. I want to use Ruby 1.9.3 from the beginning to ease a future upgrade to Rails 4.0, which will require it. This presented a few issues I had to work through for my development and production environments.</p>
<p>Mac OS X ships with Ruby 1.8.7, but I&#8217;ve been using <a href="https://rvm.beginrescueend.com/">RVM</a> to manage different Ruby versions in development and it&#8217;s worked fine. Debian is my preferred server distribution and the latest stable release includes Ruby 1.9.2-p0.</p>
<p>I&#8217;m not completely comfortable with using RVM in a production environment, and I don&#8217;t want to take on the work of installing my own Ruby entirely by hand, so this led me to look at <a href="https://github.com/sstephenson/rbenv">rbenv</a>, a lightweight alternative to RVM. It seems better suited for use in a production environment. I like to match development to production when possible so there are less things to remember, and so I switched to rbenv on my development machine, as well. Paired with <a href="https://github.com/sstephenson/ruby-build">ruby-build</a>, it gives me the important features I used from RVM (I never made much use of gem sets).</p>
<p>It did not go well.</p>
<pre>
$ rbenv install 1.9.3-p0
$ RBENV_VERSION=1.9.3-p0 gem install bundler rails
$ rbenv rehash
$ RBENV_VERSION=1.9.3-p0 rails new app
...
/Volumes/User/Steve/.rbenv/versions/1.9.3-p0/lib/ruby/1.9.1/net/http.rb:799: [BUG] Segmentation fault
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.3.0]
</pre>
<p>Searching for solutions led me to suspect that this is due to a library version mismatch between the compiled Ruby and a gem. MacPorts can make this more common, because unlike Homebrew, it imposes strict control over dependencies and will install a new version of something (e.g., OpenSSL) even if Mac OS X ships with an older one that would work fine.</p>
<p>Rather than track down the problem library, then figure out how to ask rbenv to link with a different version of it, I decided to try Homebrew.</p>
<p>It worked flawlessly. The error when creating a new Rails project is gone.</p>
<p>What really sealed the deal for me came next. I like PostgreSQL, partly because it supports additional data types that can be very useful. One example is <tt>cube</tt>, which is used by the earthdistance extension to store locations and do fast proximity searches. On MacPorts, installing those &#8220;contrib&#8221; extensions is a <a href="http://lightyearsoftware.com/2010/08/adding-contrib-extensions-to-macports-postgresql/" title="Adding “contrib” Extensions to MacPorts PostgreSQL">manual, clunky process</a>. On Homebrew, all the contrib extensions are already compiled and available.</p>
<p>Sold.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F02%2Fsold-on-homebrew%2F&#038;seed_title=Sold+on+Homebrew/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Non-Rectangular Buttons on iOS</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fnon-rectangular-buttons-on-ios%2F&#038;seed_title=Non-Rectangular+Buttons+on+iOS</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fnon-rectangular-buttons-on-ios%2F&#038;seed_title=Non-Rectangular+Buttons+on+iOS#comments</comments>
		<pubDate>Tue, 03 Jan 2012 20:35:00 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=700</guid>
		<description><![CDATA[One of the projects I worked on last year was the iOS SDK for Yahoo! Connected TV. Along with the SDK, Yahoo! wanted to ship an example app that demonstrated use of the SDK. Take a look at the screenshot to the right. See anything a little out of the ordinary? Several of the buttons, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://lightyearsoftware.com/wp-content/uploads/2012/01/connectedtv.png"><img class="alignright size-full wp-image-786" title="sample remote from Yahoo! Connected TV iOS SDK" src="http://lightyearsoftware.com/wp-content/uploads/2012/01/connectedtv.png" alt="sample remote from Yahoo! Connected TV iOS SDK" width="220" height="330" /></a>One of the projects I worked on last year was the iOS SDK for <a href="http://connectedtv.yahoo.com/">Yahoo! Connected TV</a>. Along with the SDK, Yahoo! wanted to ship an example app that demonstrated use of the SDK. Take a look at the screenshot to the right. See anything a little out of the ordinary?</p>
<p>Several of the buttons, especially the colored ones along the bottom half of the directional pad, are not rectangular.<span id="more-700"></span></p>
<p><a href="http://lightyearsoftware.com/wp-content/uploads/2012/01/connectedtv-detail.png"><img class="alignleft size-full wp-image-788" title="the frame of the green button, showing how it overlaps the down and rewind buttons" src="http://lightyearsoftware.com/wp-content/uploads/2012/01/connectedtv-detail.png" alt="the frame of the green button, showing how it overlaps the down and rewind buttons" width="203" height="170" /></a>It doesn&#8217;t matter if we&#8217;re developing on the Mac or iOS. Views are rectangular and they either gobble a click/tap or they don&#8217;t. Take a look at the green button. The blue outline shows the frame of the view. It overlaps two other buttons: down and rewind. Especially on iOS, where a fingertip is an imprecise input method, a user will find it very frustrating if a tap on down was instead interpreted as green.</p>
<p>The solution is quite straightforward on iOS: create a subclass of <tt>UIButton</tt> and override <tt>-pointInside:withEvent:</tt>.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span> pointInside<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGPoint<span style="color: #002200;">&#41;</span>point withEvent<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIEvent <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">/* Surprisingly, this method is called even when point has a negative
     * component and is obviously outside of self.bounds. */</span>
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>CGRectContainsPoint<span style="color: #002200;">&#40;</span>self.bounds, point<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">/* The point is within our bounds. If a mask exists, check the mask
         * for an allowed tap. If there is no mask, let the superclass
         * (UIButton) do the work. */</span>
&nbsp;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mask <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">return</span> mask<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span>NSUInteger<span style="color: #002200;">&#41;</span>point.y <span style="color: #002200;">*</span> maskWidth <span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>NSUInteger<span style="color: #002200;">&#41;</span>point.x<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
        <span style="color: #a61390;">else</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>super pointInside<span style="color: #002200;">:</span>point withEvent<span style="color: #002200;">:</span>event<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p><tt>pointInside:withEvent:</tt> is called by <tt>hitTest:withEvent:</tt>, once for each subview. If a subview returns <tt>NO</tt>, then its branch of the hierarchy is ignored. By making <tt>pointInside:withEvent:</tt> sensitive to only the part of the image that is the button, it&#8217;s possible to ignore events for taps on a part that doesn&#8217;t.</p>
<p>The key is building a mask. Here, it is a two dimensional <tt>BOOL</tt> array. If <tt>mask</tt> is not <tt>NULL</tt>, the x and y of the point is used to index into the array and return the value there. If <tt>mask</tt> is <tt>NULL</tt> for any reason, the code simply falls back to the superclass&#8217;s behavior. </p>
<p>One way to build the mask is to look at the alpha channel of the image.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> buildMask
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mask<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>mask<span style="color: #002200;">&#41;</span>;
        mask <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    CGImageRef image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self imageForState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>.CGImage;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>image <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    NSUInteger width <span style="color: #002200;">=</span> CGImageGetWidth<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>;
    NSUInteger height <span style="color: #002200;">=</span> CGImageGetHeight<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>;
    uint32_t <span style="color: #002200;">*</span>pixels <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span>width <span style="color: #002200;">*</span> height <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>pixels <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">/* Provided that memory for the temporary 32-bit pixel array was
         * available, draw the CGImage into that memory. */</span>
&nbsp;
        CGColorSpaceRef colorSpaceRef <span style="color: #002200;">=</span> CGColorSpaceCreateDeviceRGB<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
        CGContextRef context <span style="color: #002200;">=</span> CGBitmapContextCreate<span style="color: #002200;">&#40;</span>pixels, width, height,
                                                     CGImageGetBitsPerComponent<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>,
                                                     width <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span>, colorSpaceRef,
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Host<span style="color: #002200;">&#41;</span>;
&nbsp;
        CGContextSetBlendMode<span style="color: #002200;">&#40;</span>context, kCGBlendModeCopy<span style="color: #002200;">&#41;</span>;
        CGContextDrawImage<span style="color: #002200;">&#40;</span>context, CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, width, height<span style="color: #002200;">&#41;</span>, image<span style="color: #002200;">&#41;</span>;
        CGContextRelease<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
        CGColorSpaceRelease<span style="color: #002200;">&#40;</span>colorSpaceRef<span style="color: #002200;">&#41;</span>;
&nbsp;
        mask <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span>width <span style="color: #002200;">*</span> height <span style="color: #002200;">*</span> <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
        maskWidth <span style="color: #002200;">=</span> width;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mask <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>NSUInteger y <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; y &lt; height; <span style="color: #002200;">++</span>y<span style="color: #002200;">&#41;</span>
            <span style="color: #002200;">&#123;</span>
                <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>NSUInteger x <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; x &lt; width; <span style="color: #002200;">++</span>x<span style="color: #002200;">&#41;</span>
                <span style="color: #002200;">&#123;</span>
                    <span style="color: #11740a; font-style: italic;">/* RGBA: high 24 bits are color, low 8 bits are alpha.
                     * Less than 50% alpha is the untapped part of the image. */</span>
                    mask<span style="color: #002200;">&#91;</span>y <span style="color: #002200;">*</span> width <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>pixels<span style="color: #002200;">&#91;</span>y <span style="color: #002200;">*</span> width <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;</span> 0xFF<span style="color: #002200;">&#41;</span> &gt; <span style="color: #2400d9;">128</span>;
                <span style="color: #002200;">&#125;</span>
            <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#125;</span>
        <span style="color: #a61390;">else</span>
        <span style="color: #002200;">&#123;</span>
            NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to allocate memory, will fall back to UIButton behavior.&quot;</span><span style="color: #002200;">&#41;</span>;
        <span style="color: #002200;">&#125;</span>
&nbsp;
        <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>pixels<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to allocate memory, will fall back to UIButton behavior.&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> setImage<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>image forState<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIControlState<span style="color: #002200;">&#41;</span>state
<span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>super setImage<span style="color: #002200;">:</span>image forState<span style="color: #002200;">:</span>state<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>self buildMask<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>The subclass overrides <tt>setImage:forState:</tt> so that when the image is set or changed, the mask is regenerated. To use a non-rectangular button within Interface Builder, we need to also override <tt>initWithCoder:</tt>.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span> initWithCoder<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSCoder</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>coder
<span style="color: #002200;">&#123;</span>
    self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super initWithCoder<span style="color: #002200;">:</span>coder<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self buildMask<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>If you don&#8217;t want to use the alpha channel, another option is to provide an explicit mask image. Masks are monochrome bitmaps, where white indicates the visible area. Building the <tt>mask</tt> array from a mask image is very similar to using the alpha channel. The only difference is what part of the pixel data is analyzed.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> setMaskImage<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>maskImage
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mask<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>mask<span style="color: #002200;">&#41;</span>;
        mask <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>maskImage <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">return</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    CGImageRef image <span style="color: #002200;">=</span> maskImage.CGImage;
    NSUInteger width <span style="color: #002200;">=</span> CGImageGetWidth<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>;
    NSUInteger height <span style="color: #002200;">=</span> CGImageGetHeight<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>;
    uint32_t <span style="color: #002200;">*</span>pixels <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span>width <span style="color: #002200;">*</span> height <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>pixels <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">/* Provided that memory for the temporary 32-bit pixel array was
         * available, draw the CGImage into that memory. */</span>
&nbsp;
        CGColorSpaceRef colorSpaceRef <span style="color: #002200;">=</span> CGColorSpaceCreateDeviceRGB<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
        CGContextRef context <span style="color: #002200;">=</span> CGBitmapContextCreate<span style="color: #002200;">&#40;</span>pixels, width, height,
                                                     CGImageGetBitsPerComponent<span style="color: #002200;">&#40;</span>image<span style="color: #002200;">&#41;</span>,
                                                     width <span style="color: #002200;">*</span> <span style="color: #2400d9;">4</span>, colorSpaceRef,
                                                     kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Host<span style="color: #002200;">&#41;</span>;
&nbsp;
        CGContextSetBlendMode<span style="color: #002200;">&#40;</span>context, kCGBlendModeCopy<span style="color: #002200;">&#41;</span>;
        CGContextDrawImage<span style="color: #002200;">&#40;</span>context, CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, width, height<span style="color: #002200;">&#41;</span>, image<span style="color: #002200;">&#41;</span>;
        CGContextRelease<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
        CGColorSpaceRelease<span style="color: #002200;">&#40;</span>colorSpaceRef<span style="color: #002200;">&#41;</span>;
&nbsp;
        mask <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span>width <span style="color: #002200;">*</span> height <span style="color: #002200;">*</span> <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
        maskWidth <span style="color: #002200;">=</span> width;
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>mask <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>
        <span style="color: #002200;">&#123;</span>
            <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>NSUInteger y <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; y &lt; height; <span style="color: #002200;">++</span>y<span style="color: #002200;">&#41;</span>
            <span style="color: #002200;">&#123;</span>
                <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>NSUInteger x <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; x &lt; width; <span style="color: #002200;">++</span>x<span style="color: #002200;">&#41;</span>
                <span style="color: #002200;">&#123;</span>
                    <span style="color: #11740a; font-style: italic;">/* RGBA: high 24 bits are color. Anything other than black
                     * is tappable. */</span>
                    mask<span style="color: #002200;">&#91;</span>y <span style="color: #002200;">*</span> width <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>pixels<span style="color: #002200;">&#91;</span>y <span style="color: #002200;">*</span> width <span style="color: #002200;">+</span> x<span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;</span> 0xFFFFFF00<span style="color: #002200;">&#41;</span> <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span>;
                <span style="color: #002200;">&#125;</span>
            <span style="color: #002200;">&#125;</span>
        <span style="color: #002200;">&#125;</span>
        <span style="color: #a61390;">else</span>
        <span style="color: #002200;">&#123;</span>
            NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to allocate memory, will fall back to UIButton behavior.&quot;</span><span style="color: #002200;">&#41;</span>;
        <span style="color: #002200;">&#125;</span>
&nbsp;
        <span style="color: #a61390;">free</span><span style="color: #002200;">&#40;</span>pixels<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
    <span style="color: #a61390;">else</span>
    <span style="color: #002200;">&#123;</span>
        NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unable to allocate memory, will fall back to UIButton behavior.&quot;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fnon-rectangular-buttons-on-ios%2F&#038;seed_title=Non-Rectangular+Buttons+on+iOS/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testing Cocoa with MacRuby</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F09%2Funit-testing-cocoa-with-macruby%2F&#038;seed_title=Unit+Testing+Cocoa+with+MacRuby</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F09%2Funit-testing-cocoa-with-macruby%2F&#038;seed_title=Unit+Testing+Cocoa+with+MacRuby#comments</comments>
		<pubDate>Thu, 29 Sep 2011 15:43:05 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[Ruby & Rails]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=727</guid>
		<description><![CDATA[I spend most of my development time split between Rails and iOS. Each offers a rich API that makes building projects much more productive and enjoyable. There is one place, however, that Ruby clobbers Objective-C: testing. It&#8217;s not that Objective-C doesn&#8217;t have test frameworks. There are several: OCUnit (bundled with Xcode), GHUnit, Cedar and Kiwi. [...]]]></description>
			<content:encoded><![CDATA[<p>I spend most of my development time split between Rails and iOS. Each offers a rich API that makes building projects much more productive and enjoyable. There is one place, however, that Ruby clobbers Objective-C: testing.<span id="more-727"></span></p>
<p>It&#8217;s not that Objective-C doesn&#8217;t have test frameworks. There are several: <a href="http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/ios_development_workflow/135-Unit_Testing_Applications/unit_testing_applications.html">OCUnit</a> (bundled with Xcode), <a href="https://github.com/gabriel/gh-unit">GHUnit</a>, <a href="https://github.com/pivotal/cedar">Cedar</a> and <a href="http://www.kiwi-lib.info/">Kiwi</a>. Cedar and Kiwi use blocks to get close to an RSpec-like syntax, but there&#8217;s only so far it can go. Objective-C can&#8217;t match Ruby when creating a DSL, even with preprocessor abuse.</p>
<p>Fortunately, there is a way to write tests in Ruby and run them against Objective-C code: <a href="http://www.macruby.org/">MacRuby</a>. MacRuby is an implementation of Ruby 1.9 that compiles Ruby to LLVM bytecode and has full access to Objective-C frameworks. You can write full Mac desktop applications with it, but for this post I&#8217;ll simply use it to write test specs with RSpec for testing Objective-C classes.</p>
<p>In this post, I&#8217;ll walk you through how to install MacRuby, RSpec and how to set up your Cocoa (Mac or iOS) project to unit test with RSpec. These tests are analogous to model specs in Rails. We&#8217;ll be testing classes in isolation, not trying to recreate the Cocoa environment in order to test window or view controllers, etc.</p>
<p>A big caveat for iOS developers: MacRuby loads Objective-C code from a framework, but iOS targets don&#8217;t support building frameworks. What this means is that you don&#8217;t have access to the <tt>UI*</tt> classes in the code under test. This limits what you can test. Pure model classes (those without any external dependencies) will be fine. Theoretically, it should be possible to find the simulator frameworks and link against those, but I&#8217;ve been unsuccessful thus far. <a href="http://chameleonproject.org/">Chameleon</a> might help if you want to dig into this further.</p>
<p>With that out of the way, let&#8217;s get started. If you haven&#8217;t already, download and install MacRuby. This places the <tt>macruby</tt> binary and other Ruby tools you&#8217;re familiar with (<tt>irb</tt>, <tt>gem</tt>, <tt>rake</tt>) in <tt>/usr/local/bin</tt>, with <tt>mac</tt> prefixes.</p>
<p>Then, install RSpec 2.5 (at present, there are <a href="https://github.com/rspec/rspec-core/issues/461">problems running specs with 2.6</a>).</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ sudo macgem install --bindir /usr/local/bin --format-executable rspec -v '~&gt;2.5.0'</pre></div></div>

<p><tt>--bindir</tt> ensures the <tt>rspec</tt> script doesn&#8217;t overwrite one that might already exist in <tt>/usr/bin</tt>, and <tt>--format-executable</tt> adds the <tt>mac</tt> prefix to it, so it matches the other MacRuby-provided scripts.</p>
<p>In Xcode, open your project and create a new target (File -> New Target). Use the Cocoa Framework template, found under Mac OS X, Framework &amp; Library. Call it whatever you like. I used &#8220;Specs&#8221;. Do not use Automatic Reference Counting. MacRuby, like MRI Ruby, is garbage collected and will use the Objective-C garbage collector. If your project uses ARC, that&#8217;s OK. <tt>retain</tt>, <tt>release</tt> and <tt>autorelease</tt> are no-ops under GC, and nothing changes if the calls to them are missing in the first place. Include Unit Tests should also be unchecked.</p>
<p>You must adjust some build settings for the new target. Under Apple LLVM Compiler &#8211; Language, find the settings for Objective-C Automatic Reference Counting and ensure it is set to NO. Just below that, set Objective-C Garbage Collection to Supported.</p>
<p><img class="size-full wp-image-729 aligncenter" title="compiler settings for ARC and GC" src="http://lightyearsoftware.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-23-at-11.47.39-AM.png" alt="" width="438" height="53" /></p>
<p>Go to the target build phases, and add the <tt>.m</tt> files you wish to test to the compile sources phase. As you add files to your project later, be sure to check the boxes for both your main target and the Specs target if you want to test the new code.</p>
<p>Finally, you need to configure the schemes for the new target. In the build scheme, check the run box. In the run scheme, choose <tt>/usr/local/bin/macruby</tt> as the executable to test.</p>
<p><img class="size-full wp-image-730 aligncenter" title="run scheme info configuration" src="http://lightyearsoftware.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-23-at-11.53.56-AM.png" alt="" width="424" height="209" /></p>
<p>Set up the arguments to pass to the executable when it runs as follows:</p>
<p><img class="size-full wp-image-731 aligncenter" title="run scheme arguments configuration" src="http://lightyearsoftware.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-23-at-11.54.10-AM.png" alt="" width="526" height="312" /></p>
<p>Choose your framework as the base for expansions. You&#8217;ll pass two arguments to the program: the path to the RSpec wrapper and the directory containing the specs.</p>
<p>You might wonder why we&#8217;re using MacRuby as the executable to test instead of RSpec directly. If you try to use RSpec, Xcode won&#8217;t recognize it as a 64-bit executable and will refuse to run it under the debugger. It will work, but you must also choose &#8220;debugger: none&#8221; and give up your breakpoints, etc.</p>
<p>With this new target you get a new top-level group in your project. Xcode has also created Specs.h and Specs.m, which we don&#8217;t need. You should delete them.</p>
<p>Create a new file in this group called <tt>spec_helper.rb</tt> and paste this in:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">framework <span style="color:#996600;">'Specs'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Requires supporting ruby files with custom matchers and macros, etc,</span>
<span style="color:#008000; font-style:italic;"># in spec/support/ and its subdirectories.</span>
<span style="color:#CC00FF; font-weight:bold;">Dir</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;#{ENV['SRCROOT']}/Specs/support/**/*.rb&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">require</span> f<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
RSpec.<span style="color:#9900CC;">configure</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>config<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#008000; font-style:italic;"># == Mock Framework</span>
  <span style="color:#008000; font-style:italic;">#</span>
  <span style="color:#008000; font-style:italic;"># If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:</span>
  <span style="color:#008000; font-style:italic;">#</span>
  <span style="color:#008000; font-style:italic;"># config.mock_with :mocha</span>
  <span style="color:#008000; font-style:italic;"># config.mock_with :flexmock</span>
  <span style="color:#008000; font-style:italic;"># config.mock_with :rr</span>
  config.<span style="color:#9900CC;">mock_with</span> <span style="color:#ff3333; font-weight:bold;">:spec</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>At this point, you should be able to choose your new target from the scheme picker in the toolbar and run. We haven&#8217;t created any specs yet, so you should see this:</p>
<pre>
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys004
[Switching to process 1636 thread 0x0]
No examples were matched. Perhaps {:if=>#&lt;Proc:0x4007553a0 (lambda)>, :unless=>#&lt;Proc:0x400795b60 (lambda)>} is excluding everything?

Finished in 0.0331 seconds
0 examples, 0 failures
Program ended with exit code: 0
</pre>
<p>You may not see any output. You can use ⌘7 and look at the most recent log or use this <a href="http://twitter.com/pilky/status/109737034633060352">tip from Martin Pilkington</a> to create a new window for output. I find this much less intrusive than allowing Xcode to constantly pop up the debugging panes in my editor windows.</p>
<p>Let&#8217;s create a simple spec file. Assuming you added a <tt>.m</tt> file that implements a class called <tt>Foo</tt>, create a new file in your Specs group called <tt>foo_spec.rb</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;#{ENV['SRCROOT']}/Specs/spec_helper&quot;</span>
&nbsp;
describe Foo <span style="color:#9966CC; font-weight:bold;">do</span>
  it <span style="color:#006600; font-weight:bold;">&#123;</span> should be_an_instance_of<span style="color:#006600; font-weight:bold;">&#40;</span>Foo<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Run again and you should see this:</p>
<pre>
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys004
[Switching to process 1796 thread 0x0]
.

Finished in 0.40422 seconds
1 example, 0 failures
Program ended with exit code: 0
</pre>
<p>It works! Now try adding breakpoints, mocking and stubbing objects, etc. You have all the features of RSpec available to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F09%2Funit-testing-cocoa-with-macruby%2F&#038;seed_title=Unit+Testing+Cocoa+with+MacRuby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Cocoa Networking Talk</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F08%2Fslides-from-cocoa-networking-talk%2F&#038;seed_title=Slides+from+Cocoa+Networking+Talk</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F08%2Fslides-from-cocoa-networking-talk%2F&#038;seed_title=Slides+from+Cocoa+Networking+Talk#comments</comments>
		<pubDate>Mon, 15 Aug 2011 14:21:22 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=723</guid>
		<description><![CDATA[I have posted the slides from my talk on networking with Cocoa at CocoaConf. For those that attended: thank you! It was great meeting so many new people and having the opportunity to present. One common suggestion for improvement from attendees was for demos. These are always tricky with networking topics, because you never know [...]]]></description>
			<content:encoded><![CDATA[<p>I have posted the slides from <a href="/slides/CocoaNetworking.pdf" title="Cocoa Networking slides">my talk on networking with Cocoa</a> at <a href="http://cocoaconf.com/" title="CocoaConf">CocoaConf</a>. For those that attended: thank you! It was great meeting so many new people and having the opportunity to present.</p>
<p>One common suggestion for improvement from attendees was for demos. These are always tricky with networking topics, because you never know how good the Wi-Fi will be at a conference. When I give this talk in the future, I think I will split it into two, build some demos, and bring a second laptop with a cross-over cable.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F08%2Fslides-from-cocoa-networking-talk%2F&#038;seed_title=Slides+from+Cocoa+Networking+Talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Your Own Private WWDC 2011</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F07%2Fyour-own-private-wwdc-2011%2F&#038;seed_title=Your+Own+Private+WWDC+2011</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F07%2Fyour-own-private-wwdc-2011%2F&#038;seed_title=Your+Own+Private+WWDC+2011#comments</comments>
		<pubDate>Fri, 01 Jul 2011 15:24:57 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=702</guid>
		<description><![CDATA[Now that Apple has released the complete set of WWDC 2011 videos to registered developers, those of us who couldn&#8217;t make it to the conference have the opportunity to hear about all the new, shiny stuff coming in Mac OS X 10.7 and iOS 5. With 109 sessions to choose from, newcomers may not know [...]]]></description>
			<content:encoded><![CDATA[<p>Now that Apple has released the complete set of <a href="http://developer.apple.com/videos/wwdc/2011/">WWDC 2011 videos</a> to registered developers, those of us who couldn&#8217;t make it to the conference have the opportunity to hear about all the new, shiny stuff coming in Mac OS X 10.7 and iOS 5.<span id="more-702"></span></p>
<p>With 109 sessions to choose from, newcomers may not know where to start. This guide is intended to help you get started.</p>
<p><a href="http://www.apple.com/apple-events/wwdc-2011/"><strong>The Keynote</strong></a>: the only WWDC session not under NDA, this is where all the public news was announced. If for some reason you haven&#8217;t watched it yet, it&#8217;s worth watching, although it is a bit long and by now you&#8217;ve probably heard about everything.</p>
<p>Since everything else is under NDA, I can&#8217;t discuss specifics about the content of sessions.</p>
<p>Start with the <strong>Apple Platforms Kickoff</strong>. Where the keynote is truly for the press, this session is for developers.</p>
<p>Whether your focus is on Mac OS X or iOS, you&#8217;ll be using Xcode, so move on to <strong>Session 300: Developer Tools Kickoff</strong>. You&#8217;ll learn about the new tools and features coming in future versions of Xcode.</p>
<p>The final kickoff session is <strong>Session 400: Graphics, Media, and Games Kickoff</strong>. I found this session to be less focused on new stuff and more a general overview of the available frameworks and tools, though the demo at the end is impressive. There is a bit about Game Center and AV Foundation if you&#8217;re interested in these frameworks.</p>
<p>Trivia: in previous years, these sessions used the &#8220;State of the Union&#8221; moniker.</p>
<p>Where to next? That depends on what you want to do. Many sessions include pointers to others covering specific topics, so be sure to watch for those to find more information about areas that interest you.</p>
<h2>If you&#8217;re a Mac OS X developer&#8230;</h2>
<p>If you have an app in the Mac App Store or plan to ship one in the future, start with <strong>Session 203: Introducing App Sandbox</strong> and <strong>Session 204: App Sandbox and the Mac App Store</strong>. There are new submission requirements coming with 10.7 that are more important than anything else.</p>
<p>Follow that up with <strong>Session 101: What&#8217;s New in Cocoa</strong>. This is the high-level session to learn about the new stuff for developers in 10.7. Don&#8217;t miss <strong>Session 323: Introducing Automatic Reference Counting</strong> so you can (mostly) stop thinking about manual memory management.</p>
<p><strong>Session 127: Design Patterns to Simplify Mac Accessibility</strong> is James Dempsey&#8217;s annual talk that includes a song. Even if you don&#8217;t think you care about accessibility (hint: you should), his talk is great and the song is a funny distillation of the topic.</p>
<h2>If you&#8217;re an iOS developer&#8230;</h2>
<p>Start with <strong>Session 100: What&#8217;s New in Cocoa Touch</strong>, then <strong>Session 323: Introducing Automatic Reference Counting</strong>, followed by <strong>Session 309: Introducing Interface Builder Storyboarding</strong> and <strong>Session 102: Implementing UIViewController Containment</strong>. Follow the suggestions for related sessions depending on your interests and needs.</p>
<h2>App Design</h2>
<p>Excellent design will set your app apart from the crowd. There are two sessions covering UI and UX topics: <strong>Session 110: Designing User Interfaces for iOS and Mac OS X Apps</strong> and <strong>Session 105: Polishing Your App</strong>, the latter of which includes non-visual polish such as responsiveness and performance, a user experience issue.</p>
<h2>Security and Performance</h2>
<p>You should care about the security of your app and how well it performs. <strong>Session 202: Security Overview</strong> discusses attack vectors and options for addressing them. <strong>Session 310: What&#8217;s New in Instruments</strong> will point you in the right direction for performance analysis and tuning, while <strong>Session 312: iOS Performance and Power Optimization with Instruments</strong> and <strong>Session 318: iOS Performance in Depth</strong> teaches practical techniques for diagnosing and fixing problems for iOS apps.</p>
<p>Releasing these videos for free is a great service to the Apple developer community. There is value in almost every session, and the huge advantage we have in watching them now is we can check out topics we might not have made time for if attending the conference in person. Skip ahead or stop a video if it isn&#8217;t holding your attention.</p>
<p>My recommendations here are a starting point. Apple&#8217;s platforms are growing and getting better every year. Explore new things; you never know when you might learn something relevant to an existing project. Watch a session about a topic you think you know well. With such a rich set of frameworks, there are often little tricks to learn that mean you can rewrite some old code to be clearer or perform better.</p>
<p>Is there a particularly good session I haven&#8217;t mentioned? Mention it in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F07%2Fyour-own-private-wwdc-2011%2F&#038;seed_title=Your+Own+Private+WWDC+2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CocoaConf</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F06%2Fcocoaconf%2F&#038;seed_title=CocoaConf</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F06%2Fcocoaconf%2F&#038;seed_title=CocoaConf#comments</comments>
		<pubDate>Fri, 03 Jun 2011 15:49:47 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=675</guid>
		<description><![CDATA[CocoaConf is a new developer-focused conference for Mac OS X and iOS being held August 12-13 in Columbus, OH. I am presenting a session on networking with Cocoa. It will cover the various APIs available to Mac OS X and iOS developers from Apple and third-parties, as well as touch on issues unique to using [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://cocoaconf.com/">CocoaConf</a> is a new developer-focused conference for Mac OS X and iOS being held August 12-13 in Columbus, OH. I am presenting a session on networking with Cocoa. It will cover the various APIs available to Mac OS X and iOS developers from Apple and third-parties, as well as touch on issues unique to using the network on a mobile platform.</p>
<p>Early registration opened today and you can get a conference pass for 50% off.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F06%2Fcocoaconf%2F&#038;seed_title=CocoaConf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL 5.5 on Mac OS X</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F02%2Fmysql-5-5-on-mac-os-x%2F&#038;seed_title=MySQL+5.5+on+Mac+OS+X</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F02%2Fmysql-5-5-on-mac-os-x%2F&#038;seed_title=MySQL+5.5+on+Mac+OS+X#comments</comments>
		<pubDate>Fri, 25 Feb 2011 16:22:52 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby & Rails]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=643</guid>
		<description><![CDATA[If you&#8217;re (re)building a development workstation on Mac OS X, you may have decided to use the latest MySQL 5.5 packages from mysql.com. Unfortunately, that means you probably have seen (or will soon see) two problems. The first is this: dlopen(/Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.16.dylib Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle Reason: image not found - /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re (re)building a development workstation on Mac OS X, you may have decided to use the latest MySQL 5.5 packages from mysql.com. Unfortunately, that means you probably have seen (or will soon see) two problems.<span id="more-643"></span> The first is this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">dlopen(/Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.16.dylib
Referenced from: /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle
Reason: image not found - /Library/Ruby/Gems/1.8/gems/mysql2-0.2.6/lib/mysql2/mysql2.bundle</pre></div></div>

<p>That example is from the mysql2 gem, but the same problem exists with the older mysql gem. The problem is that the libmysqlclient shared library in the MySQL 5.5 package does not specify a full path to the library. When something links with it, such as the MySQL gem, it won&#8217;t be able to find the library at runtime.</p>
<p>There are two ways to fix this.</p>
<ol>
<li>
<p>The easy way: modify <tt>DYLD_LIBRARY_PATH</tt> in your <tt>.bash_profile</tt> (or equivalent if you use another shell). The advantage to this method is that it fixes it once for anything that links with the MySQL client libraries going forward. Add:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">DYLD_LIBRARY_PATH=&quot;/usr/local/mysql/lib:$DYLD_LIBRARY_PATH&quot;</pre></div></div>

</li>
<li>
<p>The hard, do-it-again-someday way: modify the <tt>.bundle</tt> files within the gem to use an absolute path to the MySQL client library. The fix is lost when reinstalling the gem or updating to a new version and must be reapplied. Change to your gem&#8217;s root, somewhere like <tt>/Library/Ruby/Gems/1.8/gems/mysql-2.8.1</tt> or <tt>.../mysql2-0.2.6</tt>, or even both. There are two <tt>.bundle</tt> files within the gem (under <tt>lib</tt> and <tt>ext</tt>) that you must run the following command on.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ sudo install_name_tool -change libmysqlclient.16.dylib /usr/local/mysql/lib/libmysqlclient.16.dylib mysql_api.bundle</pre></div></div>

</li>
</ol>
<p>The second problem with the MySQL 5.5 packages is in the MySQLStartupItem and preference pane. Neither work to start or stop the server.</p>
<ol>
<li>
<p>The ownership of the StartupItem files is wrong. OS X complains with</p>
<blockquote><p>&#8220;/Library/StartupItems/MySQLCOM” has not been started because it does not have the proper security settings.</p></blockquote>
<p>To fix that, run:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ sudo chown -R root:wheel /Library/StartupItems/MySQLCOM</pre></div></div>

</li>
<li>
<p><tt>basedir</tt> and <tt>datadir</tt> are not set in <tt>/usr/local/mysql/support-files/mysql.server</tt>, which breaks the preference pane. Edit that file with superuser privileges (<tt>sudo mate</tt> or vi, joe, &#8230;) and set them:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">basedir=/usr/local/mysql
datadir=/usr/local/mysql/data</pre></div></div>

</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2011%2F02%2Fmysql-5-5-on-mac-os-x%2F&#038;seed_title=MySQL+5.5+on+Mac+OS+X/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.012 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-21 21:22:44 -->

