Used iPhones are still worth big money!

A month or so ago I finally broke down and upgraded our iPhones to 3G, and sold our old ones on Ebay. It worked out well.

Bought – 2 16gb iPhone 3Gs, $300 each + tax & misc AT&T fees.
Sold – 2 8gb first gen iPhones for $330 and $335 – about $20 each for Ebay/Paypal fees and shipping.

So the initial purchase is pretty well canceled out. The new service plan is eligible for corporate discounts, so hopefully my discount will cancel out the more costly monthly bill.

Use NSUserDefaults to persist data between app runs

On the iPhone you generally want your application to start looking like it did when it was last run to give the user the impression your app is ready to pick up where it left off. NSUserDefaults provides an easy way to store your application’s settings between runs. Simply create an instance of NSUserDefaults and give it the key/value pairs you want it to save.

Storing an integer

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger: myIntValue forKey: @"intValueKey"];
[prefs synchronize]; // writes modifications to disk

Reading it back in

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
int myIntValue = [prefs integerForKey: @"intValueKey"];

or more simply

int myIntValue = [[NSUserDefaults standardUserDefaults] integerForKey: @"intValueKey"];

Of course, this would be pretty useless if it only worked for integers. The same basic syntax also works for setObject/objectForKey and some others. Check the documentation for details. I have not tried with complicated compound objects yet, but NSUserDefaults so far I have had success with strings and simple arrays.

NSNotificationCenter

I just learned about NSNotificationCenter. Any class in a program can send a notification message to the notification center, and all classes can listen to the center and respond to messages that apply to it. It’s kind of like a callback, but really not.

This is part of my code for implementing a custom keyboard in my iPhone app.

To send a notification named “keyboardDone” to all objects in your program.

[[NSNotificationCenter defaultCenter] postNotificationName: @"keyboardDone" object: nil];

To listen for the “keyboardDone” notification and call the “keyboardDoneObserver:” method when it’s received this can be added to your class’ init code.

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardDoneObserver:) name: @"keyboardDone" object: nil];

And this is the “keyboardDoneObserver:” method that gets called when notified.

-(void)keyboardDoneObserver: (NSNotification*)notification {
     // do work here
}

Adding a code beautifier script to Xcode

Xcode’s re-indent command is pretty weak compared to the code reformatting built into other IDEs. It fixes the indentation at the beginning on each line, which makes a huge difference in code readability, but I don’t think it does anything else. In Eclipse and VS I’ve gotten used to being fairly lazy about being consistent with my spacing elsewhere and relying on their built in reformatting to clean it up for me. I wanted to change the way Xcode reformats code, since it’s easier to change tools than to break bad habits.

I spent some time searching for command line code beautifiers that support Objective C and only really found one. Uncrustify is open source, which is pretty fortunate since they don’t have an OS X binary download of the current version. The source download includes the needed project files for Xcode, so compiling your own is easy enough. Just open uncrustify.xcodeproj and compile. You could also download another project, Universal Indent GUI which includes an already compiled Uncrustify executable along with a GUI front end.

After I compiled the executable, I copied it and the defaults.cfg file to a new directory and created a couple user scripts in Xcode to use it. The code for both scripts is identical, just adjust it for the correct paths to the files.

#!/bin/sh
echo -n "%%%{PBXSelection}%%%"
/path/to/uncrustify -q -c /path/to/defaults.cfg
echo -n "%%%{PBXSelection}%%%"

The “Reformat all” script will run Uncrustify on the entire document.

The “Reformat selection” is the same except “Input” is set to “Selection” and “Output” is set to “Replace Selection”.

The defaults.cfg does pretty well with obj-c but isn’t perfect. At least it’s consistent. One of these days I’ll find a better config for it it try fixing it myself.

Activating iPhones. Two iPhones – one family plan

Over the weekend my wife and I upgraded our cell phones.
We’ve had a family plan with T-Mobile for several years and had been fairly happy with it. Especially the price, both of our phones combined only cost us about $50/month. Lately we’ve both been having problems with the service, which makes me think T-Mobile is having network problems as opposed to one of us having a bad handset. For the last couple months we would make or receive calls and we would be able to hear the person on the other end but they would not be able to hear us, and like I said, it happened with both of our phones. Friday was the last straw, as I called my wife 4 times and we had problems each time.

So, Sunday we went to the local AT&T store. I would have rather gone to the Apple store but AT&T was closer and gave us an opportunity to look at other phones. Anyway, we bought 2 iPhones, which we activated once we got home. Activation was easy, but there was a little confusion on signing up for the family plan. One of the options in iTunes is to sign up 2 or more phones on a new family plan account. I assumed after I set up the first phone it would prompt me to set up additional phones, but this was wrong. After the first phone was activated there was nothing to tell me what the next step should be, so I plugged in the 2nd phone and selected the family plan option again. About half way through I realized it was going to create another separate account instead of adding the phone to the account I’d just created, so I started over and used the existing customer option to add a phone. I guess I was only a new customer for the first phone, which I suppose is true, but since the option I picked originally said activate multiple phones I assumed it would prompt me for multiple phones. In any case, it only took about 20 minutes to activate my first phone and transfer the number from my old one, and about a half hour for the second including time I wasted trying to figure out what I was doing wrong.

I have not called T-Mobile to cancel my old account. I had logged into their website to view my account information and find my account number prior to moving the phone numbers. After the new phones were fully activated I tried to log into the old account again to look for instructions on cancelling, and could not log in. The web page told me the numbers had been cancelled, so I’m thinking the account closed automatically.

Trying Windows Vista

Over the weekend I decided to test Windows Vista on my old PC. The install and hardware support were better than I expected considering the several articles I’ve seen and the coworker who assured me that my nVidia nForce2 motherboard (Abit NF7S) chipset was totally unsupported under Vista.

The install was fairly straightforward. Since I have an MSDN subscription and this is my .NET development machine, I could legally download the Vista ISO from the MSDN download site. The install was straightforward, and while nVidia does not offer drivers that can be downloaded, the NIC was supported in the original install and most of the other hardware worked after a trip to Windows update. The raid controller and one other device were still listed as unknown in device manager, and the audio was labeled as unsupported but moved to the audio section. I don’t have any speakers connected, so I can’t say if it worked or not, but a PCI sound card could always be added if needed. At least the hard drives were running in UDMA mode. Overall the system ran pretty well, and I was able to use the Aero interface.

I installed a few apps. My antivirus program failed to install. Visual Studio 2003 is officially unsupported and this Microsoft KB article didn’t provide a lot of confidence. Office seemed ok. Synergy sort of works but was too annoying to actually use.

A while back I posted about my use of Synergy to share my keyboard and mouse between my iMac and PC. I’ve been very happy with the solution for the last few months with XP on the PC. You can configure Synergy to start at system startup or when you log in, and I use the system startup option so that I can use my Mac keyboard to log into the system. With Vista, Synergy is not able to configure itself to run at system startup. At first I thought this would be my worst annoyance, until I got my first of the famous “cancel or accept” prompts that the Apple commercial spoofs so well. Every time I got the prompt, synergy would quit working and I’d have to use the PC mouse to click accept. Then, after I got rid of the prompt, Synergy wait about five minutes before it would resume working.

After a days worth of exploring Vista, I reinstalled XP.