<?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</title>
	<atom:link href="http://lightyearsoftware.com/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>RubyMotion</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F05%2Frubymotion%2F&#038;seed_title=RubyMotion</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F05%2Frubymotion%2F&#038;seed_title=RubyMotion#comments</comments>
		<pubDate>Fri, 04 May 2012 18:25:24 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Ruby & Rails]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=977</guid>
		<description><![CDATA[Yesterday, Laurent Sansonetti announced RubyMotion, the first product from his new company, HipByte. Laurent is the creator of MacRuby and worked on it part-time while an employee at Apple. RubyMotion is interesting, but I don&#8217;t have any plans to use it myself, especially for client work. There are two reasons. The first is from a [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, Laurent Sansonetti announced <a href="http://www.rubymotion.com/">RubyMotion</a>, the first product from his new company, HipByte. Laurent is the creator of MacRuby and worked on it part-time while an employee at Apple.</p>
<p>RubyMotion is interesting, but I don&#8217;t have any plans to use it myself, especially for client work. There are two reasons.<span id="more-977"></span></p>
<p>The first is from a business standpoint. I learned long ago to put aside my own opinions of how things should be done whenever possible and to swim with the current. This applies to managing servers (use the package manager and avoid installing your own software) and developing software (understand the intention of the API&#8217;s author and use it accordingly).</p>
<p>Apple ships a lot of open-source software with OS X, but they aren&#8217;t great about keeping up with releases. Nor are they good at supporting alternative ways to write software on their platforms. Remember Java, RubyCocoa, and PyObjC? This is even true, to some extent, of MacRuby. Apple paid Laurent to work on MacRuby, yet MacRuby never shipped with an OS X release. If you want to use MacRuby in a shipping application, you either require your users to install it (terrible UX) or embed it yourself (at a cost of 10+ MB to your app bundle).</p>
<p>Lion shipped on July 20, 2011. It includes Ruby 1.8.7-p249. 1.8.7 has been in maintenance mode for a long time and Apple has ignored numerous patches.</p>
<ul>
<li>p299, released on June 23, 2010, <em>over a year</em> before Lion</li>
<li>p302, released on August 16, 2010</li>
<li>p330, released on December 25, 2010</li>
<li>p352, released on July 2, 2011</li>
</ul>
<p>The Ruby core team has encouraged people to move to 1.9 since the official release of 1.9.2-p0 on August 18, 2010. There are no signs that Apple will move the system Ruby to the 1.9 series in the upcoming Mountain Lion release, either, <em>nearly two years later</em>.</p>
<p>I&#8217;m offering all this as a long-winded way to say that I do not put much faith in Apple&#8217;s desire to avoid breaking a third-party toolchain such as RubyMotion when they can&#8217;t be bothered to do a good job supporting the Ruby they ship on OS X. It&#8217;s less troublesome, but still an issue, that they never shipped the MacRuby framework, which they paid an employee to work on.</p>
<p>If Apple were to break RubyMotion, intentionally or otherwise, in a future iOS release, I would be unable to fix those apps until RubyMotion adapted to the change, however long that took. In the meantime, the apps would be broken, making users unhappy. If the apps were for clients, my choice of a third-party toolchain will reflect very badly on me, as well.</p>
<p>Objective-C is how Apple wants developers to build apps for iOS. Choosing something else means swimming against the current and invites trouble later. At the very least, the pool of available talent is massively reduced. This puts my clients in a bad place if they can&#8217;t or won&#8217;t come back to me for updates.</p>
<p>My second concern is about programmer productivity. Xcode takes a lot of abuse, and Xcode 4 has been somewhat of a step back, but it&#8217;s still a pretty good IDE. I may in the minority, but I really like the wordiness of the Cocoa APIs and the way that Objective-C&#8217;s mixes arguments into the middle of method names. For any method that takes more than two arguments, this naming style saves me from needing to remember things. Xcode&#8217;s code completion is crucial to this, though. When it stops working, writing to the Cocoa APIs is painful.</p>
<p>One of RubyMotion&#8217;s selling points is that I get to use my preferred editor. Does any text editor offer intelligent code completion for classes from both frameworks and my own source files, without a manual indexing step? If not (and I doubt it, since it&#8217;s a big job), then I&#8217;m back to having to remember things, and a lot more than just the order of method arguments.</p>
<p>RubyMotion also throws Interface Builder out. The promise is that you&#8217;ll build interfaces in code, using an ASCII art style similar to Cocoa Autolayout. I don&#8217;t see this as anything other than an admission that RubyMotion <em>can&#8217;t</em> work with IB. It is a huge weakness, perhaps worse than the code completion problem.</p>
<p>RubyMotion is an interesting idea, but I won&#8217;t consider it for anything more than prototyping in the near term.</p>
<p><strong>Update:</strong> Ian Phillips demonstrates that <a href="http://ianp.org/2012/05/07/rubymotion-and-interface-builder/">it is possible to use Interface Builder</a>, but very minimally. You can lay out the interface, but that&#8217;s it. No outlets, no actions and no storyboards (which are great, if you haven&#8217;t tried them yet). A big part of what makes the Cocoa + IB combination so wonderful is that we can freeze dry a set of objects that make up an interface and later recreate them, with all their connections intact. This work must still be done in code with RubyMotion, which is ugly. Until RubyMotion can support NIBs 100%, it might be better not to use them at all.</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%2Frubymotion%2F&#038;seed_title=RubyMotion/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>VC Is Destroying the Software Business</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F03%2Fvc-is-destroying-the-software-business%2F&#038;seed_title=VC+Is+Destroying+the+Software+Business</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F03%2Fvc-is-destroying-the-software-business%2F&#038;seed_title=VC+Is+Destroying+the+Software+Business#comments</comments>
		<pubDate>Tue, 06 Mar 2012 14:45:52 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Entrepreneurship]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=835</guid>
		<description><![CDATA[I&#8217;ve had this post bubbling around in my head for the past day or so. I almost wrote it yesterday, but decided not to. Then Tim Bray wrote about who gets the mobile money: A river of gold for the people who build good phones. Another river for the people who run the networks. And [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had this post bubbling around in my head for the past day or so. I almost wrote it yesterday, but decided not to. Then Tim Bray wrote about <a href="http://www.tbray.org/ongoing/When/201x/2012/03/04/Mobile-Money">who gets the mobile money</a>:</p>
<blockquote><p>A river of gold for the people who build good phones. Another river for the people who run the networks. And for the developers, crumbs.</p></blockquote>
<p>I&#8217;m going to take a leap here and blame it on venture capital.<span id="more-835"></span></p>
<p>One thing you won&#8217;t find a venture-backed hardware startup doing is giving away their product. For consumer software and service startups, however, this is common. Consumers are now conditioned to expect that software, whether it&#8217;s a website or an app, is free.</p>
<p>The unfortunate part of this that the average person won&#8217;t look far enough down the road to see that not paying for something they value (in some form) now will often mean that it disappears entirely later. See Maciej Cegłowski&#8217;s wonderfully snarky discussion of the <a href="http://pinboard.in/talks/biz.pdf">business of bookmarking</a> (PDF).</p>
<p>Growing a business without VC takes time. It means growing slowly, increasing headcount and expenses as revenue grows. With VC, a business can grow very quickly and work on solving big problems from the start. This isn&#8217;t a bad thing, but in the Internet age, it now also means ignoring revenue. That isn&#8217;t sustainable, and if you don&#8217;t figure out how to sell something by the time the funding runs out, you&#8217;re done.</p>
<p>There is nothing wrong or shameful in exchanging software or a service for money. The creation of these things is a skilled task that takes years to master. We don&#8217;t expect plumbers or carpenters to give away their expertise for free. Why should software developers?</p>
<p>The latest example of this decline in how we value software is from Readability. To be fair, as near as I can tell, they aren&#8217;t venture funded, but they suffer from the same symptoms. Their app is free, yet clearly they retain a faint memory of what running a business means because they offer an &#8220;optional contribution&#8221; in-app purchase for $5. It is a tacit acknowledgement that software requires time, effort and expertise to create, yet I&#8217;m left with the impression that they are embarrassed to ask for money. It is deplorable. Meanwhile, the king of the vertical, Instapaper, costs $5 up front, same as it&#8217;s been from nearly the beginning.</p>
<p>The wasted billions of VC is making it awfully hard for the rest of us to make a living selling software.</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%2Fvc-is-destroying-the-software-business%2F&#038;seed_title=VC+Is+Destroying+the+Software+Business/feed/</wfw:commentRss>
		<slash:comments>3</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>Why Software Projects Are Regularly Late</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fwhy-software-projects-are-regularly-late%2F&#038;seed_title=Why+Software+Projects+Are+Regularly+Late</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fwhy-software-projects-are-regularly-late%2F&#038;seed_title=Why+Software+Projects+Are+Regularly+Late#comments</comments>
		<pubDate>Mon, 30 Jan 2012 15:17:09 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Consulting]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=825</guid>
		<description><![CDATA[Michael Wolfe provides an excellent answer to the question of why software development estimates are regularly off by a factor of 2-3: Let&#8217;s take a hike on the coast from San Francisco to Los Angeles to visit our friends in Newport Beach. Other answers point out that coming to a task with related experience certainly [...]]]></description>
			<content:encoded><![CDATA[<p>Michael Wolfe provides an excellent answer to the question of <a href="http://www.quora.com/Engineering-Management/Why-are-software-development-task-estimations-regularly-off-by-a-factor-of-2-3/answer/Michael-Wolfe">why software development estimates are regularly off by a factor of 2-3</a>:</p>
<blockquote><p>Let&#8217;s take a hike on the coast from San Francisco to Los Angeles to visit our friends in Newport Beach.</p></blockquote>
<p><span id="more-825"></span></p>
<p>Other answers point out that coming to a task with related experience certainly helps, but just because you&#8217;re an experienced hiker doesn&#8217;t mean you know how long it&#8217;ll take to hike an entirely new trail. Even if you&#8217;ve hiked a particular trail before, it doesn&#8217;t prepare you for mud, wildlife or broken ankles.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fwhy-software-projects-are-regularly-late%2F&#038;seed_title=Why+Software+Projects+Are+Regularly+Late/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bundler 1.1 Prerelease is Worth It</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fbundler-1-1-prerelease-is-worth-it%2F&#038;seed_title=Bundler+1.1+Prerelease+is+Worth+It</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fbundler-1-1-prerelease-is-worth-it%2F&#038;seed_title=Bundler+1.1+Prerelease+is+Worth+It#comments</comments>
		<pubDate>Fri, 20 Jan 2012 17:03:28 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Ruby & Rails]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=820</guid>
		<description><![CDATA[In two posts from last year, Pat Shaughnessy discusses why Bundler 1.1 will be much faster and how to use some of the new features. Ordinarily, I avoid prerelease gems because I don&#8217;t want to risk the stability of an application. My release schedule won&#8217;t often align with a gem&#8217;s, assuming there is one. I [...]]]></description>
			<content:encoded><![CDATA[<p>In two posts from last year, Pat Shaughnessy discusses why Bundler 1.1 will be <a href="http://patshaughnessy.net/2011/10/14/why-bundler-1-1-will-be-much-faster">much faster</a> and how to use some of the <a href="http://patshaughnessy.net/2011/11/5/besides-being-faster-what-else-is-new-in-bundler-1-1">new features</a>. Ordinarily, I avoid prerelease gems because I don&#8217;t want to risk the stability of an application. My release schedule won&#8217;t often align with a gem&#8217;s, assuming there is one.<span id="more-820"></span></p>
<p>I finally realized today that this doesn&#8217;t matter. Unlike the rest of the gems your Rails application uses, Bundler lives above the fray. It is perfectly safe to use a prerelease version of Bundler on your development machine and stick to the stable release on your production servers.</p>
<p>I encourage you to give it a try. <tt>bundle install</tt> imposes practically no overhead over the actual gem installation time, and <tt>bundle outdated</tt> is tremendously useful when planning for gem updates.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ gem install bundler --pre</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%2Fbundler-1-1-prerelease-is-worth-it%2F&#038;seed_title=Bundler+1.1+Prerelease+is+Worth+It/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git: HTTPS Repository + Access Control</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fgit-https-repository-access-control%2F&#038;seed_title=Git%3A+HTTPS+Repository+%2B+Access+Control</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fgit-https-repository-access-control%2F&#038;seed_title=Git%3A+HTTPS+Repository+%2B+Access+Control#comments</comments>
		<pubDate>Mon, 09 Jan 2012 21:04:50 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=807</guid>
		<description><![CDATA[I&#8217;ve slowly switched to Git from Subversion over the last year or so, and lately I have begun to feel dissatisfied with my repository configuration. In this post, I&#8217;ll outline how to set up Git in a central repository model, exporting repositories over HTTP(S) and allowing for fine-grained access control. Though it goes against the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve slowly switched to Git from Subversion over the last year or so, and lately I have begun to feel dissatisfied with my repository configuration. In this post, I&#8217;ll outline how to set up Git in a central repository model, exporting repositories over HTTP(S) and allowing for fine-grained access control.<span id="more-807"></span></p>
<p>Though it goes against the spirit of Git, I prefer the central repository model for two reasons. The first is backups. With a central repository, I only have to think about backing up one place to an off-site location. The second is access. My primary development system is a desktop, but I do occasionally take a laptop on the road. It&#8217;s easier to pull relatively recent source from a central, Internet-facing repository than it is to tunnel back into my network. I also do a lot of Rails work, and it&#8217;s simplest for <a href="https://github.com/capistrano/capistrano/wiki/">Capistrano</a> to pull from an Internet-facing repository.</p>
<p>So my goals are:</p>
<ul>
<li>Public repositories are available over plain HTTP without authentication</li>
<li>Pushing into a public repository requires authenticated HTTPS
<li>Private repositories are only available over HTTPS and require authentication for any access</li>
<li>The ability to allow a user access to only a subset of private repositories</li>
</ul>
<p>Some details of the discussion will only be applicable to Debian/Ubuntu systems, but are easily adapted to other distributions.</p>
<p>The first step is creating a central repository.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ cd /home/git
$ mkdir repo-name.git &amp;&amp; cd repo-name.git
$ git --bare init
$ sudo chown -R www-data:www-data .</pre></div></div>

<p>Next, you need to set up Apache to serve this repository. I use the <a href="http://progit.org/2010/03/04/smart-http.html">smart HTTP</a> transport supported by Git 1.6.6 and later, which is nearly as fast as the <tt>git://</tt> protocol, but doesn&#8217;t require poking a hole in the firewall. Add this to your appropriate virtual host configuration.</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:<span style="color: #ff0000;">80</span>&gt;
        <span style="color: #00007f;">ServerName</span> YOUR-SERVER-NAME
        <span style="color: #00007f;">ErrorLog</span> /var/log/apache2/git-error.log
        <span style="color: #00007f;">CustomLog</span> /var/log/apache2/git-access.log combined
&nbsp;
        <span style="color: #00007f;">DocumentRoot</span> /home/git
        <span style="color: #00007f;">SetEnv</span> GIT_HTTP_EXPORT_ALL
        <span style="color: #00007f;">SetEnv</span> GIT_PROJECT_ROOT /home/git
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Let Apache serve static files</span>
        <span style="color: #00007f;">AliasMatch</span> ^/(.*/objects/[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">2</span>}/[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">38</span>})$          /home/git/$1
        <span style="color: #00007f;">AliasMatch</span> ^/(.*/objects/pack/pack-[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">40</span>}.(pack|idx))$ /home/git/$1
&nbsp;
        <span style="color: #00007f;">ScriptAlias</span> / /usr/lib/git-core/git-http-backend/
&nbsp;
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /home/git&gt;
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Options</span> +ExecCGI -<span style="color: #0000ff;">Includes</span>
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        &lt;<span style="color: #000000; font-weight:bold;">Location</span> /&gt;
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
                <span style="color: #00007f;">Deny</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;
&nbsp;
        &lt;<span style="color: #000000; font-weight:bold;">LocationMatch</span> ^/public-repo.git&gt;
                <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">LocationMatch</span>&gt;
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;
&nbsp;
<span style="color: #adadad; font-style: italic;"># mod_authn_alias essentially configures groups of users.</span>
&lt;<span style="color: #000000; font-weight:bold;">AuthnProviderAlias</span> file internal&gt;
        <span style="color: #00007f;">AuthUserFile</span> /etc/apache2/git-internal.htpasswd
&lt;/<span style="color: #000000; font-weight:bold;">AuthnProviderAlias</span>&gt;
&nbsp;
&lt;<span style="color: #000000; font-weight:bold;">AuthnProviderAlias</span> file clients&gt;
        <span style="color: #00007f;">AuthUserFile</span> /etc/apache2/git-clients.htpasswd
&lt;/<span style="color: #000000; font-weight:bold;">AuthnProviderAlias</span>&gt;
&nbsp;
&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> YOUR-SERVER-IP:<span style="color: #ff0000;">443</span>&gt;
        <span style="color: #00007f;">SSLEngine</span> <span style="color: #0000ff;">on</span>
        <span style="color: #00007f;">SSLCertificateFile</span> PATH-TO-YOUR-CERTIFICATE-FILE
&nbsp;
        <span style="color: #00007f;">ServerName</span> YOUR-SERVER-NAME
        <span style="color: #00007f;">ErrorLog</span> /var/log/apache2/git-error.log
        <span style="color: #00007f;">CustomLog</span> /var/log/apache2/git-access.log combined
&nbsp;
        <span style="color: #00007f;">DocumentRoot</span> /home/git
        <span style="color: #00007f;">SetEnv</span> GIT_HTTP_EXPORT_ALL
        <span style="color: #00007f;">SetEnv</span> GIT_PROJECT_ROOT /home/git
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Let Apache serve static files</span>
        <span style="color: #00007f;">AliasMatch</span> ^/(.*/objects/[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">2</span>}/[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">38</span>})$          /home/git/$1
        <span style="color: #00007f;">AliasMatch</span> ^/(.*/objects/pack/pack-[<span style="color: #ff0000;">0</span>-9a-f]{<span style="color: #ff0000;">40</span>}.(pack|idx))$ /home/git/$1
&nbsp;
        <span style="color: #00007f;">ScriptAlias</span> / /usr/lib/git-core/git-http-backend/
&nbsp;
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /home/git&gt;
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Options</span> +ExecCGI -<span style="color: #0000ff;">Includes</span>
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Require authentication to all repositories</span>
        &lt;<span style="color: #000000; font-weight:bold;">Location</span> /&gt;
                <span style="color: #00007f;">AuthBasicProvider</span> internal
                <span style="color: #00007f;">AuthType</span> Basic
                <span style="color: #00007f;">AuthName</span> <span style="color: #7f007f;">&quot;Git&quot;</span>
                <span style="color: #00007f;">Require</span> valid-<span style="color: #00007f;">user</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Allow both internal and client users to access this repository.</span>
        &lt;<span style="color: #000000; font-weight:bold;">Location</span> /client-repo.git&gt;
                <span style="color: #00007f;">AuthBasicProvider</span> internal clients
                <span style="color: #00007f;">AuthType</span> Basic
                <span style="color: #00007f;">AuthName</span> <span style="color: #7f007f;">&quot;Git&quot;</span>
                <span style="color: #00007f;">Require</span> valid-<span style="color: #00007f;">user</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</pre></div></div>

<p>Create the password file. Remember to set user and group ownership and permissions appropriately.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ sudo htpasswd -m -c /etc/apache2/git-internal.htpasswd &lt;user&gt;
$ sudo chown root:www-data /etc/apache2/git-internal.htpasswd
$ sudo chmod 640 /etc/apache2/git-internal.htpasswd</pre></div></div>

<p>Repeat the <tt>htpasswd</tt> command once for each user, dropping the <tt>-c</tt> option (which creates the file, or truncates if it already exists) for subsequent users.</p>
<p>For each repository you want to export, you must run <tt>git update-server-info</tt> once by hand, and enable the post-update hook to do the same. On Debian, the sample post-update hook already does it, but it must be renamed to enable it.</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ cd /home/git
$ foreach r in *; do (cd $r; git update-server-info; \
    mv hooks/post-update.sample hooks/post-update); done</pre></div></div>

<p>For any existing repositories that you push to, writes to those files is now done by Apache, so you must change the ownership of all of the files in the central repository to the web server user (<tt>www-data</tt> on Debian).</p>
<p>The final roadblock is that I use a wildcard, self-signed SSL certificate. Git refuses to accept these unless you approve it. There are two ways to do that.</p>
<ol>
<li>The simple, but insecure way: set <tt>http.sslVerify = false</tt> in your <tt>~/.gitconfig</tt>. This turns off certificate verification for all HTTPS remotes.</li>
<li>The more secure, complicated way: preface any command that talks to the remote (<tt>clone</tt>, <tt>push</tt>) with <tt>GIT_SSL_NO_VERIFY=1</tt>. Once you have a local copy, you can also edit its <tt>.git/config</tt> and add a new <tt>http</tt> section with the <tt>sslVerify = false</tt> setting.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Fgit-https-repository-access-control%2F&#038;seed_title=Git%3A+HTTPS+Repository+%2B+Access+Control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lights Post-Mortem</title>
		<link>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Flights-post-mortem%2F&#038;seed_title=Lights+Post-Mortem</link>
		<comments>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Flights-post-mortem%2F&#038;seed_title=Lights+Post-Mortem#comments</comments>
		<pubDate>Thu, 05 Jan 2012 16:11:30 +0000</pubDate>
		<dc:creator>Steve Madsen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://lightyearsoftware.com/?p=782</guid>
		<description><![CDATA[After two full seasons in the App Store, it&#8217;s a good time to look at how Lights Finder has performed and examine some of the metrics. Marketing By far the biggest problem for the small developer in the App Store is visibility. We cannot rely on Apple to market our apps. Getting featured is akin [...]]]></description>
			<content:encoded><![CDATA[<p>After two full seasons in the App Store, it&#8217;s a good time to look at how <a href="http://lightyearsoftware.com/products/christmas-lights-finder/">Lights Finder</a> has performed and examine some of the metrics.<span id="more-782"></span></p>
<h2>Marketing</h2>
<p>By far the biggest problem for the small developer in the App Store is visibility. We cannot rely on Apple to market our apps. Getting featured is akin to winning the lottery; it&#8217;s great, but we can&#8217;t count on it. Nothing has changed from selling software before the App Store: we still have to figure out how to market it.</p>
<p>In both 2010 and 2011, I used <a href="http://prmac.com/">prMac</a> to send a press release to iOS-related news outlets. With the exception of some automated repostings of the press release, neither year resulted in any real editorial coverage. I also submitted the app to many iOS review sites. Again, nothing came of this.</p>
<p>I did three things in 2010 that I did not repeat in 2011: a screencast, mostly for review submissions, advertising (Facebook and AdMob, neither were worthwhile), and a free weekend in early December.</p>
<p>Last year, I priced the app at 99¢, figuring that it would appeal to the mass market audience and be a good impulse buy. Sales were disappointing, so for 2011 I figured I had little to lose and raised the price to $1.99. The free weekend in 2010 didn&#8217;t boost visibility at all, and since weekends are the biggest sales days of the week for this app, I felt no need to repeat the experiment.</p>
<p>Excluding the free downloads, year-over-year sales for December were up 13%. Apple hasn&#8217;t announced earnings for the quarter including December 2011 yet, but for the <a href="http://www.apple.com/pr/library/2011/10/18Apple-Reports-Fourth-Quarter-Results.html">prior quarter</a>, iPhone sales were up 21% year-over-year. My sales lagged overall iPhone growth, but it&#8217;s still growth and customers seemed no less willing to buy at $2 than $1.</p>
<h2>Design</h2>
<p>Lights Finder is a classic &#8220;scratch my own itch&#8221; app. For years, since I was a kid, my family set out once or twice a year to drive around and look at lights. I moved to Columbus in 2006. In a new place, it isn&#8217;t obvious which neighborhoods are good to visit and which are mostly dark. Young children have short attention spans and aimless wandering isn&#8217;t very popular.</p>
<p>For the first version, I was fine investing time, but gave myself a very limited budget, which meant I had to design it as best as I could myself. The result was serviceable, but far from polished.</p>
<p>For 2011, my biggest goal was to get rid of the programmer art and work with a professional designer. I have mixed feelings about my decision. While I am very happy with the result, sales didn&#8217;t cover the costs. It&#8217;s hard to justify spending thousands on a personal project when sales don&#8217;t cover costs.</p>
<h2>Technology</h2>
<p>In 2010, I supported iOS 3.1 and later. At the time, this followed the common &#8220;current version plus the previous major release&#8221; advice. For 2011, I stuck with this, but a year later that meant iOS 4 and 5. Since any device that can run iOS 4.0 can run 4.2 (and should, given how sluggish 4.0 is on iPhone 3G), I set the minimum version at 4.2.</p>
<p>This allowed me to delete quite a bit of code, modernize my API usage, and, most importantly, convert the project to ARC.</p>
<p>ARC is wonderful. There isn&#8217;t even one crash report in iTunes Connect, on any iOS version.</p>
<p>Next year, and for every new app, I will only target iOS 5 and later, though. Take a look at these charts:</p>
<p><img src="http://lightyearsoftware.com/wp-content/uploads/2011/12/2011-metrics.png" alt="Graph of metrics from Lights Finder 2011 season" title="Graph of metrics from Lights Finder 2011 season" width="628" height="207" class="alignnone size-full wp-image-799" /></p>
<p>For the sake of completeness, the chart on the left shows the breakdown by device type. Unsurprisingly, most people used the app on their iPhones.</p>
<p>The next two are the pleasant surprise. The middle apes Marco Arment&#8217;s <a href="http://www.marco.org/2011/11/30/more-ios-device-and-os-version-stats-from-instapaper">device and OS stats from Instapaper</a>. Almost 78% of Lights Finder users were already on iOS 5, and 90% were at 4.3 or later. Of course, anything running 4.3 can also run 5.0, but it turns out that quite a few people running 5.0-capable hardware were still using 4.2 or earlier. Fully 99% of users were on a device that is <em>capable</em> of running iOS 5!</p>
<p>While I don&#8217;t feel like sharing raw numbers, I acknowledge my sample size isn&#8217;t nearly as large as Instapaper&#8217;s. Still, I&#8217;m encouraged by the data. Lights Finder is as likely to be used by casual people as technology nerds. iOS 5 has only been available for a couple of months, and the lagging 21% will upgrade eventually, especially if more apps require it. Looking forward from iOS 5, adoption should be even faster with over-the-air updates.</p>
<h2>Customer Support</h2>
<p>Based on a presentation a few months back at <a href="http://groups.google.com/group/cidug">CIDUG</a>, I decided to add a link on the about screen soliciting feedback. This resulted in some ego-bruising moments, but overall it was a good choice. Some people wrote in with a question, and it was nice to have the opportunity to help them. It also allowed me to ask for a review, and several obliged.</p>
<p>Others were unhappy and demanding refunds, sometimes rudely. I suspect most of these people never expected an answer, and some became much nicer after I sent one. I tried to be helpful, explained that App Store developers can&#8217;t issue refunds, and how to contact Apple about one. (To date, <a href="http://www.ideaswarm.com/AppViz2.html">AppViz</a> shows no refunds.)</p>
<p>It is disappointing that people can get so worked up about a $2 app. These are probably the same people who spend $2 on a lousy cup of restaurant coffee and don&#8217;t think twice about it. If an app doesn&#8217;t meet their lofty expectations, though? A venomous 1 star review and demands for a refund.</p>
<p>Giving these people a quicker route to vent their disappointment than an App Store review likely worked in a few cases. Often, they were unhappy because the directory, while robust, didn&#8217;t have excellent coverage in their area. I asked where they lived and, for those that replied, dug up some addresses from Google. In the long run, it makes the app better, but it left me feeling bitter about doing so much for $2 (well, $1.40) and rewarding rudeness.</p>
<p>The upside is that about 30% of the people who used the app in 2010 came back in 2011. That doesn&#8217;t seem very high, but it&#8217;s likely that half of the 2010 users acquired the app during the free weekend, used it once, then forgot about it. If most of the returning users were the ones that paid, that bodes well for 2012 and beyond. Eventually, the holes in the directory will be filled, and maybe one day Apple will decide it has a place in the holiday apps feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyearsoftware.com/feeder/?FeederAction=clicked&#038;feed=Articles+%28RSS2%29&#038;seed=http%3A%2F%2Flightyearsoftware.com%2F2012%2F01%2Flights-post-mortem%2F&#038;seed_title=Lights+Post-Mortem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.988 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-18 11:43:53 -->

