Archive for November 2012

The technical term is “Leap Month”

So I am guessing that Google needs some help in their development and/or QA departments. Or else Google knows something that the rest of us don’t know…

I saw this little nugget tweeted about this morning and had to try it for myself. Sure enough, my Galaxy Nexus 7 with Jelly Bean 4.2 is missing the entire month of December. (To reproduce, go into the People app, edit a contact, tap ‘Add another field’, select ‘Events’, and notice that December is not in the month scrolly.)

In an unrelated story, I predict that Android 4.2.1 will be coming out very soon.

BTW, Happy 50th Birthday to Kirk Hammett, lead guitarist for Metallica.

Hello NSScanner

In an attempt to broaden my iOS development horizons, I thought I would take a look at some of those iOS classes and components that you may not know too much about or have used in the past, but probably should due to their elegance or functionality.

Today’s example is NSScanner (reference and programming guide). This handy class has one main purpose, to scan through a source string into either strings or other data types, such as integers and floats.

Converting a NSString to an integer is fairly trivial, as you can just do something like [myString intValue]. However, the NSScanner class maintains a pointer as the source string is scanned, so if you need to loop through a string and scan multiple values in from one string, NSScanner is your class. One other interesting thing that NSScanner can do is to take in a string of hexadecimal digits and convert them as well.

In the simplest case, here is how you would convert a string to an integer:

NSString *theString = @"42";
unsigned int theValue;
[[NSScanner scannerWithString:theString] scanHexInt:&theValue];

All of the scan methods return a BOOL that lets you know if the scan was successful or not, so be sure to not do what I am doing above and check the return value to make sure there was not an error.

Here is how you would process a hexadecimal string and examine each byte in the string:

int theLength = [hexString length];
for (int i = 0; i < theLength; i += 2)
    NSRange theRange = NSMakeRange(i, 2);
    NSString *hexDigits = [hexString substringWithRange:theRange];
    unsigned int theValue;
    [[NSScanner scannerWithString:hexDigits] scanHexInt:&theValue];
    NSLog(@"Byte number %d is %d\n", (i / 2), theValue);

And a final example, let’s say you had the text of an HTML page and you wanted to pull out all of the links in the page (denoted by an A tag with an HREF= entry). Here is some code that would do that:

NSScanner *scanner = [NSScanner scannerWithString:theHTMLString];
NSString *foundString = nil;
[scanner scanUpToString:@"a href=" intoString:nil];
while (![scanner isAtEnd])
    [scanner scanUpToString:@"\"" intoString:nil];
    [scanner scanUpToString:@"\"" intoString:&foundString];
    [scanner scanUpToString:@"a href=" intoString:nil];
    NSLog(@"Link found: %@", foundString);

If you would like to download the NSScannerTest project that I put together to demonstrate these features in a running app, here is the download link, make sure to be using the latest version of Xcode and iOS SDK:

NSScannerTest source code

(Bonus mini tutorial: If you download and look at the source code, you will get a little sampling of NSRegularExpression and NSTextCheckingResult, two Foundation classes that probably deserve a tutorial posting of their own in the future.)

I have a couple of ideas on what I am going to cover next, but if you have any suggestions, please use the comments. Thanks and I’ll see you next time.

DBNull string field handling

Let’s say for the sake of argument that you are using a SQL Server Compact database in your C# .NET application, and your User table has nvarchar fields that are nullable, and your User class doesn’t care if those fields are null, it just wants empty strings instead.

Sadly to say, you are eventually going to end up with nulls in those fields, and as a result, if you use a SqlCeDataReader to step through a record set, this kind of stuff will (at some point) give you a runtime error:

myUser.UserName = (string)dataReader["UserName"]);

So I started looking for the best way to handle this problem. What I didn’t want to do was this for every single string field assignment:

myUser.UserName = (System.DBNull.Value == dataReader["UserName"] ? "" : dataReader["UserName"]);

This seems a bit wasteful to me, as the data reader is accessed twice. Sure, I could have encapsulated this into a function to pretty up the code a bit, but that would just be hiding the ugliness. Then, it occurred to me to try the Convert class to see what would happen, and it turns out that this code knows how to convert a DBNull to an empty string:

myUser.UserName = Convert.ToString(dataReader["UserName"]);

The Convert class may in fact do the same thing as I have shown above, but I would hope that Microsoft would make their built in function better than something that I would just hack together.

BTW, I hope everyone out there has voted, this is an important election. (Finally, tomorrow I can watch TV or get the mail without being bombarded by increasingly stupider campaign and “issue” advertisements.)