Tuesday, March 29, 2011

Stopping iWeb From Turning Text Links Into Images

Back in September 2010, Rage Software's blog published the provocatively titled post Are You Making The Biggest Search Engine Blunder with iWeb? Well it was provocative to me since I'd been publishing the Tangerine Element web site using iWeb since July 2008 when iTimeZone came out on the App Store. I immediately consumed the article. If you haven't read it, please do so you're up to speed. As soon as I had a chance, I enabled Show text imaging indicator in iWeb. I was horrified, the main navigation for Tangerine Element, as well as other bits of seemingly innocent text, was being converted to images. I burned numerous hours trying to tweak the right combination of settings to solve this problem without success. Eventually I gave up, but I finally cracked it tonight! Here's what to do.

There is a very nice inspector in iWeb that allows you to set properties on hyperlinks. Your hyperlinks are going to be text in text boxes, and this is where you can make all your links into images. If you click your text box and set the hyperlink properties, iWeb will immediately change your text into an image on publish. To get a text hyperlink, you have to double-click so that just the text is selected, not the box, then set the hyperlink properties. This also allows you to set the Format tab properties for rollovers.

Monday, March 28, 2011

Recommendation: Use FaceTime on Mac OS X for Video Chat Instead of iChat

I've been using iChat to video chat with my family for at least 6 years. With each Mac OS X release, Apple's made nice improvements to the video calls in iChat. This app is what sealed the deal for getting my parents off Windows years ago, and more recently prompted me to upgrade my mother-in-laws iMac to Mac OS X 10.6 Snow Leopard. It's been one of my favorite Mac-only apps. Of course Skype has been an option too in recent years and I've used it plenty especially to people on Windows. In my experience though, iChat's video quality has always been better. But it is time to say goodbye to iChat for video calls and use FaceTime, it's just better for most people.

Yes FaceTime costs a couple bucks, but video quality is definitely improved because FaceTime uses a widescreen aspect ratio to send & receive video. This has always been on my iChat wish list since iChat 5.0.3 on Snow Leopard captures video using a VGA (640x480) aspect ratio (i.e. 4:3) and then stretches it for widescreen viewing. FaceTime for Mac has the ability to send & receive video calls in 720p HD, but only the new early 2011 MacBook Pros have a built-in FaceTime cameras capable of sending 720p HD, as does the iPhone 4. Older Macs with iSight camera's top out at VGA resolution, but the widescreen aspect ratio only in FaceTime helps.

The other big reason to switch the family over to FaceTime is so they can receive FaceTime calls from iPhone 4, iPod touch, or iPad 2. This came in very handy today since I had taken the time to get my parents to buy FaceTime on their iMac a few days ago. This allowed me to FaceTime to my parents from the hospital room of my wife's father. It sounds like a commercial, but it happened & was great. Thanks Pocono Medial Center for the open WiFi.

About the only gripe I have for FaceTime is that when calling Mac to Mac, the app starts the video call in portrait orientation instead of landscape. A widescreen device that can't have it's orientation changed should of course start in landscape.

Tuesday, March 22, 2011

Be cautious about using Xcode 4.0 with LLVM 2.0 to deploy apps to iPhone 3G & below devices, apps crash

Update
Looks like this was resolved in Xcode 4.0.2 since I can't reproduce it anymore.

Original
On two separate iOS apps compiled with LLVM 2.0, user's whose iOS device could only run arm6 binaries crash at launch. Recompiling with LLVM 1.7 in Xcode 3.2.6 produces a fat binary that works for both armv6 & armv7 based devices.

It's certainly possible that there is some build setting I tweaked to expose a bug in LLVM 2.0. If that is true, I haven't found which one yet.

I filed a bug with Apple on this of course, # 9141747. If you are seeing the same issue, please dupe my bug.

Here are some build settings that might be relevant:

SettingSelection
ArchitecturesStandard (armv6 armv7)
Build Active Architectures OnlyNo
C/C++ Compiler VersionLLVM 2.0 or
LLVM 1.7
iOS Deployment TargetiOS 4.0 or
iOS 3.1.3
C Language DialectC99 [-std=c99]

Saturday, March 19, 2011

Nick Cage will apparently do anything for a buck

Even funnier, the American Library Association thought this would inspire someone else to read.

Friday, March 18, 2011

Batman (1989)'s Alfred Has Departed

Sad to hear the actor responsible for one of my favorite Alfred performances has left the building.

Ain't it Cool News: Hammer & Tim Burton fave, Michael Gough passes on...

Wednesday, February 09, 2011

Flash Player 10.2 vs. iTunes 10.1.2 CPU Utilization Playing a Song

Flash Player 10.2 was released today. The big claimed improvement is better, i.e. lower, CPU utilization playing H.264 encoded HD video. This tweet claims a big drop in CPU usage for Pandora.com's Flash app.

Curious, I installed Flash Player 10.2 on my main iMac even with the rare Safari pseudo-hang I had on the work laptop after installing Flash Player 10.2

Here's the audio playback performance I see in Mac OS X 10.6.6:

  • Pandora.com playing a song with Flash Player 10.2 uses ~ 10% of CPU
  • iTunes 10.1.2 playing a 256 kbps AAC file ~ 5% of CPU
  • Pandora.com's Flash app paused, ~ 6.6% CPU

Yeah, Flash is totally not going to use more CPU cycles than native Mac OS X audio/video playback Real Soon Now™

Wednesday, February 02, 2011

How To Compare NSDecimalNumbers in Objective-C

I was working on some code today where I had to compare two NSDecimalNumbers. This was my first attempt at comparing them:

NSDecimalNumber *number1 = [NSDecimalNumber one];
NSDecimalNumber *zero = [NSDecimalNumber zero];

if (number1 > zero) {
	//1 is always greater than 0 right?
}

This code will compile without errors or even warnings, but it doesn't work. It works, but it doesn't do what you expect. Turns out you aren't comparing the values of the two NSDecimalNumbers, your comparing pointer addresses.

Even more shocking, Objective-C does not have operator overloading! I've been developing in Objective-C for 3+ years now and I had no idea, it just never came up in iTimeZone. Assuming that Objective-C had operator overloads that did the expected evaluation on the value cost me about 4 hours today, especially since the compiler was no help.

I switched over to this implementation and thought I was done:

NSDecimalNumber *number1 = [NSDecimalNumber one];
NSDecimalNumber *zero = [NSDecimalNumber zero];

if ([number1 floatValue] > [zero floatValue]) {
	//1 is always greater than 0 right?
}

Looks good right? Wrong! While this works for short fractional numbers, numbers that have more precisions will lose them with that syntax. I could have also used:

...
if ([number1 doubleValue] > [zero doubleValue]) {
	//1 is always greater than 0 right?
}

That increases the precision from 6 digits to 15, quite a leap, but some digits could still get cutoff.

The absolutely correct way?

...
if ([number1 compare:zero] ==  NSOrderedDescending) {
	//Hey number1 is greater after all
}

I don't think I am going out on a limb here saying that isn't the easiest to understand syntax. A comment surely would have to go above the if statement to rewrite that in plain english, or even using an operator. While I have only written a few operator overload methods in C++ and none in .NET, I sure did use them in .NET all the time. I hope Objectice-C gets them in a future release.

Saturday, December 18, 2010

How to fix Xcode build error 'Directroy "/XYX/" following -F not found'

I started working on iTimeZone HD, the iPad release, for real today and something pretty weird happened.

I created a new target as a stand alone iPad application based on my current iTimeZone iPhone target. Once I built, first thing I see is this message:

warning: directory '"Macintosh HD/Users/YourName/Code/Project"' following -F not found

This doesn't happen on the iPhone target, and it took me a while to figure out what was going on. Here's what you do to get rid of this annoying message:

  1. Get Info on your Target (e.g. iTimeZone HD)
  2. Click on the Build tab
  3. In the Configuration drop down, select All Configurations
  4. In the search box enter Framework
  5. You should see Framework Search Paths in the results. Click on it.
  6. Press delete
  7. Close the info window and rebuild

You're warning should now be gone.

Saturday, December 04, 2010

Best Way to Implement Private Methods in Objective-C

Since the iPhone SDK came out, I've been using the following syntax in my Objective-C implementation file (the .m) to implement private methods:

@interface ClassName (Private) - (void)privateMethod; @end

@implementation ClassName - (void)privateMethod { //keep this private }
@end

This style just creates a Category for your class that's not in the header, so other classes can't read it. Turns out there was an even better way introduced in the Objective-C 2.0 spec using Extensions, which are like anonymous categories, but the improvement is the implementation must exist in the main implementation block for the class. Here's the example re-written:

@interface ClassName () - (void)privateMethod; @end

@implementation ClassName - (void)privateMethod { //keep this private } @end

Not much has changed, instead of decorating your category with a name, (Private), you just put empty parenthesis, ().

Once I switched over the iTimeZone code base, realized I was carrying some dead weight method declarations, so win!

Here's Apple's documentation.

Update
Check out bbum's comment for additional syntactical sweetness to make private/public properties with property redeclaration.