Archive for December 2013

Don’t forget to account for new lines in your iOS NSRegularExpression

The NSRegularExpression class is handy for searching and parsing strings. That is, it is handy until it starts to fail at seemingly random intervals.

I had a regex that was working fine on my small set of initial test data, but when I expanded it to work on a slightly larger and varied set of data, all of a sudden the weather turned a bit cloudy.

After some investigation on Stack Overflow and diving through the Apple documentation, I realized that I should probably add the NSRegularExpressionDotMatchesLineSeparators option to my NSRegularExpression, and the skies turned bright and sunny again.

Here is an example of what I am talking about. In this instance, I am looking to obtain the text in an NSString called theString that is in between the sentinel literals of =BeginTag= and =EndTag=:

NSString *pattern = @"=BeginTag=(.*?)=EndTag=";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
    options:(NSRegularExpressionCaseInsensitive | NSRegularExpressionDotMatchesLineSeparators)
    error:nil];
[regex enumerateMatchesInString:theString options:0 range:NSMakeRange(0, [theString length])
    usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop)
    {
        NSString *s = [theString substringWithRange:[match rangeAtIndex:1]];
        NSLog(@"Enumerated matching string: %@", s);
    }];

If you leave off the NSRegularExpressionDotMatchesLineSeparators flag, and theString contains new line characters in between the sentinels, you end up with no text enumerated with the block.

BTW, Happy Birthday to Steven Spielberg, one of the true geniuses of our time.

How to build an app with iOS SDK 6.1 in Xcode 5

When you update to Xcode 5, you get all of the new Xcode and iOS 7 goodness, which is great if you are ready to handle that much goodness. If you have to maintain compatibility with older applications, it can be a problem as the iOS 7 SDK will wreak havoc with your application.

The easier path for now is to just set your project to specifically build against the iOS SDK 6.1 instead of just using the “Latest SDK” entry, and then to either copy or put a symbolic link in the Xcode 5 app bundle to the SDK living in the old Xcode 4.x bundle. Personally, I have found this Stack Overflow post to be handy:

How to point Xcode to my 10.6 SDK so it can be used as a “Base SDK”?

In addition, the answer by Rob Napier references a script that you can use to automatically put these symlinks back into the Xcode 5 bundle when you update the app:

Links Xcode SDKs from the /SDKs directory

EDIT on 12/21/2013: Keep in mind this all becomes a moot point when, on February 1, 2014, Apple will only allow apps to be published to the App Store that have been built with the iOS SDK 7.0 or newer (here’s the link to the article in the iOS Developer Center).

BTW, Happy Birthday to Jim Leyland, the baseball manager who I admired greatly from his time managing the Pittsburgh Pirates.