Archive for the ‘Personal’ Category

Slow news day: favorite feeds updated

Tuesday, August 5th, 2008

It’s been a while since I’ve updated my Favorite Feeds in the Downloads section of the sidebar of my blog front page. (Sounds like AppleScript, eh?) I would export from Vienna and update it every day, but I have to manually edit the .opml file first to remove embarrassing subscriptions such as porn and the New York Times. For your convenience and amusement, the latest version is up now.

C4: I’m a twit

Saturday, August 2nd, 2008

In September I’m traveling to Illinois, affectionately known as the Land of 10,000 Tollbooths, in order to attend C4, affectionately known as C4. This year will be C4’s third, signified by the title C4[2] because programmers are terrible counters. In any case, I’ll be making an appearance there for the first, or nilth, time. The Rogue Amoeba army is planning to invade and conquer the conference, which we’ll subsequently rename to R4 (give or take an R, depending on how many of us show up).

The C4[2] online registration was unusual in requiring a Twitter ID. (@rentzsch I forgot to mention my special diet: Kobe fillet with Château Lafite.) As we all know, it’s against the law to ignore * in a web form. Thus, at the urging of my attorney, my agent, and my astrologer (all the same person), I signed up. Fedaykin, follow me!

I’m a Rogue

Saturday, June 7th, 2008

I’m delighted to announce that I’ve been hired as Rogue Amoeba Employee 008. (Employee 007 is Longwell, Justin Longwell.) I’ll be working on Rogue Amoeba’s apps as a software engineer, as well as providing comic relief. Thanks to Alex, Paul, and Quentin for this once-in-a-lifetime opportunity. My coworkers at Rogue Amoeba Software, LLC include fellow bloggers Mike Ash and Guy English. Together we form perhaps the most talented group of Mac programmers outside of Apple. (Yes, I’m talking to you, Adobe and Microsoft.) Indeed, I haven’t seen such an array of stars in one place since the Ghostbusters music video.

I’ve joined Rogue Amoeba just in time to miss WWDC ‘08. In an earlier post, I mentioned that I left Marko Karppinen & Co. LLC just in time to miss WWDC ‘07. (I’ll make it there someday! :-( ) The question is, what have I been doing in the meantime? Backpacking through Europe? Rotting in Gitmo? Running for President? No, I’ve been working on super-secret projects for Francis Technical Services, LLC. Although FTS is a little-known company, its software is well-known, at least inside Apple. For example, FTS is responsible for Radar, the Apple-internal Cocoa app that opens when employees click on the funny-looking rdar://problem/ URLs you often see. The number at the end of the URL corresponds to the problem ID of the bugs you file on the web with Apple Bug Reporter (also known as RadarWeb). It’s useful to have one of these URLs available when communicating with Apple engineers, because their managers forbid them from lifting a finger without a Radar problem number.

While at FTS, I did some bug analysis for Radar: that is, analysis of bugs in Radar’s source code, not analysis of bugs in Radar’s database, to which as a contractor I had extremely limited access. However, I mostly worked on other projects, such as Radar’s sibling app Sonar. Apple’s DTS uses Sonar to communicate with ADC members (such as me!). If you’ve ever seen sonr://request/ URLs — the Mighty Quinn provides one in an Apple Mailing List post — those open in Sonar. (By the way, I’ve read all of your emails to DTS. No, you haven’t been accepted to the iPhone Developer Program. Stop whining.) Another project that I worked on was Merlin, an app for Apple’s Human Resources department. I think that Steve Jobs is doing an outstanding job at Apple, so before I left I used Merlin to double his annual salary.

I’d like to thank Dave Francis, the owner and founder of Francis Tech, for the opportunity to work there. Despite appearances, I’m not really the type to hop from job to job. I’ve just been looking for Mr. Right, LLC, a company to fall in love with, marry, and have baby apps with. (As for any other support claims, sorry Billie Jean.) I can see myself growing old with Rogue Amoeba. (Easy to see when you’re already old?) Besides, someone has to stick around and keep an eye on mikeash, stop him from taking over the world.

Now without further ado, please take out your credit card and buy some of our fine software. As a special bonus for our Leopard customers, your purchase will be (code-)signed by your favorite Rogue Amoeba star.

Cocoa Blogs free, as in beer

Sunday, March 30th, 2008

Wait, beer is not free! Or so my bartender yelled last night as I ran out the door. (I also had one bourbon and one scotch.) The front page of Cocoa Blogs was already free, but the syndicated feed has only been free to contributors — kind of like Congress. Now Scott has decided (he is the decider) to make the feed available for free too. Indeed, new items are appearing in the feed. Remember, folks, you heard it here first. This is your Number 1 source for news, rumors, and outright lies.

My own long list of Cocoa blogs, including the Cocoa Blogs feed, can be downloaded for free from the “Favorite Feeds” link in the sidebar of my blog. The list is in convenient .opml format for import into your favorite free feed reader. There seem to be many choices nowadays. (Too bad that they all suck. Mine sucks the least, though.) The contents of my web site have been and always shall be free, as in loader. If I asked for contributions, that would just embolden the terrorists. Last call!

News Flash: Vienna brings down the mighty NewsGator

Wednesday, January 9th, 2008

In an obvious gesture of defeat, NewsGator has announced that they — is a company a collective or an individual? — are no longer attempting to charge money for NetNewsWire. Their cover story is some mumbo-jumbo about “enterprise”. Sure, and Leopard was delayed by the iPhone. ;) What they would never admit publicly is that they realized it was pointless to compete against the best Mac RSS utility on the planet. Who would pay for NetNewsWire when Vienna is free? Not to mention open source! (Oops, I just mentioned it. I take it back.)

Let it not be said, however, that we are without pity for the downtrodden. On behalf of the Vienna developers, I apologize for destroying the commercial feed reader market. What else can I say? Ya gotta do what ya gotta do. Give the fans what they want. The battle has certainly made great entertainment, the classic David vs. Goliath tale. Once again, David (actually Jeff) has overcome insurmountable obstacles, beat overwhelming odds, leapt over tall buildings in a single bound, to emerge victorious. It’s always a thrill to see the underdog win … except the Miami Dolphins.

Yet I shall only allow myself a moment to rest on my laurels, to savor the sweet smell of success. (It smells a little like tequila, actually.) For I’ve already chosen my next target: outliners. Look out, OmniGroup!

WordPress Bug Fix: more props for me

Saturday, December 15th, 2007

Although I abhor self-promotion — much as Roger Federer abhors winning tournaments — someone must take on this thankless task. (I had to fire my publicist, because he had never heard of me.) Thus it is with great regret and sorrow that I announce my latest contribution to the WordPress open source project. It was just one minuscule twitch for mankind, yet one ginormous vault for a man, viz., yours truly.

Now some critics might claim that the security issue was trivial. In my defense, I would argue that critics are doo-doo heads. Except the ones in New York: they all love me.

What ever happened to Cocoa Blogs?

Thursday, November 29th, 2007

It seems dead, though the clock is still ticking. (Countdown to extinction?) Anyway, I’ve just updated my own extensive list of cocoa blogs and other favorite feeds, which you can download from the Downloads section of my sidebar. FileMerge will reveal the changes in my all-important favor. Remember bloggers, X-Mas is coming soon, not to mention Y-Mas and Z-Mas. I’m keeping track of who’s naughty and nice — mostly by intercepting your wireless packets. If you’re nice, you’ll get a hot dog and a shake.

WordPress Bug Fix Near Saturday: props lapcat

Saturday, September 22nd, 2007

The network has decided to renew my series for at least one episode. WordPress 2.3 is approaching release, and I’m pleased with the progress that it has made in supporting syndicated feeds. The patch I submitted to fix the Atom feed modification date bug has been committed to the trunk. RSS 2.0 feeds still don’t give modification dates, but that could be considered a personal preference. (As can RSS 2.0 itself. Of course, no one would prefer the worse to the better, as Socrates would say, if he were 2500 years old and spoke English.)

Other syndication bugs that have been fixed in the trunk include checking the last modified date of posts rather than comments for comments feeds, an obsolete Atom feed template, and checking the last modified date of unapproved comments for comments feeds. WordPress 2.3 should be a good update for feed readers such as you and feed readers such as Vienna.

Time to go. Joan Cusack is calling again.

Fewer feeds, more favorites on average

Sunday, August 19th, 2007

Despite what I said in my comment, I did end up taking Daniel Jalkut’s message to heart.

To an extent. A tad.

Basically, I cleared out some dead and abandoned feeds. I added a few new ones too. Sorry Daniel, I’m incorrigible! I’m also an enabler: for all you news junkies out there, get your fix by downloading the updated opml of my Favorite Feeds, available in the sidebar of my blog. Go ahead, just browse a bit. Once you develop a taste for syndication — by a taste for I mean an addiction to — you’ll need a powerful feed reader. And then … well, that’s about it.

Embedding frameworks in loadable bundles

Saturday, August 11th, 2007

While I worked for Marko Karrpinen & Co. I only made one commit to BaseTen, but as Sappho would say, that one was a doozie! BaseTen is an open source Cocoa framework for PostgreSQL. It has an API resembling Apple’s Core Data framework, which uses SQLite. You can check out the source and build BaseTen.framework as well as the optional BaseTenAppKit.framework and an Interface Builder palette, BaseTenPalette.palette. (By the way, I abhor Interface Builder. Or at least Interface Builder 2. I’ll reserve judgment on Interface Builder 3 until I learn more about it, and only then will I abhor it.) The frameworks are designed to be embedded within your application’s bundle, in the standard location for embedded frameworks: the directory Contents/Frameworks.

An app needs to know how to locate linked frameworks at runtime, so at compile time the app’s executable gets a record of each linked framework’s install name. An install name is, as you should expect by now, not a name. It’s a path, namely, the location of the dynamic library containing the framework’s code. To be exact, the install name is where the library should be at runtime, for a library wouldn’t even need an install name if it just indicated where the library actually is at compile time. Install names enable you to target Panther, for example, while still compiling with Tiger. You can use the command-line otool -D to see that the install name of

/Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

is

/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

Using absolute paths for install names is fine when your app links against system frameworks, which reside in pre-determined locations, but absolute paths won’t suffice when your app links against embedded frameworks, because the app could be installed almost anywhere in the file hierarchy, e.g., ~/Desktop or /Volumes/MyDistributionDmg. That’s why an embedded framework needs a relative path install name. The BaseTen and BaseTenAppKit projects achieve this by setting the build setting INSTALL_PATH (what else would you do with a build setting but set it?) to @executable_path/../Frameworks. The relative @executable_path is the path to the Contents/MacOS directory in your application’s bundle. When BaseTen is built with that build setting (to answer my last question, you would build with it), the install name of the framework becomes

@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

as you can verify with otool -D. Thus, when your app links against BaseTen.framework and records the install name, it can find the framework in its own bundle at runtime.

BaseTen’s IB palette needs to use the BaseTen frameworks too. The problem, however, is that if the frameworks are built to be embedded in an application, they aren’t configured correctly to be embedded in the palette. When Interface Builder launches it will fail to load the palette, logging an error:

Interface Builder[29996] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette
  Reason: image not found))

The reason that the image is not found — the reason behind the reason — is that the executable in this case in not actually BaseTenPalette but rather Interface Builder itself, which is trying to load the palette. The @executable_path leads to

/Developer/Applications/Interface Builder.app/Contents/MacOS

but BaseTen is embedded in

~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks

so the install name doesn’t locate the framework at runtime.

In Tiger, the relative @loader_path was introduced to supplement @executable_path. The @loader_path is relative to the image loading the dynamic library, wherever that image may be. Thus, if we change the install name of BaseTen to

@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

and the install name of BaseTenAppKit to

@loader_path/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit

then BaseTenPalette should be able to locate the frameworks when Interface Builder launches. Problem solved, right?

If you’ve already skipped ahead to the end of this post, you’ll know that the problem is not solved. (Spoiler alert: Harry drops out of school to follow Trey Anastasio.) We’ve eliminated one error only to find another:

Interface Builder[2599] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit
  Reason: image not found))

Whereas BaseTenPalette can now find BaseTen at runtime, BaseTenAppKit cannot. They both have a record of BaseTen’s install name as

@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

but they don’t have the same @loader_path.

At this point, you may throw up your hands and throw in the towel, exclaiming Alas, BaseTen cannot have two install names! — or some such exclamation perhaps not suitable for children. (Oh rat farts!). Yet your exclamation would be in vain, because the install name of the dynamic library doesn’t matter after linking. All that matters is the install name recorded in the linked executable, and that can be forged.

Apple provides the nefarious command-line install_name_tool to forge install names for dylibs and give them fake id’s. This is how frameworks get into bars, since there are very few that are twenty-one years old. You can examine the details of my fix in the BaseTen Trac, but basically what I did to allow BaseTenAppKit to find BaseTen was to run the following command in a build phase script for BaseTenPalette:


install_name_tool -change \
	"@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"@loader_path/../../../../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH/BaseTenAppKit.framework/Versions/A/BaseTenAppKit"
	

I discovered the correct install name through a stroke a genius, or to put it another way, trial and error. The @loader_path for BaseTenAppKit turns out to be

~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks/BaseTenAppKit.framework/Versions/A

which makes sense in retrospect, but if you could guess ../../../.. on your first try, you’re a superfreak. Anyway, you can check the install names before and after with otool -l, or succinctly with otool -L.

Caveat developtor: for install_name_tool to work, you may need to build your frameworks with the option -header-pad_max_install_names. BaseTen already does this. See the man pages for more information, man.