Journal, Programming Timothy Sanders Journal, Programming Timothy Sanders

iOS Beta Testers Wanted!

I'm putting the last few VoiceOver accessibility labels in my iOS app (RoadTrip) and then it's basically done. I want to take a stab at putting some custom textures in and I'm sure I'll find some new bugs once I turn off VoiceOver and go back to the iPad version but the end of the project is visible from here. If I know you in real life, you have a iOS 5.0 device available, and you're willing to do some beta testing for me I'd appreciate it. Get in touch with me! I'm hoping to release a beta version by the weekend.
Read More
Journal Timothy Sanders Journal Timothy Sanders

Blog–ruptcy!

Oh yeah, this thing. Here's the ridiculous thing. I've been meaning to write a whole mess of posts. And in fact it had reached a logjam of stuff. I was paralyzed on writing any given post because I knew there were so many to write. So then I decided I was going to declare "blog bankruptcy" and just write one post touching briefly on all of the topics. The thing is that I decided that in early December and I've had a task sitting in Omnifocus about it for over two months. In that time frame even more shit has transpired that needed to be in the post. In short, it wasn't going to happen. So here we are. Here's what I'm going to do. I'm going to dump a list of interesting things, no more than a couple of sentences on each. Once it's all here maybe it will free me up to write more on particular topics. Feel free to jab me if any of these catch your eye and you want to hear more.
  1. We got a new TV! We replaced the old set with a projector and an 84" retractable screen. It's pretty sweet!
  2. While doing all of the projector install and wiring I put my foot through the hall ceiling, so we had a big hole for several weeks. This was less sweet.
  3. Back in October Schrödinger got really sick and we had to take her to the Cat Hospital. Turns out she's having renal (kidney) failure and was super-dehydrated. They had to keep her there on an IV for five days, one of which we couldn't visit her at all. That super-sucked and now I have to administer fluids subcutaneously to her daily. (Translation: I have to stick a needle under her skin and give 100 mL of lactated ringer's fluid.) She's doing fine now and she's got a special diet that helps her along.
  4. Not to be outdone Heisenberg had some sort of hypoglycemic shock in January. I came in and found him passed out on the floor with his face in his food plate. He couldn't stand and when I checked his blood sugar it was drastically low. He only had to stand overnight in the hospital but we're still adjusting his insulin trying to find the right balance. He seems OK for now, so we'll see what happens.
  5. Since my last post talked about iTunes Music Match I should probably mention that I turned it on since then on my iPhone and it works well. I find that I can't stream music from the internet down to my phone and then wirelessly to the Airport Express but that's a pretty edge case. It is pretty cool to be able to search my entire music library from my phone. Macworld has a useful article describing how to upgrade crappier audio files after using Music Match. It worked for me and upgraded 4,788 tracks so that's awesome. I did notice one example later where my "explicit" CD rip had been replaced with a "clean" radio edit so keep an eye out for that.
  6. I got Skyrim for Christmas. Probably my vote for best game of 2011. So good!
  7. I also got Super Mario 3D Land for the 3DS. It's a lot of fun, but the last few worlds get ridiculously difficult. At one point I was up to well over 100 lives but I'm on the last 2-3 worlds now and I've gotten down to a bit over 25.
  8. Playing the 3DS again really drives home the odd conflict in Nintendo's hardware these days. I like the 3DS and the 3D effect does make some sections of Super Mario easier, but I've also died many times because I move my head or arm and lose the sweet spot mid-action sequence. It's weird that over with the Wii they've made this big push towards getting non-games, this "blue ocean" strategy and then their handheld is so weirdly finicky as to require serious training in how to use it.
So there you go! Hopefully this will clear the decks and I'll resume posting. I have some pictures of the projector install and ceiling repair that I intend to post at the very least.
Read More
Gadgetry, Journal Timothy Sanders Gadgetry, Journal Timothy Sanders

iOS 5.0 Recommendations

I just wrote an email to my immediate family laying out my thoughts about iOS 5.0 and what they should do about upgrading and using iCloud and the like. I realized as I sent it that it might be interesting to more people so I'm going to post it here. It's worth noting a few things about the perspective. I've been running iOS 5.0 on an iPhone 3GS and WiFi iPad 2 for a bit over a month and on a fourth generation iPod Touch since June (although I don't do anything other than software debugging on the touch). So I don't have any experience with 5.0 on an iPhone 4. I suspect it's fine but I haven't tried it personally. I've been running the gold master for the week it has been available. The folks I was sending the email to have a WiFi iPad 1 and a 3GS.

Anyway, here's what I wrote:

1) You'll need iTunes 10.5. I suspect iTunes will ask about upgrading sometime today. That should be fine but be aware it will take a little time so don't do it if you're in a hurry.

2 ) The next time you sync your iPad or iPhone to the computer after the iTunes update it's likely to ask you if you want to upgrade. If you do be prepared: it will take a while to update and restore. My phone (which has more files on it than my iPad) takes about an hour to restore after a system upgrade. It's all pretty seamless but it takes a while because iTunes first backs up the phone, then downloads the system update, then wipes the device, then installs the update, then puts all of your files back from that backup.

3 ) I haven't run iOS 5.0 on an iPad 1, but I suspect it's a fine thing to install. I still would not recommend installing iOS 5.0 on a 3GS phone. I've been running the "Gold Master" released version for a week and it's faster than the betas were but the phone is still very sluggish compared to how it was on 4.3. I still feel playing real-time games on the 3GS is ugly with the quasi-random freezes. Also be aware if you install 5.0 it may be difficult or impossible to go back to 4.3 (the new version usually updates the cellular baseband firmware in ways incompatible with earlier OSes, so to roll back you have to do tricky re-flashing of very low-level chips.) I ordered a new iPhone 4S that I'm getting on Friday, but the only thing that's made running 5.0 on my 3GS acceptable was knowing it was a short-term solution. If they follow the pattern you may find that the inevitable 5.1 works better on a 3GS than 5.0 does. I would suggest waiting at least a week or two and see what shakes out with the 3GS/5.0 situation. And you have to be careful with that because iTunes will encourage you to upgrade. If you just click things without reading you'll get an upgrade.

4 ) iOS 5.0 has iCloud for file storage and you can use iTunes Music Match to stream your music library from online storage. Music Match costs $25/year. This is going to be really cool, but I'd advise staying away from both features for a while. I've tried Music Match on my iPad and it makes a real mess out of things. I told it this morning to download all of my Talking Heads music (I have ~150 tracks from Talking Heads) and my iPad started well over 400 downloads. No idea what it's doing, but it's taking quite a while. Apple cloud things tend to get overwhelmed in the first few days after launch so I'd suggest keeping all of your contacts, calendars, and data files exactly where they are for the first couple of weeks. I turned on Music Match on my iPad because most of the time I listen to my phone - which I'm still syncing manually right now. I have some files on iCloud for testing but only stuff that has multiple backups.

5 ) Having said all of that, turning on the "Sync over WiFi" option in iTunes is pretty awesome. With that your iOS device will sync (and backup!) whenever you plug it into the charger if iTunes is running on the machine you use to connect. None of that uses iCloud in any way - it's just your device and your computer talking over the local network. I recommend turning that on as soon as you can. I've been using that for months now - but I still haven't turned on backing up to iCloud because I trust THAT a lot less.

Read More
Blog Administration Timothy Sanders Blog Administration Timothy Sanders

Possible Blip

Just a quick heads–up: I need to switch the Registrar for hiddenjester and that will require some DNS foolishness. It's possible this site will disappear for some users for a tiny bit. No worries. We will return :-)
Read More
Programming Timothy Sanders Programming Timothy Sanders

Quick tip about localizing currency on iOS

[UPDATE:2014-02-19 I've modified this sample code. This worked in 2011, but not in 2014. I think the issue is that ARC used to make a copy in the call that creates the NSMutableCharacterSet but now it does not and you have to specify mutableCopy or you don't get a NSMutableCharacterSet. Where I once wrote:
NSMutableCharacterSet* tempSet = [NSCharacterSet whitespaceCharacterSet];
You should in fact use:
NSMutableCharacterSet* tempSet = [[NSCharacterSet whitespaceCharacterSet] mutableCopy];
I apologize for the confusion.

Let's say you have a text field in your iOS app and you want to take currency values in said field. NSNumberFormatter is your friend and can happily turn a string like "$42.23" into the floating point number 42.23. It will also turn the floating point number 42.23 back in "$42.23". Even better with the German locale active it will turn 42.23 into "$42,23 €" and vice-versa (note the comma as well as the euro symbol). Sweet! However, here's a minor glitch. Sweden's currency "symbol" is in fact a string – "kr". While your formatter will turn the float 42.23 into "42,23 kr" it cannot turn "42,23 kr" back into the floating point value. What to do? What I decided to do was strip whitespace and currency symbols from the string before trying to convert the string into a float. Like so:

NSCharacterSet* costTrimmingCharacters = nil;
//OK, some settings have currency symbols that can't survive a 2-way trip. For example, Sweden's currency "symbol" is "kr"
//So what we're going to do is trim whitespace and currency symbols from the string. Also then we don't have to use the currencyFormatter and can
//simply use the decimalFormatter (since it will strip $ from US locales, for example.)
NSMutableCharacterSet* tempSet = [[NSCharacterSet whitespaceCharacterSet] mutableCopy];
[tempSet addCharactersInString:[[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCurrencySymbol]];
costTrimmingCharacters = [tempSet copy];
//Note in a real app you should store costTrimmingCharacters somewhere and only build it the first time you need it.

NSNumberFormatter* currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setLocale:[NSLocale autoupdatingCurrentLocale];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString* aggravatingString = [NSString stringFromString:@"42,23 kr"] NSString* goodString = [aggravatingString stringByTrimmingCharactersInSet:costTrimmingCharacters]; NSNumber* goodValue = [currencyFormatter numberFromString:goodString]


Full disclosure: I didn't test that exact snippet, it's frankensteined from a few pieces of code out of RoadTrip that would have just obscured the point. So there may be a syntax error somewhere due to a typo but the idea should be clear. Last two little suggestions:
  1. I use a related character set in the field delegate's shouldChangeCharactersInRange: replacementString: method so that I don't even accept illegal characters and that way you can't even enter "kr" unless you're in the Sweden locale.
  2. In the delegate's textFieldDidEndEditing: method once I've converted the string into a float I go right ahead and convert it back into a string and assign it back into the field. That means if they entered 42.23 they'll see a nice $42.23 or 42,23 € or whatever their locale specifies.
Read More