Jan 172009

My iPhone development signing certificate expired yesterday. Thankfully I found that creating a new certificate is quick and painless. Luckily I still have my Certificate Signing Request (CSR).

All you really have to do is upload the CSR. If you don’t have it, you’ll have to create a new one by following the instructions in the certificates tab in ADC’s iPhone center.

After uploading the CSR, you’ll have to approve it by clicking the ‘approve’ button in the certificates tab. In a few minutes, the certificate is ready to download.

Jan 122009

Thanks to Craig Hockenberry for pointing out that iPhone developer & distribution certificates are beginning to expire. I checked my keychain and found that my developer certificate expires tomorrow and my distribution certificate expires on the 25th. I’m not sure if I still have my original certificate signing request (CSR), so I’ll probably have more work to do.

For any other iPhone developers reading this, open Keychain Access, do a search for ‘iPhone’ and note the expiration dates. Don’t be caught by surprise.

Dec 142008

D90 Video I captured at last night’s tree trimming party, with music added in iMovie.

Lots more photos here.

Dec 122008

In an application I’m working on, I display a UIWebView with a navigation bar. I wanted to display the title of the web page in the navigation bar when I load a page, but there doesn’t appear to be any obvious way to do it.

There’s actually a very easy way to get the title (or any other property) of a page in a web view: stringByEvaluatingJavaScriptFromString:.

In this case, I use the delegate method webViewDidFinishLoad to obtain the page title and set the title of the navigation bar,

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString* title = [webView stringByEvaluatingJavaScriptFromString: @"document.title"];
    navbar.title = title;
}

The result looks like this:

iPhone Simulator
Uploaded with plasq’s Skitch!

Nov 302008

Coda is my favorite web development environment on the Mac, combining a syntax-aware editor, a visual CSS editor, and an FTP client that can sync local changes to the web server. Until I read this item at Dra Studio, I had no idea you could add custom books to Coda.

Adding books to Coda is very simple – simply click the ‘+‘ button at the bottom of the Books page and enter the book title, main URL, and a search URL. You can find URLs for some useful books to add at Dra Studio & SitePoint.

I find the WordPress documentation (codex.wordpress.org) especially useful when working on WordPress plugins or themes.

Coda
Uploaded with plasq’s Skitch!

Nov 222008

One of the changes I’m making in the next version of ICanHasCheezburger is improved multi-touch handling. In the current version, I’m only handling left & right swipes to switch to the previous or next images. For the update, I’d like to handle the same gestures as the photo app:

  • Pinch to zoom in & out
  • When zoomed in, drag the image to see different portions
  • When zoomed or moved, double-tap to return to the standard zoom
  • Swipe left & right to move to the next image – but NOT when zoomed in
  • Single tap to toggle toolbar & menu bar

In many cases you can use a UIScrollView, which implements most of those behaviors. For ICHC, I decided to subclass UIImageView to handle touch gestures.

Nov 202008
Making lulz
Uploaded with plasq’s Skitch!

Sep 282008

I like to check Flickr’s camera finder page every few days to see how popular the D90 is. As I write this, the D90 is ranked 15 of 102 Nikon models. Less than a week ago, it wasn’t even listed. Yesterday it was #19, a jump of 4 places in one day.

Here’s a shot I took today with my 50mm lens at f1.8. I love being able to use auto focus with that lens.

New Orchid

Sep 262008

Since the F**KING NDA makes it difficult to find iPhone programming tips & sample code, I thought I’d share this little tidbit.

Sometimes the easiest way to display a help or information screen is a UIWebView. It’s very easy to display the contents of an HTML file stored in the application’s resource bundle.

    NSData *info = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"info" ofType:@"html"]];
    [webView loadData:info MIMEType:@"text/html" textEncodingName:@"utf8" baseURL:nil];

However, if you have any external links, they will open in the same web view, which you probably don’t want. I found a very nice work-around to have any clicked URLs open in Safari. You’ll need to specify a delegate for your web view that implements the webView:shouldStartLoadWithRequest:navigationType method. The code is very simple.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if (navigationType == UIWebViewNavigationTypeLinkClicked) {
        [[UIApplication sharedApplication] openURL: [request URL]];
        return NO;
    }
    return YES;
}

Sep 192008

Kudos to Craig Hockenberry for defying Apple’s F***ING NDA and releasing the source code for an iPhone game, Lights Out, as inspiration for aspiring iPhone developers.

Aug 272008

Xcode gives this very informative error message when an iPhone enabled for development is being updated in iTunes.

Very informative XCode error
Uploaded with plasq’s Skitch!

Aug 262008

For the past few months I’ve been working on a server administration application (I can’t go into specifics). It was ported Windows code that included some MFC emulation using old-fashioned Mac APIs such as WaitNextEvent. As expected, it never worked reliably and I was starting to feel defeated by it.

I figured out that the actual server code consisted of self-contained C++ objects that had very little to do with the application code. I ended up throwing away most of the old application code and grafting the server code into a modern Cocoa application using some ObjectiveC++ bridge classes. Once I got it to build, it took less than a day to get it working, and in the process fixed lots of long-standing bugs.

Aug 132008

TouchCode is a set of iPhone open source projects that fill in some features that are missing from Cocoa Touch. The most useful part is TouchXML, which is a drop-in replacement for Cocoa’s NSXML* classes.

I was able to get the unmodified ObjectiveFlickr code working by simply doing a global search & replace of NSXMLDocument with CXMLDocument, NSXMLNode with CXMLNode, and NSXMLElement with CXMLElement. The result is less ugly than using NSXMLParser.

For the Official LOLCats application I need to handle RSS feeds, which I found to be exceptionally ugly with NSXMLParser. With TouchXML it’s easy. I can get an array of items with something like this:


NSError *err = nil;
CXMLDocument *doc = [[CXMLDocument alloc]
initWithContentsOfURL: [NSURL URLWithString: @"http://feeds.feedburner.com/myfeed"]
options:0 error: &err];

NSArray *nodes = [doc nodesForXPath: @"//item" error: nil];

Aug 122008

I spent the weekend modifying ObjectiveFlickr to work on the iPhone, which was mostly a matter of changing the response handling code that depends on NSXMLDocument. I was pretty much able to plug in my MCFlickrParser class, which I use in LOLCats, to create a NSDictionary structured very much like the XML document.

Yesterday I was informed about FlickrKit, which already works on the iPhone. FlickrKit seems more advanced, but it’s also a lot larger than ObjectiveFlickr. I created simple Flickr browsers using both frameworks. The FlickrKit version is 704k, while the ObjectiveFlickr version is only 148k. I’ve only tried it on the simulator and the performance seems about the same for both.

I will probably stick with OF for this project, since I would like to support Zooomr as well as Flickr and OF already seems to support Zooomr.

Aug 102008

UPDATE: Minutes after I posted this, I got a notice from Apple that the update has been approved and is now ready for sale.

Apple still hasn’t approved my update to LOLCats. Still no response from Apple for the second update, which I feel is pretty urgent, since it reduces the possibility of inappropriate images appearing, which I’ve received several complaints about.

I’m now getting close to another update, which adds Zooomr support.

Meanwhile, I’m working on a second Flickr-related application. I had expected to share a lot of code with LOLCats, but it turns out I’ve only reused one class, my Flickr parser.

For this app, I need to support Flickr authorization, so it seemed easier to rewrite Flickr’s ObjectiveFlickr code, which already supports authorization. However, ObjectiveFlickr depends on XMLDocument, which isn’t available on the iPhone. I’m replacing the response handling code with my Flickr parser class. When it’s finished, I’ll release the Flickr-related code (not the entire app) as open source.

On a fun note, I purposely added the LOLCATS tag to this photo of Midnight to make it to appear in the application. As a result, the number of hits on that photo are about 100x the average for my similar photos.

Midnight watching

Aug 082008

Until I started poking around in Flickr’s Objective C code, I didn’t realize that Zooomr supported a variant of Flickr’s API. I found that it’s fairly easy to port code which uses Flickr to Zooomr. In less than an hour, I had LOLCats working with Zooomr. I plan to include Zooomr support in the other iPhone Flickr app I’m working on.

Aug 052008

I recently moved my Subversion repositories from my home server to Dreamhost, for the extra safety of an offsite backup of my source code. When I switched this domain to MediaTemple it unsurprisingly broke my Subversion repository.

While DreamHost provides an easy one click Subversion setup, it requires a little more work on MediaTemple. After a few headaches, I managed to get it set up. I hope I can save some people a bit of trouble with these tips. This only applies to a GridServer. It will probably be different for other MediaTemple account types.

Unlike DreamHost, the GridServer doesn’t support HTTP access for Subversion; you can only use SSH. Note that your SSH login includes the domain name. The login will usually be serveradmin%yourdomain.com@yourdomain.com.

You’ll need to log in to your serveradmin account via ssh to create the repository. For best results, it should be in in the /data directory. After logging in, create the repository with the following commands:

cd data
svnadmin create --fs-type fsfs SVN

This will create a repository named SVN. You can use a different name if you prefer.

You can then set up the repository in XCode. Create a new repository configuration and enter a URL like svn+ssh://serveradmin%yourdomain.com@yourdomain.com/home/XXXXX/data/SVN. To find the actual path, when you’re logged in via ssh, enter the command pwd, which will give you something like /home/11111/users/.home. You can ignore the /users/.home part.

Be very careful to enter the login and password correctly. If you attempt too many incorrect logins, you will be locked out. To regain access, go to the Mediatemple control panel and click the button to unlock, and wait about 10 minutes.

SVN Setup
Uploaded with plasq’s Skitch!

Jul 312008

I found this very interesting article about the MOS 6502 processor’s illegal opcodes. My first computer was an Ohio Scientific Challenger 1P, on which I did a lot of 6502 assembly language programming.

Jul 302008

Paulo is planning another photowalk on August 23 in connection with Scott Kelby’s Worldwide Photo Walk. This one will be in Lauderdale-by-the-sea, a quaint beach town only a few miles from me, at the end of Commercial Blvd. I’ve been there many times.

Jul 252008

When you’re debugging a memory allocation issue, it’s very useful to be able to see the retain count of an object. One way to do it is by calling the object’s retainCount method, which you can do in the debugger console by entering something like call (int)[self retainCount].

That’s a lot of typing if you do it very often. Fortunately GDB lets you create macros that can make it a lot easier. To define a macro called rc, which will print the retain count, you can define a macro as follows:

define rc
call (int)[$arg0 retainCount]
end

You can now type rc self to see the current object’s retain count. Unfortunately you’ll have to enter that definition every time you start the debugger.

However, GDB lets you create a startup file with commands that will be executed every time it starts up. Simply create a file called .gdbinit in your home directory and enter that definition in it. You will now have the command rc available every time you use the debugger.

/dev/random is Digg proof thanks to caching by WP Super Cache