Coding tip for if statements

When I was a young engineer, a more senior colleague of mine taught me a lot about writing code and helped me adopt my own style. Just like an artist, every developer has his own style with no style being wrong. However, there is one coding convention that he taught me I think all developers should use. Here’s what developers shouldn’t do:

if (something)
       dosomething;

Instead they should do:

if (something)
{
      dosomething;
}

(or if you prefer, put the { on the if line).

Why do I say is? It’s simple, if you come along later and add a line to the first statement, like:

if (something)
        dosomething;
        dosomethingelse;

you could have the wrong thing happen. If you wanted the “dosomethingelse” to only happen if the if statement was executed, that’s not what would happen (it would always execute). The brackets make it explicit what will happen on the if statement. I’ve seen this type of coding in a lot of code and it will definitely lead to failure at some point or another.

I’m sure some people will take offensive with what I say, but this tip will save lots of time in debugging at some point.

Managing Multiple iPhone Developer Certificates

Back in the dark ages of iPhone development, being part of 2 separate iPhone development teams was problematic as Xcode didn’t deal with multiple developer certificates too well. Now Xcode will automatically select the right certificate (it took me awhile to find a reference).

 

Xcode.png

Each developer certificate now has a unique hex value at the end which lets you have 2 certificates for the same developer. However, until today, I never managed to get this to work properly. It turns out that in order to make things easier, instead of following Apple’s directions to create a certificate signing request, I control clicked on the private key I created for the first certificate and selected ‘Request a Certificate from a Certificate Authority With “iPhone Developer Private Key (Scott Gruby)’.

 

Keychain Access1.png

 

After that I was able to create my second certificate and have it associated with the same private key (I don’t think Xcode likes 2 different keys to have the same name). I’m not sure if this was absolutely necessary or if changes to how Apple generates certificates and changes to Xcode made things easier, but I’m not going to complain. I now can debug apps for multiple teams without having to change the bundle identifier and possibly make a mistake and check it into source control.

Easy version numbering in projects

 

When I start all of my projects, I do a few things to make version numbering easy.

First, I create a Defines.h file that looks something like this:

 

 

#ifdef INFO_PLIST
#define STRINGIFY(_x)        _x
#else
#define STRINGIFY(_x)      # _x
#endif

 

#define STRX(x) x

#define APP_VERSION_NUMBER STRINGIFY(1.0.0 b1) #define CF_BUNDLE_VERSION APP_VERSION_NUMBER

 

Then,  in the build settings, I set it up like this:

 

Xcode.png

 

Then my Info.plist has:

<key>CFBundleShortVersionString</key>

<string>APP_VERSION_NUMBER</string>

<key>CFBundleVersion</key>

<string>CF_BUNDLE_VERSION</string>

<key>CFBundleGetInfoString</key>

<string>AppName APP_VERSION_NUMBER, Copyright © 2010 Gruby Solutions</string>



 

 

So, I just change 1 value in Info.plist and the version number changes. Granted I could just change Info.plist for each build, but I’d have to change a few items. This becomes even more useful when projects have multiple components. In my projects that have multiple components, I like everything to have the same version number (these aren’t operating systems, so I can require an install of all components as once). With this technique, I just change the Defines.h and all the components get the same version number.

Some people change the APP_VERSION_NUMBER and CF_BUNDLE_VERSION to be different, but this mechanism still makes it easy to change the values.

 

Leaving logging statements in production code

I’ve written in the past about how I think that leaving logging code in production or release builds is bad practice. While I have no objections to being able to turn debug logging on or off to help troubleshoot problems in the field, it shouldn’t be on by default. Recently I’ve read conflicting views about leaving NSLog statements in code. One really good solution is:

 


#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"%s %@:(%d) %@", __PRETTY_FUNCTION__,\
[[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__,\
[NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif

(I’ve modified the solution a little.)

Then in Xcode’s build settings, add a preprocessor macro for DEBUG_MODE. Presto, NSLog statements never make it into shipping code. If you need to turn the logging on and off, I like to write the statements out to a file so that they don’t pollute Console and it makes it easier for users to send me logs. Furthermore, I’ve seen NSLog cause crashes because the developer passed the wrong arguments or did something like NSLog(@”test: %d, self). This type of bug should be fixed, but using the above logging would prevent the crash in production code.

 

Tenets of software development

Lately I’ve been talking to people about some development projects and I keep repeating my 2 tenets of software development. The first is from Brian Hall of Mark/Space. He used to say

Shipping is a feature.

While this sounds quite simple in nature, it’s pretty important to any product. Not only is shipping a feature, I think it is the number 1 feature. My second tenet is something that I came up with when more and more features were added to a project and QA kept finding issues.

Software is never done; it’s just shipped.

Now you’re probably saying that these are either obvious or just plain idiotic. Anyone that has done software development for anything length of time has to agree with the second. How many bug fix releases have you done? I may strive to be a perfectionist, but I’m also a realist. You can spend forever making software perfect, but you’ll never reach the end.

It’s important, in my opinion, for anyone in a software project to be on the same page with these tenets. Without these, you can’t ship a product which means you can’t make money. There aren’t that many companies that I know of that can survive without shipping products and making money (OK, maybe there are companies that only do government contracts and keep taking money without shipping something that works.)

Cleaning up after yourself

Yesterday I saw a Twitter post from Jonathan Wight of Toxic Software complaining about background apps that when you trash them, still keep running and he suggested using FSEvents to automatically terminate when that happens.

Well, I have a number of projects that have background apps and I thought that this would clean things up a bit, so I slapped together a sample project. In addition, I’ve worked on a number of projects that suffer from the same problem, so hopefully other developers can incorporate this (or something similar) so that when you trash an app, the background helper app goes away with it.

I’m using Stu Connolly’s SCEvents to wrap up the FSEvents. This simplifies my code a bit. I’ve included his source in the download; it is released under the MIT License.

Feel free to download this code. I’m releasing it under an MIT License

Comments are welcome on the code.

Programming extortion or poor estimating?

For a project we have at work, we needed to have some Java code written for encryption. The tool we have has example code for it, but it wasn’t quite what I wanted. So, one of our developers got a quote from the company that put together the example to change the code to what I wanted as I don’t know Java. The quote to modify the code was 4 hours @ $155/hour. While I don’t have a problem with the hourly rate, I thought the 4 hours was utterly ridiculous as the example code was almost what we needed and the encryption libraries are already built into Java. In addition, getting $620 approved for this might have been more trouble than it was worth.

On Friday, I sat down, did some Google searches, installed NetBeans, and within an hour, I had the Java code working. Prior to this, I had never written a line of Java code. However, Java, like most languages I work with, has a very similar syntax that for my very small piece of code, was quite easy to understand.

So the high quote was one of three things. First, they might not have understood the request (I just double checked the email exchange and it seemed quite clear to me). Second, they could have been extremely poor at estimating. I’ve been writing software for many years now and my estimating is sometimes way off whack, but that is usually for big tasks and tasks where I’m starting from scratch, not sample code. My worst estimating that I ever did, I estimated 2 weeks (80 hours) to complete a bridge between a Mac application running as a native Intel application and a PowerPC plugin. Somehow I managed to complete this in less than 4 hours. However, I wasn’t and am still not aware of any commercial shipping application that has this functionality besides what I wrote, so writing this was a complete unknown. Third, the quote could have been high because they may have thought we had no other option and when you’re a monopoly, you can charge whatever you want.

Initially, I quickly jumped to the conclusion that the third option is what happened. After thinking about it and throwing out the other 2 options, I’d like to say that the 3rd option wasn’t the real reason, but it is really hard to discount it.

The end of unsized integers

In recent versions of the Mac OS SDK, Apple has largely moved away from datatypes such as int and long as they have different meanings in 64 bit OSes. In a project I’m working on, this bit me twice recently. The first is that a UINT (the code was ported from Windows) was incorrectly typed to be a byte or a dword (2 bytes) when it should have been 4 bytes. If the type was a UINT32 (UInt32 in Mac speak), setting the correct type would have been easy and not confusing. Likewise, there was another case where a variable was typed as unsigned long long which was 8 bytes on a 32 bit OS, but 16 bytes on a 64 bit OS (if I’m off on the values, please forgive me). If it was specified as UInt64, that is completely unambiguous and a bug would not have occurred.

So, this day forward, I’m going to do my absolute best to only use sized integers, like SInt32, UInt32, etc. where the exact size is specified. This will be much more important using both 32 bit and 64 bit versions of Mac OS X. Granted, for many developers, it still doesn’t matter, but I’ve dealt a lot of USB communications and structures, so the size of the integers makes a huge difference.

Who says hacks don’t cause problems?

The other day I had lunch with a friend and a friend of his wanting to get into Mac development. We were talking and this guy said that he admired a company that created “haxies”. I said that I really disliked them as their software can cause problems left and right with the system.

The very next day, I got a ReceiptWallet crash report where the user said he pulled down a menu and tried to create a new library. This action is pretty basic and just uses actions in the nib. In this user’s case, it caused ReceiptWallet to crash. Normally I would have ignored this and just said it was some fluke, but I decided to dig deeper. Here’s the top of the crash report:

Process:         ReceiptWallet [99875]
Path:            /Applications/ReceiptWallet.app/Contents/MacOS/
ReceiptWallet
Identifier:      com.ggtenterprises.receiptwallet
Version:         2.0.9 (2.0.9)
Code Type:       X86 (Native)
Parent Process:  launchd [98]

Date/Time:       2009-03-11 16:49:08.632 -0600
OS Version:      Mac OS X 10.5.6 (9G66)
Report Version:  6

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000c0226ccb
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib               	0x935cd688 objc_msgSend + 24
1   com.apple.AppKit              	0x947c453b -[NSApplication
sendAction:to:from:] + 112
2   com.apple.AppKit              	0x9487317c -[NSMenu
performActionForItemAtIndex:] + 493
3   com.apple.AppKit              	0x94872e81 -[NSCarbonMenuImpl
performActionWithHighlightingForItemAtIndex:] + 220
4   com.apple.AppKit              	0x9484fb5a AppKitMenuEventHandler +
6608
5   com.apple.HIToolbox           	0x964d4143
DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*,
HandlerCallRec*) + 1181
6   com.apple.HIToolbox           	0x964d357d
SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*,
HandlerCallRec*) + 405
7   com.apple.HIToolbox           	0x964efed2 SendEventToEventTarget +
52
8   com.apple.HIToolbox           	0x9652423d
SendHICommandEvent(unsigned long, HICommand const*, unsigned long,
unsigned long, unsigned char, OpaqueEventTargetRef*,

I then looked at what was loaded in memory and saw this:

  0xeb2000 -   0xeb4fff +com.unsanity.menuextraenabler 1.0.3 (1.0.3) /
Library/InputManagers/Menu Extra Enabler/Menu Extra Enabler.bundle/
Contents/MacOS/Menu Extra Enabler

Hmmm, looks like a “haxie” that deals with menus. While the company that makes these haxies has repeatedly said that their software doesn’t cause problems, but until users can prove to me that the problem is reproducible without the haxie installed, I have no insert in pursuing the matter. In a post about two years ago, a member of Apple’s DTS team wrote that they don’t investigate any crash that has haxies in it.

While I use one program (1Password) that patches the system, it is quite stable and only affects a few programs (Safari, FireFox, NetNewsWathcer). I’m just really tired of haxies that touch stuff that they shouldn’t.

The end of an idea

Ever since the iPhone SDK came out, I had planned to write ReceiptWallet for iPhone as it seemed like a logical thing to do. A few users asked for it, so I thought it was a good idea. However, today is the day that ReceiptWallet for iPhone ends. I’ve toyed with it for the last few months, but just don’t have my heart into it as it isn’t something that I see myself using. As much as I wanted to do this product to answer the needs of the public, it just isn’t going to happen. I was going to finish it to get it out the door, but then I’d have a crappy product that wasn’t my best work.

In addition, there are some serious issues that have to be overcome before it could become usable.

First off, the camera on the iPhone can’t focus close enough to get quality images. As you can see, these pictures are awful. I’m not sure they would be acceptable for any form of documentation. (Who knows, maybe the IRS would accept something that can’t be read.)

IMG_0065_thumbnail.pn

Second off, the synchronization mechanism with the desktop would not be seamless; you would have to launch ReceiptWallet on the iPhone, click on sync and run ReceiptWallet on the desktop. Apple has not provided a plugin mechanism (like Palm did with HotSync Manager) for third parties to sync data.

Third, I’m not happy with the data entry mechanism. ReceiptWallet on the desktop uses combo boxes to allow you to type a few characters and then a dropdown menu shows everything close; nothing like this exists on the iPhone.

The future may change things with ReceiptWallet for iPhone, but ending this today takes a huge weight off my chest and will let me move on.