The devil is in the details

I’m a very detail oriented person and one of the things that annoys me in reading code is something like this in header files:

Copyright 2010 __MyCompanyName__. All rights reserved.

There are numerous posts including this one that tell you how to change this by default. However, you can change it on a per project basis in Xcode by setting the organization. While many may consider this minor, the question I have to ask is “what else did the developer miss?”. This kind of detail is one of the reasons I’ve been quite good at reviewing code and finding issues.

I’ve seen this mistake made in commercial projects as well as open source projects. Do people look at the code when they first create a file? While we’re at it, when I create a file, I make sure the copyright is set to whoever really owns the source; when I’ve done contract work, the source is always owned by the client, so I make sure it is set. About 70% of the code I’ve seen has had the wrong copyright. Most people don’t care about this, but if push comes to shove, I don’t want to be in the middle of someone trying to determine who owns the code.

New Service: Professional Source Code Review

While discussing what I should do with my spare time, a colleague suggested that I write a book. That sounds interesting, but what makes me qualified to write a book? He said what makes anyone qualified to write a book. Good point, but I still am not writing a book.

Today I spent my time on the (almost) daily dog walk thinking about that and came up with an idea “professional source code review”.

So, I’m now opening up my new service. For a flat fee, I’ll spend up to 5 hours reviewing source code and then I’ll prepare a detailed outline of issues and recommendations on how to proceed. Who am I targeting? In general I’m looking for companies that have outsourced their projects and want to keep an eye on the development to make sure they’re getting their money’s worth and to be advised of where things can go wrong. Many companies that undertake development don’t have internal resources to review source code and rely completely on the outsource vendor. While many applications work, reviewing code can assist in polishing the code and possibly preventing future issues.

What happens if your vendor fixes the issues and you want another review, I’ll spend an additional 5 hours (at half price) re-reviewing the code. Are my services cheap? Well, no, but how much is your vendor going to charge you fixing their own mistakes? Software development is a unique business where we’re paid to write the software and then fix mistakes (most projects I’ve worked on are on a time and materials basis).

Why should you hire me? I’ve been writing handheld software for over 16 years (yes, I actually have as I wrote Newton software while I was still in college). I’m very meticulous and have seen enough code to know what is good and what is bad. Software can work, but some of the hardest problems to track down are caused by poorly written code. I can help resolve these issues.

If interested, contact me. Of course, there are certain projects that I can’t review, so I’ll need a high level overview of your project before I can let you know about proceeding.

Why oh why? or What was I thinking?

I was profiling some code today and saw a blip when a startup window closes. For some reason that I have yet to explain, I struggled with the code. What I ended up putting in was something like this:

[self performSelectorInBackground:@selector(closeStartupWindowInBackground)
                       withObject:nil];

with closeStartupWindowInBackground defined as:

- (void) closeStartupWindowInBackground
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[NSThread sleepForTimeInterval:1.5];
	[self performSelector:@selector(closeStartupWindow)];
	[pool drain];
}

Now, anyone that has done Objective-C for awhile knows that this is utter crap. Why spawn a new thread to simply do something after a delay? The correct way to do this is:

[NSTimer scheduledTimerWithTimeInterval:1.5
                                 target:self
                               selector:@selector(closeStartupWindow)
                               userInfo:nil
                                repeats:NO];

or

[self performSelector:@selector(closeStartupWindow)
           withObject:nil
           afterDelay:1.5]

In addition to spawning the thread, the original code closed the window on a background thread. Many parts of AppKit are not thread safe, so doing that could potentially crash.

Does anyone know why I’d do something so stupid as write that original code?

[Update: this gets worse, going back 9 months to my original code before I touched it, I had the performSelector code in there to begin with, but for some reason though that it would block the main thread. Granted it does block the main thread briefly while executing the close method, but that’s fine.]

Four years of going Paperless

I’ve always been good about keeping receipts, but I just shoved receipts in folders sort of ordered by date. Just over 4 years ago, I was looking for a receipt and got frustrated that I couldn’t find one. The idea for ReceiptWallet (now Paperless) was born as there was no other Mac product on the market tailored to receipt management. Two weeks of work later, I had a working version of the software and released it to the world a few weeks later.

Ever since then, I have scanned every paper receipt, stored every web receipt, as well as every manual I’ve received. To many, this may sound like overkill, but I’ve had no problems easily pulling up receipts for everything I’ve bought. Some stores accept copies of receipts and I hope that more will do so in the future. I’ve gone one step further and pretty much every piece of paper that comes in our door gets scanned as it make it so simple to find documents that there is almost no reason to use a regular filing cabinet (OK, I still file the paperwork after scanning and storing) as scanning is easy and storage space is cheap.

More and more documents are being delivered electronically, so it makes sense to store everything electronically (as long as you have sufficient backups). Printing out documents is usually a waste.

I still keep the paper receipts, but this year, I’m going to do more cleaning and get rid of all the ones I can no longer read and ones for items that I’ll never return.

If you haven’t started a system for storing documents electronically, there is really no reason to delay; scanners are cheap and fast and storage space is plentiful. I highly recommend the Fujitsu ScanSnap scanner and have recently been impressed with the Brother MFC-7840W all-in-one (more on this device in a future entry).

Objective-C/Cocoa Tips

[Updated 7 November 2010.]

I’ve been writing Objective-C and Cocoa code for almost 8 years, but it feels like a lot longer. There is good reason for that and it’s that during that time I haven’t just worked on projects during the day, I worked on projects at night, so the 8 years is more like 10-12 years of writing code. During that time, I’ve written a ton of code and come up with a lot of tips to help me. Each developer has his/her own style, so I’m sure that some people will take objection to some of what I say. However, a number of projects I’ve worked on could really have used this information to be more solid.

Without further ado:

  1. When you start a project, set the Organization in the project so that all new files created have the correct copyright. Pretty much every project I’ve worked on has most of the files stamped with the wrong copyright.
  2. Never use [self autorelease] or [self release]. These make code very hard to trace and WILL lead to a crash when another developer comes along and releases an object thinking there is a memory leak. Code should be restructured so that whoever instantiated the object releases it. In addition, CLANG will flag objects that aren’t released as a potential memory leak and having to sift through the CLANG messages every time analyze is done.
  3. Follow Apple’s guidelines on method naming. Methods that return an object that must be released by the caller must begin with “alloc” or “new” or contain “copy” in it. (create also seems to be in there as well). Methods that return an autoreleased object must NOT start with “alloc” or “new” or contain “copy” in it. These are important so that CLANG can analyze your code and not flag things that require you to have to go through each issue and trace the code.
  4. Never subclass core objects such as NSString, NSArray, NSSet, etc. If you need additional functionality either use a category or make a new class that has the object as part of it.
  5. If an object is added to an array, an NSOperationQueue, etc., make sure the object is released or autoreleased.
  6. Don’t use [NSObject new]; use [[NSObject alloc] init]; This is simply for readability. While they are equivalent, every time I see an alloc/init, I know I have to do a release or autorelease. “new” isn’t as widely used and someone could accidentally do self.object = [NSObject new] which would cause a memory leak if the object property is retained.
  7. Use assign properties for objects in limited cases such as XMLNodes or delegates. In most cases properties should be retained or copied.
  8. Don’t do a lot in the init methods. Also, be careful of using self.xxxx in an init method as there can be side effects in the assignment if you are using KVO or have your own setter. (The side effects part comes right from a WWDC presentation.)
  9. For properties that are retained, don’t do self.xxx = [[NSObject alloc] init]. This is a memory leak. You can add autorelease to the end or do the assignment in a few steps, i.e.
    	NSObject *obj = [[NSObject alloc ] init];
    	self.xxx = obj;
    	[obj release];

    If you don’t want KVO, you can eliminate using self. However, make sure you release the object before assigning it.

  10. Only use threading if you absolutely must and use NSOperations as much as possible. Threading is tricky and I’ve only seen a few places where it has been done right.
  11. Never make different build products using scripts, define values, and configurations. Use build targets. If you don’t, your project file will change all the time and people will keep checking in a slightly modified project file.
  12. Don’t put unnecessary things in the .pch file, create a Defines.h for that. Use the .pch file for including other files, one of which can be Defines.h. Put the Defines.h at the top of the project to make it easier accessible.
  13. Don’t name every file in the project with the same prefix. If you are sharing code with other projects, then making those have the same prefix, that is fine, but if you have 100 files that start with SG, it becomes quite annoying.
  14. Don’t sprinkle UNIX like code everywhere and don’t use UNIX calls when Cocoa calls are available.
  15. If you use CoreData, first read as much as you can about CoreData. Second, explicitly set the managedObjectModel and don’t let the OS do it for you. The OS will merge all the managed object models in your bundle and create 1 model. This is problematic when you have to do migrations.
  16. If using CoreData, use the XML data store until you are comfortable with the data model. Verify the metadata in the XML before you switch to sqlite.
  17. Networking code is hard. Make sure you don’t use synchronous calls even in threads as you can’t handle cancels. Use NSOperations for the calls. Debugging the code is even harder than writing, so don’t over complicate it.
  18. Don’t do version numbering in Info.plist files as you have to update 3-5 items each time you change the version number. See my post on an easy way to do this.
  19. Don’t use NSAssert everywhere. Do actual error checking and handle conditions where necessary. While NSAsserts are usually compiled out for release builds, NSAsserts just annoy me to no end and basically serve no purpose to me.
  20. Make sure builds compile with no warnings. Don’t ship code with build warnings unless there is some type of compiler issue preventing this from happening.
  21. Don’t turn on unnecessary flags in Xcode; making warnings into errors makes it hard to test code. If you abide by the item above, you don’t need to make warnings into errors.
  22. Before checking in files, always do a diff from your changes to what’s in source control. Don’t check in files just because you change 4 spaces into a tab. This also helps review the code and make sure you didn’t leave in test code.
  23. Never store a value using NSNotFound. Seems pretty obvious to me. Apple says:

    Prior to Mac OS X v10.5, NSNotFound was defined as 0x7fffffff. For 32-bit systems, this was effectively the same as NSIntegerMax. To support 64-bit environments, NSNotFound is now formally defined as NSIntegerMax. This means, however, that the value is different in 32-bit and 64-bit environments. You should therefore not save the value directly in files or archives.

  24. Never release an NSOperationQueue from within an NSOperation. That’s like pulling the rug out from under you while you’re standing on it!
  25. Be careful with type casting.
    NSUInteger value = (NSUInteger) -1;

    could have very strange consequences. Likewise, doing:

    NSUInteger value = (NSUInteger) NSNotFound;

    May not do what you want it to do and the results could be different on 32 and 64 bit machines.

These are just some tips that I’ve learned/developed over the years. I write a lot of code and have been involved in a number of projects that need TLC. Feel free to comment if you have more tips or want to debate anything I have written; these aren’t the be all, end all to writing code, but they do help me write code that will stand the test of time (I recently got involved in a project that has code I wrote over 6 years ago that is still in use!)

 

Review: Charles Proxy – Useful development tool; ugly interface

During the testing of one of my projects, our QA folks mentioned a tool called Charles Proxy that they used to throttle the connection speed down to 3G speed as some issues can only be reproduced on slow connections. I pretty much ignored the product as I wasn’t assigned any bugs related to this. A few weeks later, I was assigned a bug dealing with 3G. As I really didn’t want to try to reproduce the issue on a device over 3G (the iPhone simulator makes it easy to reproduce issues, but as Apple points out, there is nothing like testing on a real device), I downloaded Charles Proxy and gave it a whirl. Unfortunately the limitations in the demo quickly required me to cough up the $50. As much as I was reluctant to cough up the money for an app that doesn’t look like a Mac app, it has already paid for itself.

Throttling down the connection speed seems to be one of the small features of Charles Proxy. It is a full tool for analyzing web traffic. When developing iPhone applications that talk to web services (which is pretty much everything these days), being able to look at the packets, headers, responses, XML results, and JSON results. In addition, it gives timing results for the requests so that I can see where slowdowns exist.

I’ve used it to determine that a client’s server was slow (they reported poor performance), that a different client’s web server wasn’t doing compression on text/plain files, and to see where I made incorrect requests to the server.

The major downside of the software is that the interface doesn’t look like a Mac app. As I’ve written before, I really dislike apps on the Mac that don’t look like Mac apps. Cross platform apps just aren’t my cup of tea.

 

Pros

  • Extremely useful for iPhone app development involving web services.
  • Lots of information about web requests; requests, responses, headers, etc.
  • Easy setup; it auto-configures the Mac proxy settings when it starts and changes it back when it quits.
  • Ability to throttle down the connection speed.
  • Lots of settings.

Cons

  • Ugly Mac interface.
  • A bit costly. (Maybe not for a developer tool.)

Summary

If you’re developing iPhone (or even Mac apps) that involve web services, Charles Proxy is an absolute necessity. If you ignore the ugly interface (I’m not talking about the layout, just the interface elements don’t look very Mac like), the app works well and gets the job done. It could be prettier, but the tool is extremely useful.

Developing iPhone applications with teams

In my last post, I identified a number of areas that make developing iPhone applications with teams problematic and sometimes difficult. In this post, I’m going to present some of my ideas on how to make it easier.

  • Use source control. While this may seem obvious to most developers, there are certain aspects of development that people aren’t putting under source control. This includes, mobile provisioning files, certificates, and private keys. I’ll expand on these items later.
  • Give all developers the team agent credentials. Teams should designate one member to deal with provisioning (add devices and generate mobile provisioning files), but there may be a time when another developer needs to do it (someone is sick or has gone home for the day). This can be a security risk, but until Apple allows admin users in the provisioning portal to do everything that an admin user can do, this is absolutely necessary.
  • Each developer should create a separate developer certificate. While the developers should have team agent credentials, each developer should have his/her own account associated with the team. This will allow the developer to create a certificate and install the development builds on a device. I wrote about the process of generating multiple certificates with one private key which is important for developers working on multiple projects.
  • Check the distribution private key and certificate into source control. One of the steps in distributing an application either via AdHoc or AppStore is to create a certificate signing request for the company, upload it to the provisioning portal and then generate a certificate. After this has been done, the certificate and private key (exported as a .p12 file) should be checked into source control so that all developers can install the key and potentially generate AdHoc or AppStore builds.
  • Create a build script. Use bash or another shell to create a script that checks out the source code and builds the app. For extra credit, have the build script generate a .ipa file to easily distribute the app and then zip it up along with the mobile provisioning file. In addition, I have my scripts zip up the app and the dSYM file and place it in the source tree (I only checkin the AppStore builds as we generally have a lot of AdHoc releases). This allows any developer to analyze the dSYM file in case of a crash. My scripts name the output files using the svn revision and a timestamp to keep things straight. Lately I’ve modified my scripts to allow a developer to specify the trunk, a specific revision, or a specific tag. In theory, anyone can generate a build with no special knowledge.
  • Be careful with source control. This isn’t specific to iPhone development and applies equally as well for other types of development. When I start work each day or after a break in the day, I try to remember to update my source code. In addition, I always make sure I checkin my code at the end of the day. In addition, I check in groups of files at a time and avoid doing huge checkins as the more files I touch, the more chance of having a conflict with another developer’s changes. I use Versions for a visual Subversion tool. This makes it easy to see what files I’ve changed and then before I check in my changes, I diff the files to see everything that I’m checking in. I have Versions setup to use Changes to make it easier to compare the files. It does take more time to checkin my changes, but this gives me an additional opportunity to review my changes. If I try to submit and there is a conflict, I carefully review the conflicts.
  • Use instant messaging. I’ve been working from home for 11 years now, so I’ve been remote on just about every project I’ve done. I use instant messaging with other developers, our QA, and my project manager. While sometimes it is easier to call, a quick instant message is very valuable in collabarating. It allows be to bounce ideas off other developers and get more information on bugs from QA.

These are just some of my ideas; I’m sure I’ll have more and I’m sure not everyone will agree with them. My hope is that these ideas will help me work better on teams.

Feel free to comment and leave your own ideas for team development.

iPhone Development and teams

Since I’ve been self employed again, I’ve been working on 3 iPhone development projects. On 2 of the projects, I’m the lone developer (at the moment), with a QA resource and a project manager. On the 3rd project, at its peak, we had 5 developers, 7 or 8 QA folks, and a project manager. This last project has made it painfully obvious to me (more so than the other 2), that Apple has designed iPhone development around the loan developer that has no formal QA.

Why do I say this? Well, for a number of reasons. First off, the whole provisioning thing is quite problematic for a team. The concept that only the team agent can do AdHoc and AppStore provisioning is not realistic. The Team Agent has typically been someone that is the CTO of a company or someone else that is not involved in the project on a day to day basis. We have to pass around the agent credentials in order to do provisioning (admin privileges are not enough).

Second, Xcode’s Build and Archive is not maintainable for a team. If one person does the build, another person on the team may have to examine the crash logs and therefore need the dSYM file in the archive that is built. The archive needs to be checked into source control, but Xcode hides it somewhere else.

Third, with Build and Archive in preparation for deploying as either AdHoc or AppStore, the developer is building the app from his local source tree. Almost all projects that I work on are built using a build script so that the builds are done from source control in order to have a reproducible build. Building an app from the local source tree is quite dangerous as a developer may have forgotten to check in a file and then the next person comes along may not be able to build the app.

Fourth, Xcode’s managed provisioning isn’t all that helpful. It generates a completely wildcard provisioning file which I’m not really sure how it affects different apps when there are different app IDs. In addition, most of the devices that are provisioned aren’t on developer machines, but are QA devices and other devices.

Fifth, the 100 device limit for AdHoc provisioning may sound like a lot, but if you have a team with 5 developers, each with 3 or 4 devices (iPhone 4, iPhone 3GS running 3.1.3, and iPad), and then have 7-8 QA folks with 3 devices each, you can see that the devices get eaten up quite quickly. This isn’t even considering all the devices a client may want to use for testing. I understand that Apple doesn’t want people using AdHoc provisioning to get around the AppStore, but here is a case where we’re doing the right thing and could run into issues.

Sixth, Xcode’s ability to deploy an application to the AppStore is another area where it is problematic for the team. This requires that one of the developers does the submission. In theory, QA should do the upload once the build has been approved. The way around this, of course, is to use the Application Loader to handle it. However, the Application Loader application is half baked and very much geared to only working on one project. You have to go back through the setup wizard to change accounts (I’ve done uploads for 3 different projects).

While it is true that probably 95% of iPhone development is done by single developers, some of the top applications are done in teams and I think the teams are still trying to figure out the best way to handle development.

In my next post, I’ll outline some of my ideas/practices for effectively working in teams on iPhone development.

Open source is not always the answer

I’ve been a huge fan of open source software for years and have contributed back to a few projects including the Palm OS Emulator and pilot-link. I’ve used a number of open source projects in my own applications and, of course, follow the license for attribution (I don’t touch GPL code). Years ago when I was a lot greener, I used open source thinking that it must be perfect and treated the code at black boxes. This bit me on at least one project where we had to fix the code for years due to assumptions by the developer.

Now that I have more years under my belt and have done some of my own open source, I take a different view of open source. When I incorporate open source into my projects (with a few exceptions such as Sparkle that has been thoroughly tested), I closely examine the code and make sure I understand it. This takes time, but makes it less likely that I’ll get bitten. I’ve seen a number of projects where developers find open source, shove it in an app, and call it a day without understanding what it does. I found one piece of code that completely went against what Apple has said to do in determining if a feature exists on a device; in another application, I found extremely complex networking code that may have been unnecessary (networking code is hard and the more complex it is, the harder it is to debug).

The main thing to realize with open source is that it was written by humans that can make mistakes and do! I have a large collection of open source code on my machine for reference (someday I’ll catalog all that I’ve found) and use it to save time. I’m not saying that developers should reinvent the wheel for every piece of code, but they should be cautious when shoving code in their applications.

iPhone Developer Provisioning Portal Tips

Recently I’ve been put on 2 different iPhone development projects and on both projects, I’m responsible for doing the builds. Any developer that has dealt with the provisioning portal knows how confusing and how much of a pain it is to use. It looks to me like there is a bit of confusion over the portal, so here are some tips.

  • There are 2 types of distribution mechanisms; one is through the AppStore and one is AdHoc distribution. So, they need to be differentiated in the project and on the portal to make it clear.
  • In your project, I recommend creating 3 configurations; Debug, AdHoc, and AppStore. This makes it clear what you’re doing.
  • Only the Team Agent (the person that signed up for the developer account) can create the distribution mobile provisioning files (AppStore or AdHoc). So if you as the developer didn’t set up the account, you either need to get the credentials of the person that signed up or bother that person when you need to add/remove devices for the AdHoc build.
  • Name your provisioning profiles in the portal with AdHoc and AppStore (respectively) so you can easily select the right profile in Xcode. Naming one Distribution is not very helpful.
  • Bundle the AdHoc mobile provisioning file with every build sent to testers; the file is small and then no one has to ask you for the file later.
  • Save yourself some headaches and check the mobile provisioning files into source control.
  • Export the private key and certificate used to create the distribution profiles as a .p12 file and check that into source control. Depending on how paranoid you are, you might also check in a file with the password for the .p12 file. The next developer that takes over your project will thank you for not making them jump through hoops.

While some of this may be obvious and I’m sure some people won’t agree with what I say, I think that these tips really make it easier to manage iPhone development.