Automatic Git Revision Stamping for App Store Projects

Posted by: on Nov 2, 2010 in Blog | Tags: , , , , , | No Comments

Following up on my post about automatic Subversion revision stamping, here is a modified script for use with Git-based projects.

Read More

Option-Click to Reposition Cursor in Terminal

Posted by: on Oct 7, 2010 in Blog | Tags: , | 3 Comments

I found this on SuperUser today and just have to share it.

In Terminal, you can reposition the cursor on a line by option-clicking where you want it to go. Credit where due.

It doesn’t happen every day, but certainly a few times a week: I end up with a monster command, spanning two full 100 character wide lines or more. Inevitably, there’s an error in there in the middle, and I sit waiting, holding down left-arrow to fix it and try again.

How to Set Up Internet Sharing on Mac OS X

Posted by: on Jun 10, 2010 in Blog | Tags: , | No Comments

These days, it’s not uncommon to be faced with the situation of having two or more Wi-Fi devices you might wish to use in a hotel room when the hotel does not provide free in-room Wi-Fi. The hotel doesn’t know that those devices are all yours and in one room, so using them means paying per device, which is crazy.

This explains how to easily set up Internet connection sharing in Mac OS X 10.6 so you can pay once, and piggyback the rest of your devices off that one laptop. These instructions assume that you have a wired Ethernet connection available in the room.

  1. Plug in your laptop to the Ethernet, pay and get it working.
  2. Go to System Preferences -> Network. Take note of the IP address, router and one DNS server.
  3. Ethernet connection settings

  4. There are three IP address ranges reserved for private use: 10.x.x.x, 172.{16-31}.x.x and 192.168.x.x. Looking at the IP address, router and DNS address from the previous step, pick one of those ranges that is unused. You’ll use this for the wireless network you create shortly. For example, the router is in 10.1.x.x and the DNS server is in 172.16.x.x, so I’ll use 192.168.x.x.
  5. You may find it easiest if you’re moving between locations to create a new network location for this Internet sharing configuration. You can do that in the Location drop-down at the top of the System Preferences window.
  6. Still in the Network part of System Preferences, choose AirPort, then click Advanced. Go to the TCP/IP tab.
  7. Pick any IP address in your chosen range, with a matching subnet mask. 10.x.x.x should use 255.0.0.0, 172.16.x.x should use 255.255.0.0, and 192.168.x.x should use 255.255.0.0. Enter the same router address you copied down from the Ethernet configuration. For this post, I’ll use 192.168.1.1.
  8. Wireless connection TCP/IP settings window

  9. Go to the System Preferences -> Sharing. Click the Internet Sharing item, but not the checkbox next to it. This should show “share your connection from” is Ethernet, and “to computers using” has AirPort checked. Click AirPort Options.
  10. Internet Sharing options dialog

  11. Pick a network name. I also recommend turning on 128-bit WEP. It’s not great, but it’s better than nothing. You need to pick a password, which unfortunately must be exactly 13 characters.
  12. Click the checkbox next to Internet Sharing and Start in the scary warning dialog that follows.
  13. From one of your other devices, you can now connect to your new wireless network. You will have to configure its IP address manually, since your Mac is not running a DHCP server to supply it.
  14. Use another, different address for your wireless device, but in the same network as the AirPort you just set up. Since it’s using 192.168.1.1, I’ll use 192.168.1.2. Use the same subnet mask, but use the AirPort’s IP (192.168.1.1) as the router. Use the DNS IP you copied down in step #2.
  15. an example of wireless network settings on an iPhone

That’s it: you should now be able to use the Internet from your wireless device, via your laptop plugged into the Ethernet.

Automatic Subversion Revision Stamping for iPhone Projects

Posted by: on May 26, 2010 in Blog | Tags: , , , , | 2 Comments

Early during development of a new iPhone OS application, I discovered that App Store submissions must use a strict format for the CFBundleVersion key in the Info.plist file. It can only be numbers and dots. This left me a little frustrated with how to version pre-1.0 releases to testers. I didn’t want to use an open-source style “0.9” and yet it wasn’t 1.0. What I really wanted was “1.0 b1” or similar.

I stumbled on Daniel Jalkut’s post about automatically stamping the Subversion revision into Info.plist and thought that might be a good way to go. I also created a new key in Info.plist, LYSApplicationDisplayVersion, that I use as a human-friendly version string, which is where I get my preferred “1.0 b1” form. CFBundleVersion now takes the form of major.minor.revision, where major and minor are the important parts of the human-friendly version (“1.0”) and revision is the Subversion revision number that produced the binary.

I like this method because it solves one problem raised by commenters on Daniel’s post. Because the Subversion revision is the third component, it doesn’t matter that r3999 is a mature 1.2 point release and r4000 is a risky pre-2.0 alpha for testers. Those versions end up 1.2.3999 and 2.0.4000 and it’s clear that they are from two different branches of development. For iPhone Ad Hoc distribution, iTunes also parses the version properly and knows that 1.0.100 is newer than 1.0.95.

Here is the script to paste into your custom script build phase:

# Xcode auto-versioning script for Subversion
# by Axel Andersson, modified by Daniel Jalkut to add
# "--revision HEAD" to the svn info line, which allows
# the latest revision to always be used.
 
use strict;
 
die "$0: Must be run from Xcode" unless $ENV{"BUILT_PRODUCTS_DIR"};
 
# Get the current subversion revision number and use it to set the CFBundleVersion value
my $REV = `/usr/bin/svnversion -n ./`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Info.plist";
 
my $version = $REV;
 
# (Match the last group of digits and optional letter M/S/P):
 
# ugly yet functional (barely) regex by Daniel Jalkut:
#$version =~ s/([\d]*:)(\d+[M|S]*).*/$2/;
 
# better yet still functional regex via Kevin "Regex Nerd" Ballard
($version =~ m/(\d+)([MSP]*)$/) && ($version = $1);
 
die "$0: No Subversion revision found" unless $version;
die "$0: Modified, switched or partial working copy, you sure about that?" if $2 && ($ENV{"BUILD_STYLE"} eq "Ad Hoc" || $ENV{"BUILD_STYLE"} eq "App Store");
 
open(FH, "plutil -convert xml1 \"$INFO\" -o - |") or die "$0: $INFO: $!";
my $info = join("", <FH>);
close(FH);
 
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>\d+\.\d+).*?(<\/string>)/$1.$version$2/;
 
open(FH, "| plutil -convert binary1 - -o \"$INFO\"") or die "$0: $INFO: $!";
print FH $info;
close(FH);

There are a couple of other changes to this script for Subversion 1.5 and later, and for iPhone OS targets.

The first is that the regular expression allows for a trailing P in the Subversion revision. This signals a working copy from a sparse checkout, which I never use and therefore may be a problem. I have the script fail if any letter is appended to the revision when the BUILD_STYLE is “Ad Hoc” or “App Store”, which are two new configurations, cloned from Release, that I use for Ad Hoc and App Store distribution, respectively. Especially for modified working copies: I never want to accidentally hand out a build made from a modified working copy. Should the day come that I really do, I can comment this line out, make the build, and uncomment it again.

The second is that iPhone projects convert Info.plist to the binary plist format in the application bundle. In order to extract the existing CFBundleVersion key, it must be converted back to XML. When writing the plist back out, it is again converted to binary. Both of these steps use plutil, which is part of the Developer Tools.

Safari’s Web Inspector in Nightly

Posted by: on Oct 1, 2008 in Blog | Tags: , | No Comments

Surfin’ Safari has a great post talking about some recent improvements to the Web Inspector in the latest WebKit nightly builds. Safari’s Web Inspector has long been a really great tool for examining the DOM and simple profiling of a requested page and its resources, but these new updates make it a serious tool for web developers.

If you’ve never tried a WebKit nightly build before, it is easy (on a Mac, anyway) to run it side-by-side with Safari. You don’t have to give up your stable, released browser to check out these new features. Still, it will be very nice when these improvements make it into an official release.

For Firefox users, YSlow is a very nice extension built on top of Firebug that provides a detailed report card on page load performance, including suggestions for improving it.

What else might be in Snow Leopard?

Posted by: on Jun 12, 2008 in Blog | Tags: | No Comments

Apple Inc. announced Mac OS X 10.6 “Snow Leopard” at WWDC’08 on Monday, but other than a press release and a page each for 10.6 Client and Server, very little information was given that isn’t covered under the WWDC NDA.

Still, one “feature” is interesting, especially in the face of (mostly confirmed) rumors that 10.6 will drop support for the PowerPC:

Snow Leopard dramatically reduces the footprint of Mac OS X, making it even more efficient for users, and giving them back valuable hard drive space for their music and photos.

Dropping PowerPC will save reduce the size of executable code by around 50%. Here is the output of otool -f for iTunes:

Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 18
    cpusubtype 0
    capabilities 0x0
    offset 4096
    size 17345088
    align 2^12 (4096)
architecture 1
    cputype 7
    cpusubtype 3
    capabilities 0x0
    offset 17350656
    size 17053824
    align 2^12 (4096)

The PowerPC’s CPU type is 18 (look in /usr/include/mac/machine.h), so the PowerPC code in the main iTunes executable accounts for 50.4% of the total. I’m going to assume that this ratio will mostly hold true for frameworks, too.

The entire iTunes bundle is 122 MB, though. Trimming the 16.5 MB + 1 MB of bundled frameworks off of that is only about 14%; not what I’d call a “dramatic” footprint reduction. What else might they have planned?

Another couple of options are transparent compression at the filesystem layer and conversion of image resources to a vector format.

Apple’s own page says that read/write ZFS will be in 10.6 Server, so it’s reasonable to expect it will be in Client, too, perhaps with some of the more advanced features disabled. ZFS includes an option to transparently compress data. NTFS on Windows has had this for years, and third-party products did it on FAT years before that, so it’s entirely reasonable to expect that Macs will finally get this, too. 71% of the iTunes bundle is resources, mostly localizations, and inside those, the largest directories are for the in-app help, which is HTML.

Support for resolution independence has been rumored for years, and while Apple has supported it to some degree since 10.4, it hasn’t really caught on. Might they finally be converting all of the system image resources to a vector format? I don’t have any numbers on it, but a vector graphic is certain to take up much less space than a 512×512 PNG.