2718.us blog » Mac OS X http://2718.us/blog Miscellaneous Technological Geekery Tue, 18 May 2010 02:42:55 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 MacWJ: It’s like Windows Journal for Tablet Macs http://2718.us/blog/2010/05/07/macwj-its-like-windows-journal-for-tablet-macs/ http://2718.us/blog/2010/05/07/macwj-its-like-windows-journal-for-tablet-macs/#comments Fri, 07 May 2010 09:59:44 +0000 2718.us http://2718.us/blog/?p=263 MacWJ… because there are oh-so-many tablet Macs.  There are ModBooks and there are non-Apple tablet machines running Mac OS X.  So, if you have such a device and are looking for something that provides a surface on which to draw, write, etc., with various “pens” and with the ability to save to PDF and PNG, MacWJ may be of use to you. It’s open-source under MIT license.

MacWJ requires OS X 10.5 or newer and some sort of tablet-pen input, whether a tablet-form computer or a Wacom graphics tablet or something else of that sort.  Ready-to-run recent build(s) are available on bitbucket, as well as the full source code.

]]>
http://2718.us/blog/2010/05/07/macwj-its-like-windows-journal-for-tablet-macs/feed/ 0
Simplifying the Assembly of Localizations in Xcode http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/ http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/#comments Thu, 22 Apr 2010 20:11:51 +0000 2718.us http://2718.us/blog/?p=254 A comment on a bitbucket fork of Murky led me to “Automatically localize your nibs when building“, which suggests a great way to automate the hard developer-side stuff in localizing in Xcode–pulling the original strings from the XIB files and putting the translated strings back in.  You absolutely should read the original blog post there, because I cannot adequately explain the big-picture part of the idea with a short quote.

My one complaint with the setup described is that the script for the “Run Script” build phase described there is a maintenance headache that I could do without.  Here’s my solution:  Create two new build targets, both of the “Shell Script” type–these are targets that just run a shell script, so they are created with only a “Run Script” build phase.  I called my two new targets “Create/Update English .strings files” and “Create/Update l10n XIBs” but you can call them whatever you want.

In the “Create/Update English .strings files” target’s “Run Script” phase, the script is:

# Create/Update English .strings files
  1. for xibFile in "$PROJECT_DIR/English.lproj/"*.xib; do
  2.  ibtool –generate-strings-file "${xibFile}.strings" "$xibFile"
  3. done
  4. exit 0

This uses ibtool to create a strings file for every XIB in the English localization (from foo.xib, foo.xib.strings will be created).

In the “Create/Update l10n XIBs” target’s “Run Script” phase, the script is:

# Create/Update l10n XIBs
  1. originalResourceDirectory="$PROJECT_DIR/English.lproj"
  2. for localizedDirectory in "$PROJECT_DIR/"*.lproj; do
  3.  if [ localizedDirectory != originalResourceDirectory ]; then
  4.   for xibFile in "${originalResourceDirectory}/"*.xib; do
  5.    xibBaseName=$(basename "${xibFile}")
  6.    ibtool –strings-file "${localizedDirectory}/${xibBaseName}.strings" \
  7.     –write "${localizedDirectory}/${xibBaseName}" \
  8.     "$xibFile"
  9.   done
  10.  fi
  11. done
  12. exit 0

This goes through every .lproj directory except English.lproj and uses ibtool to apply the .xib.strings files in those localizations to the XIB files in English.lproj.

By having these as two separate targets, they aren’t run every time I build and each part can be run on its own, on demand.  By using the power of shell scripting, I avoid having to alter the scripts for every new localization or XIB.

]]>
http://2718.us/blog/2010/04/22/simplifying-the-assembly-of-localizations-in-xcode/feed/ 0
Integrating Version Control Revisions in Mac App Version Numbers http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/ http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/#comments Mon, 22 Mar 2010 13:57:26 +0000 2718.us http://2718.us/blog/?p=238 When I was using Subversion for version control in working on my Mac apps in Xcode, I had come to use a build script phase to tack on the subversion revision number as the last part to the version number:

# tack the subversion revision number onto the CFBundleVersion
  1. REV=`svnversion -n "${PROJECT_DIR}"`
  2. REV=${REV/#[0-9]*:/}
  3. REV=${REV//[^0-9]/}
  4. BASE=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${PROJECT_DIR}/Info.plist"`
  5. /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASE.$REV" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

This takes the CFBundleVersion from the project’s Info.plist, adds a period and the subversion revision number, and injects that into the Info.plist of the built product.

When I made the move to Mercurial, I couldn’t quite do this anymore.  While subversion revision numbers are monotone increasing and consistent everywhere (they are the unique identifiers of a particular version), Mercurial’s “revision numbers” are local to a particular instance of the repository and may not match up from one instance to another.  Mercurial uses a hash as the unique identifier of a particular version, and these hexadecimal hashes are not monotone, making them unsuitable for use in CFBundleVersion.

Though it took some time, I’ve finally come to a system with Mercurial that I think is workable:

# use the number of minutes between the tip and the most recent tagged commit
  1. HG_LAST_TAG_TIMESTAMP=$(/usr/local/bin/hg log -r "$(/usr/local/bin/hg log -r '.' –template '{latesttag}' –repository "${PROJECT_DIR}|>")" –template "{date|hgdate}\n" –repository "${PROJECT_DIR}" | cut -f1 -d' ')
  2. HG_TIP_TIMESTAMP=$(/usr/local/bin/hg log -r '.' –template "{date|hgdate}\n" –repository "${PROJECT_DIR}" | cut -f1 -d' ')
  3. REV=$(( ($HG_TIP_TIMESTAMP$HG_LAST_TAG_TIMESTAMP) / 60 ))
  4. BASE=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${PROJECT_DIR}/Info.plist"`
  5. /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASE.$REV" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

This calculates the number of minutes between the most recent tagged ancestor of the tip and the tip itself and adds that to the CFBundleVersion.  Because it’s time-based, it is guaranteed to be monotone increasing, consistent, and unique (well, provided multiple commits don’t happen within a 1-minute span, which is safe for me).

]]>
http://2718.us/blog/2010/03/22/integrating-version-control-revisions-in-mac-app-version-numbers/feed/ 0
A WebView Subclass with Isolated Cookie Storage http://2718.us/blog/2010/03/11/a-webview-subclass-with-isolated-cookie-storage/ http://2718.us/blog/2010/03/11/a-webview-subclass-with-isolated-cookie-storage/#comments Thu, 11 Mar 2010 07:38:14 +0000 2718.us http://2718.us/blog/?p=227 Following the advice of Kevin Ballard on StackOverflow, I created IGIsolatedCookieWebView, a subclass of WebView that does not access or affect the system-wide shared cookie storage (shared among all WebKit apps).  Each instance of IGIsolatedCookieWebView has its own cookie storage so that, for example, multiple instances of IGIsolatedCookieWebView within the same application can be logged in to the same web site with different credentials.  IGIsolatedCookieWebView should be usable in place of WebView, except that IGIsolatedCookieWebView uses the resource load delegate, so that can’t be used by the application.  IGIsolatedCookieWebView is published under a 3-clause BSD an MIT license.

]]>
http://2718.us/blog/2010/03/11/a-webview-subclass-with-isolated-cookie-storage/feed/ 0
A Drag-Resizable Subclass of NSComboBox http://2718.us/blog/2010/03/10/a-drag-resizable-subclass-of-nscombobox/ http://2718.us/blog/2010/03/10/a-drag-resizable-subclass-of-nscombobox/#comments Wed, 10 Mar 2010 09:57:02 +0000 2718.us http://2718.us/blog/?p=223 IGResizableComboBox is a drag-resizable subclass of NSComboBox—that is, IGResizableComboBox should be usable in place of NSComboBox and it adds a small bar at the bottom of the pop-up list that can be dragged to resize the pop-up list.  IGResizableComboBox is published under a 3-clause BSD an MIT license.

It still has some quirks:

  • behavior is strange when the pop-up is above the combo box (whereas it is usually below) [fixed; when the pop-up is above the combo box, the drag-handle is at the top and the top edge moves while the bottom edge stays fixed at the combo box]
  • the formula for resetting the number of visible items after dragging occurs is not quite right [fixed; dragging now snaps to whole-item positions]
]]>
http://2718.us/blog/2010/03/10/a-drag-resizable-subclass-of-nscombobox/feed/ 0
Unsticking the Mighty Mouse Scrollball http://2718.us/blog/2009/12/01/unsticking-the-mighty-mouse-scrollball/ http://2718.us/blog/2009/12/01/unsticking-the-mighty-mouse-scrollball/#comments Wed, 02 Dec 2009 02:34:43 +0000 2718.us http://2718.us/blog/?p=206 This information is provided as-is, with no warranty, etc., which is to say if you use this information at all, you do so at your own risk.

I’ve been using an Apple Mighty Mouse (bluetooth) for years now, so for years I’ve been dealing with a scrollball that occasionally gets stuck.  As someone who used to use mice that relied on a physical ball for tracking, this is nothing new.  The only real difference is that we can’t remove the scrollball to directly ungunk the mechanics.  My personal preferred way to ungunk/unstick/clean the scrollball (and mind you, for all I know, this might destroy your mouse) is to turn the mouse off, take a q-tip, soak up some denatured ethyl alcohol, and rub it around the scrollball, rolling the ball in every possible direction to try to get as much of the alcohol down and around the ball as possible, hoping to loosen up any gunk in the works there and bring it up top where it can be wiped away.  Typically, this unsticks the ball and brings some visible gunk and stuff to the topside.  It also helps to press down on the ball while rolling it around to ensure that it is moving the mechanical bits with which it has contact.  Let the mouse fully dry before turning it back on.

]]>
http://2718.us/blog/2009/12/01/unsticking-the-mighty-mouse-scrollball/feed/ 1
Best Drive Failure Ever http://2718.us/blog/2009/10/27/best-drive-failure-ever/ http://2718.us/blog/2009/10/27/best-drive-failure-ever/#comments Tue, 27 Oct 2009 23:27:05 +0000 2718.us http://2718.us/blog/?p=194 I suppose it’s a bit misleading to call the least bad something the “best.”  This past weekend, I experience a harddrive failure–a 2-year-old WD RE2 0.5TB drive failed before its 5-year warranty was up and well before its MTBF (1.2 million hours = 136.895463 years).  It’s been a while since I had a drive fail on me (excepting the hanging behavior of the 1.5TB Seagate drives, which isn’t really failure), but I’ve had plenty of drives fail over the course of 25 years of computing.  With the luckier failures, I didn’t lose anything important.

What’s noteworthy about this failure, though, is that it’s the first time I’ve had a drive fail and lost absolutely nothing.  The drive was half of a software RAID1 setup.  OS X’s Disk Utility showed the drive with SMART status “failing” and showed the RAID as “degraded” but was still able to make a complete copy of the RAID to another drive.  Even supposing the RAID hadn’t survived, all of my data except possibly the most recent hour is backed up to yet another drive via Time Machine.

I’m not going to claim the system is bulletproof (I’m sure it isn’t), but it is nice to see a redundancy/backup plan actually work when tested by the real world.  I’m just waiting on a cross-shipped replacement from WD to rebuild the RAID.

Remember: it’s not if your harddrive fails, it’s when your harddrive fails.  Drive failure is inevitable.

Edit: The replacement from WD was shipped next-day air, so I’ll have the new drive tomorrow.  First business day to process the RMA, second business day to ship the replacement, and the replacement arrives on the third business day.  Pretty fast.

]]>
http://2718.us/blog/2009/10/27/best-drive-failure-ever/feed/ 0
Mac Pro (2007) Bluetooth http://2718.us/blog/2009/10/26/mac-pro-2007-bluetooth/ http://2718.us/blog/2009/10/26/mac-pro-2007-bluetooth/#comments Mon, 26 Oct 2009 05:59:57 +0000 2718.us http://2718.us/blog/?p=191 I’ve had my Mac Pro for over 2 years now and for much of that time I’ve been resigned to the idea that my Apple Wireless Keyboard and Mighty Mouse were just not going to work well more than 6 inches from the front-lower-right corner of the Mac Pro case.  Early on, after I’d had the machine a month or two, I mentioned it to my brother-in-law, who told me that he’d seen some talk online about bluetooth range issues, but that he was fairly certain it was all resolved before my machine was manufactured.  In fact, that’s what most of the bits I could find seemed to indicate–the incidence of Mac Pros with bad bluetooth range dropped dramatically in early 2007.

Dropped dramatically, but not entirely.  The underlying issue seems to be mislabeled antenna wires.  I’d made an earlier pass at trying this fix, but failed because I couldn’t find any of the other wires I was supposed to use in place of the one labeled “BT” that was attached to my bluetooth module.  Just now, however, with some more disassembly, I was able to find the other wires, swap the “BT” wire for the only other wire long enough to reach, and now my keyboard and mouse work from across the room.

Details:  Read this and this.  Open the case, remove all four SATA brackets/drives.  If you can see all four antenna wires, great, go for it!  (That is, swap the “BT” wire for the only other wire long enough to reach.  If you’ve got the Airport module, see those two links to figure out how to deal with those wires.)  If not, as it was for me, remove the heatsink cover (bottom-middle of case) and the front fan assembly (bottom-front of case), then poke around in the bundles of wire behind SATA bay 1, top of the motherboard/logic board, toward the front of the case.  That’s where I found the wires I needed.

To remove the heatsink cover, grip it at the edge closest to the motherboard and lift and pull toward you–it’s held in place by a few magnets, no latches or anything.

To remove the front fan assembly, unscrew the screw that goes through the motherboard at the top-right of the fan assembly and possibly look for a screw at the bottom-right of the assembly, just under where the heatsink cover was.  Once those two screws are removed, pull the assembly straight out of the case (perpendicular to the motherboard)–it slides in a track along the bottom of the case and pulls away from a plug on the motherboard (no cables to worry about).

]]>
http://2718.us/blog/2009/10/26/mac-pro-2007-bluetooth/feed/ 0
Mac: Chrome versus Firefox http://2718.us/blog/2009/09/17/mac-chrome-versus-firefox/ http://2718.us/blog/2009/09/17/mac-chrome-versus-firefox/#comments Thu, 17 Sep 2009 05:04:26 +0000 2718.us http://2718.us/blog/?p=178 Seeing the announcement of Chrome 3 on Ars Technica reminded me of my desire for Chrome on the Mac. I’m not unhappy with Firefox, especially with the processor-specific-optimization builds, but it’s still slow and it just gets slower the longer I keep it open, constantly churning the CPU doing something and occasionally pausing for no apparent reason. (I dislike the interface and the feel of Safari, though less so with 4 than earlier versions.) So, I Googled Mac Chrome and found that they’ve got a developer preview up for Mac and I just had to download and install it. Both on my Macbook Air and on my Mac Pro, the SunSpider benchmark performance of “Shiretoko” intel-optimized Firefox 3.5.2 was 3-4x slower than the Chrome developer preview 4.0.207.0 (in which I am writing this post). This is huge. When I switched to “Shiretoko” from stock Firefox, I ran the SunSpider benchmarks and found a slight and significant improvement, but not even close to 2x, let alone 3-4x. I can’t wait for a final Chrome (or at least a Chrome that supports SOCKS proxy settings so I can securely browse over WiFi).

]]>
http://2718.us/blog/2009/09/17/mac-chrome-versus-firefox/feed/ 0
Open Source (BSD/MIT License) http://2718.us/blog/2009/09/06/open-source-bsd-license/ http://2718.us/blog/2009/09/06/open-source-bsd-license/#comments Sun, 06 Sep 2009 10:24:58 +0000 2718.us http://2718.us/blog/?p=170 I’ve released a few things as open source recently, under BSD or MIT license, hosted at Google Code.

  • asLJCore is the primary component of the LiveJournal client asLJ, managing all communication with the server.
  • YDDecode is a Cocoa class wrapped around some public-domain C code for decoding data encoded with YEnc.
  • NCIDStatusBarMenu is a utility to help pull NCID-based callerID notifications and display them as Growl notifications (among other things).  I’d been meaning to update it for nearly 2 years with no success and the future isn’t looking much better, so I’m releasing the source instead.

(My musings on licensing below the cut.)Permissive BSD/MIT licenses because in writing asLJ among other things, I’ve had to work to find libraries, frameworks, components, classes, etc., that weren’t GPL-licensed so that I could continue to choose how I wanted to release my software.  I am also heavily influenced by the simplicity of the BSD and MIT licenses compared to the lengthy GPL (and while the LGPL ought to be workable for many libraries, I couldn’t quite wrap my head around the language of it–the LGPL is several paragraphs of modification to the GPL).

(The song lyrics and commentary for OpenBSD4.3 have a lot to do with how I feel about GPL versus BSD/MIT.)

]]>
http://2718.us/blog/2009/09/06/open-source-bsd-license/feed/ 0