Expiration perspiration

All hell broke loose for me in the Program Portal and Xcode today: welcome to 2009 and the expiration of development certificates over the holiday break. It’s far from obvious what is causing these problems, hence this quick essay to help others avoid them now and in the future. I’m sure that I’ll refer back to this essay on January 13th, 2010 when my latest certificates expire.

The problems began when I noticed that new devices couldn’t be added to an existing Ad Hoc provisioning profile. I assumed that meant something had changed in the Program Portal, so I wrote up a Radar ID# 6489692.

I then began looking for a workaround to the problem. When I tried to create a new distribution profile (using Program Portal > Provisioning > Distribution > Add Profile) I saw “Create a distribution certificate” instead of our company name. That led me to the root of the problem: our distribution and development certificates had expired.

A quick way to identify this problem is to open Keychain Access and do a search for “iPhone”. If you see a red X after “iPhone Distribution” or “iPhone Developer”, you have a lot of work to do.

Luckily, I had a copy of the original Certificate Signing Requests (CSRs) so recreating the certificates was straightforward. Words to the wise: keep a copy of your CSRs along with your private key developer key. If you’re not backing this stuff up in a safe place, you’re going to have some serious headaches in the future.

If you don’t have the original CSRs, you’ll need to follow the steps on the portal. Good luck.

Once I had approved the requests and the new certificate was issued, my Ad Hoc profile magically started working again on the Program Portal. Unfortunately, the magic didn’t extend to the development profiles. My developer certificate (“iPhone Developer: Craig Hockenberry”) had expired, but a reference to the previous one was still in the profile. To workaround this problem, I clicked on Edit > Modify on the Program Portal > Provisioning > Development page. On that page I added a checkbox to the second instance of my name (representing the developer certificate.) Once that was done, I generated new provisioning profiles.

As we all know, that’s only the beginning. To make Xcode happy, I removed the expired certificates from Keychain Access and downloaded new copies from the portal. Make sure to clear the search field, if don’t you’ll get confused because the search doesn’t refresh after the new certificate is loaded.

I then downloaded the new provisioning profiles and moved them into Home > Library > MobileDevice > Provisioning Profiles. After doing this, you need to quit and restart Xcode. Open your project file, select Project > Edit Project Settings from the menu bar and update the Code Signing Identity settings for each build configuration. Then say a little prayer and do a build. If there is a God, you’ll have a new signed binary.

To those Apple employees that are reading this, here’s a suggestion: send an email to a developer whose certificates are about to expire. The current system requires the developer to dig around a complex system to figure out what is broken. Since this system is designed to break over time (through expiration) please let us know it’s about to happen. It will make things easier for everyone involved.

Updated January 13th, 2009: You will also need to recreate the App Store provisioning profile for “iPhone Distribution”. Since it’s tied to the same distribution certificate that your Ad Hoc profile is, you’ll see “<matching certificate identity with private key not found in login keychain>” displayed when you try to select the Code Signing Identity in your Project Settings. Again, the portal is very awkward here: I needed to do the Edit > Modify > Submit with no changes to force the creation of a new .mobileprovision file. Once downloaded and installed in Library > MobileDevice > Provisioning Profiles, Xcode populated the signing identity list correctly.

Cooking with gas

One of the great things about the NDA being lifted is that a lot of great books about iPhone development are finally being published. It’s about time: for many months the top search hit on this site has been iphone app development. A lot of new developers need guidance.

Last week, Addison-Wesley contacted me saying that they wanted to mail a free copy of Erica Sadun’s new book, The iPhone Developer’s Cookbook. I guess that’s one of the benefits of having a web log that a lot of other iPhone developers read: I took them up on the offer since there were no strings attached.

To be honest, I wasn’t expecting to get much out of this book. After spending many months digging around in the bowels of the SDK, I thought I had seen it all. I’m happy to report that I was wrong.

If you’re an experienced iPhone developer, you won’t learn much from the beginning of the book: you already know about the application package, setting up Xcode, platform limitations, how UIKit uses MVC, and so on. If you’re new to the platform, this information will certainly be helpful and I found that it was presented clearly and concisely.

So what did I like about this book?

First off, there are the recipes. These short snippets of code show you how to do a lot of common tasks. Need to build some draggable views? Just look up the recipe “Dragging Views” and you have a few pages of pertinent information (including a brief introduction to UITouch.)

I much prefer this format over long, involved examples that are complete implementations. The recipes in this book act as a quick way to get up to speed and they help you find more detailed information in the Developer Documentation in Xcode. The recipe format gets you pointed in the right direction.

In going through these recipes I ended up learning some new things. For example, I didn’t realize that you can set the number of rows in a UIAlertView. Again, the short and sweet recipe format makes it easy to pick these things out.

There are also some clever recipes: I particularly enjoyed the one that added a UIProgressView as a subview to an empty UIActionSheet. A nice trick to leverage the existing UIKit classes in new and different ways.

But the real value of this book comes from Erica’s experience in working with the Jailbreak APIs. She goes where the Xcode documentation does not and lets us peek behind the curtains. (This book, in effect, summarizes a lot of the poking around she did during the early days of the iPhone.)

Personally, I will never use undocumented iPhone SDK calls. It’s just too dangerous: you risk not getting accepted into the App Store because you’ve broken the terms of the license agreement (section 3.3.1.) And even if you do sneak it through, what are you going to do if the unpublished API changes and breaks your app? You’ll have a hell of a lot of unhappy customers for the couple of weeks it takes to get a new version submitted and approved.

So why is Erica’s exploration into the undocumented side of the API so helpful? Because it shows us what Apple is using in their own applications. And if we need similar functionality, we can file enhancement requests using this inside knowledge.

As an example, there’s the page curl animation that is used in the Maps application. You won’t find it in the API documentation, but it’s there if you use @”mapCurl” or @”mapUnCurl” as the animation type. If you want to do that in your own app, write a Radar and let the developers at Apple know. Make sure to give them context for the enhancement request: tell them why exposing the API would make your app better.

Personally, I have written Radars for the inclusion of the UICalloutView class and UIToolbar customization functionality.

In summary, I highly recommended Erica’s book. If you’re a beginner, you’ll find code that helps get you started. For those of us who have more experience, you’ll find it to be a valuable reference for both public and private APIs.

If you’re planning to buy a copy, please make me rich with affiliate kickbacks at Amazon. Thanks!

Lights Off

There was a time when I would have never considered jailbreaking my iPhone. That was a time before I saw Lucas Newman’s and Adam Betts’ groundbreaking application for the iPhone: Lights Off.

It’s a simple game. It’s simple code. And it demonstrated what was possible for the rest of us outside of Cupertino. I was hooked. Big time. Seeing Lights Off at C4[1] was an inspiration for pretty much everything I’ve done on the iPhone since.

As a result, I feel compelled to document this historic piece of software. And what better way to do this than with source code that works on the iPhone 2.0 software. The archive also includes a Jailbreak folder that contains the original source code that worked with version 1.0 of the iPhone OS.

Do not look at this code for tips on how to design iPhone applications correctly. Rather, it is a testament to the curiosity and coding instincts that were required for developing sophisticated software without any documentation or headers. I purposely made as few changes as possible while porting to 2.0: FileMerge can be used to see what’s improved since Jailbreak and you’ll see plenty of compiler warnings.

Since Lights Off is inspired by Tiger Electronic’s game Lights Out, it doesn’t feel right to release this via the App Store. You will have to build and install it yourself; no exceptions. If requested, I will remove this project from the site, so get it now.

Now who will be the first to reach line 212 in puzzles.plist?

Note: If Apple feels this information is crossing over the NDA line, I’ll be removing this essay and the accompanying code. It’s probably a good idea to save it for reference. Hopefully they’ll realize that college students and other developers learning about the iPhone will find it helpful.

Symbolicatifination

Now that we’re all beta testing, we’ll hopefully get some crash logs from testers. But you’ll quickly realize that these crash logs don’t look as good as they do when you pull them off the device with Xcode’s Organizer: there are no symbols and fricken’ useless because you can’t tell where the code is crashing.

Thanks to the free-flowing information regarding this wonderful SDK we’re all using, it took me awhile to figure out how Xcode “symbolicates” these crash logs. The secret is here:

/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneRemoteDevice.xcodeplugin/Contents/Resources/symbolicatecrash

I copied this script into my ~/bin folder so I have easy access to from the command line. You’ll probably want to put it somewhere in your $PATH, too. I chose not to use a symbolic link because I don’t want to lose this valuable script during an Xcode upgrade.

After you’ve gotten things setup how you’d like, it’s a simple matter of running the script like this:

% symbolicatecrash Twitterrific_2008-07-21-191314_Nero.crash

Note that the script uses Spotlight to locate the .dSYM files used by atos. (Check the top of the PERL source code for a summary of how this tool works.)

This has a very important implication for your iPhone app development. It is absolutely essential that you save your .dSYM files for any release you make public. You also need to make sure that Spotlight is able to index those copies. (Some of us like to keep Spotlight out of project folders.)

I’d also suggest taking a look at the source code for the script. You’ll see that architectures besides “armv6” are supported: if you have a need to symbolicate logs from “i386”, “x86_64”, “ppc” or “ppc64”, it should work fine. There are also some options for parsing the crash log that I don’t fully understand. Yet.

Again, if Apple feels this information is crossing over the NDA line, I’ll be removing this essay. It’s probably a good idea to save it for reference. In any case, enjoy your newfound ability to symbolicate!

Update August 14th, 2008: symbolicatecrash has a bug that prevents it from working correctly when there is a space name in the path where the .dSYM files are being archived. Your app symbols won’t be included in the output if they are stored in a folder like “~/Projects/dSYM Archive”: use “~/Projects/dSYM_Archive” instead. (rdar://problem/6150458).

Update August 14th, 2008: If you add this script to the end of your build, it will automate the process of creating the .dSYM and .app archive. You’ll need to update the configurations which will be checked: $CONFIGURATION = “Distribution-Free” is specific to my project. Note that the .app binary that’s saved is not the same one that ends up in your build folder. It hasn’t been compressed or code signed (rdar://problem/6150088), but it appears to have enough information for symbols to be resolved with atos.

Update September 25th, 2008: If you’re having problems locating the crash logs, take a look at this article. It explains where iTunes puts the files on Mac OS X, Windows XP and Vista.

Update December 11th, 2008: Bryan Henry has discovered and fixed a bug with symbol name lookups. If you’re experiencing this problem, duping the Radar wouldn’t be a bad idea either.

Known issues…

First off, thanks to everyone for the kind words about the new version of Twitterrific. It’s really great to get all this awesome feedback! Don’t forget to post a review on iTunes: we want as many stars as possible :-)

As with any first software release, there are a few known issues:

  • After you upload a picture to TwitPic, the keyboard disappears. This is an Apple bug which we can’t fix (they are working on the problem.) In the meantime, you can try to tap on the text area and when the loupe appears, so will the keyboard. If that doesn’t work, try tapping the “Close” button and then tap the Reply or Post button again to refresh the interface (your text will be preserved.)
  • Some images uploaded to TwitPic are not rotated correctly. Again, this is a bug with the EXIF data that Apple is putting into the JPEG image. We are working on a workaround now, but didn’t have it ready in time for the launch. We’ve also heard from TwitPic that they are working on some AJAX code that will rotate the images directly in the browser, so that may help in the short term.
  • Scrolling is jerky. Because we have links and variable height rows in the list, we are pushing the limits of the processor. We have some ideas of how to improve this in the future, by only displaying the text of the tweet after the scroll finishes (similar to how the avatar images work now.) This is really tricky code to write and we had a very tight deadline—trust me when I say it bugs us, too :-)
  • The Sigur Rós ad from The Deck displays incorrectly. The root of the problem is that Twitterrific can’t handle HTML entities. It could, but that would compound the problems with jerky scrolling mentioned above. We’re working with the folks at The Deck to change this over to UTF-8 so it will work OK on the phone.
  • Entering a “+” sign in your tweet ends up as a space after being posted. It’s surprising that no one typed this character in several months of testing. We’ll fix this ASAP.
  • Launching the application can cause a restart of the iPhone. All indications at this point are that this is a problem with the iPhone OS and not Twitterrific (it’s happening with other applications.) We are working with Apple to resolve the issue. Please make sure to send any crash reports if prompted by iTunes. No matter how much you beta test, there’s always one problem that slips by—even if you’re Apple.
  • Sorry, but we can’t offer discounts or free upgrades for the iPhone version to current Twitterrific users. There are no provisions on the App Store for developers to do this. Please contact Apple if you think there should be a way to do this—we already have :-)
  • The push notification service announced by Apple during the WWDC keynote will not be available until later this year. We don’t know if Twitterrific will be able to support it or not: it requires additions/changes at the source of the data (Twitter) and the volume of information may be too great for Apple to handle. We are definitely keeping an eye on things and talking to the right people.

If you find something that’s not on this list, please let us know by using the contact form at the Iconfactory. Select “Support” in the drop-down menu. Thanks!