Monday, December 20, 2010

Apple announces iAd Producer

Today Apple announced iAd Producer; iAd Producer makes it easy for you to design and assemble high-impact, interactive content for iAd. iAd Producer automatically manages the HTML5, CSS3 and JavaScript behind your iAd to make creating beautiful, motion-rich iAd content as easy as point and click.

For advanced developers, iAd Producer offers sophisticated JavaScript editing and debugging, along with a powerful extension mechanism that enables them to create and re-use their own page templates and components.

The iAd Producer features:
  • a visual design tool (IDE, kind of Quartz Composer-ish)
  • Page Templates
  • Component Library
  • Pre-built animations and effects
  • Simulator (Mac or iOS device)
  • Asset library
  • Advanced JavaScript Editing
  • JavaScript Debugging (like Safari Developer JS features)
  • JavaScript "minification" optimization
  • and Project validation 

Developers can log in and learn more...

Thursday, December 9, 2010

Announcing Device Profiler

Now available in the App StoreDevice Profiler is a handy tool for app beta testers and iOS developers, absolutely free.

Tap the DevProfiler icon to quickly find the UDID of your device. Easily email your device info to the development team so they can include your iPhone, iPod touch or iPad in the Ad Hoc provisioning profile needed to enable your device to run private beta apps.

Click here to see our complete list of apps.

Wednesday, December 8, 2010

Announcing BackWords Dictionary

Now available in the App Store, BackWords Dictionary is a new way to search for words. Pick letters with just a flick of your finger and BackWords quickly finds matching words. BackWords is a fun alternative to looking up words in a traditional dictionary, thesaurus or even on the web.

BackWords is powered by the Enhanced North American Benchmark Lexicon (ENABLE), the authoritative word list and common alternative to the Official Scrabble Players Dictionary that is used in many popular word games, including Words With Friends. BackWords contains over 173,000 words, with a few objectionable terms removed so it's suitable for word game players of all ages.

BackWords is a great helper when playing word games like Scrabble, Words With Friends or Boggle or solving tough crossword puzzles.

Click here to see our complete list of apps.

Monday, December 6, 2010

Announcing Fridgemags 1.1

Everyone loves playing with the old alphabet magnets on their refrigerator - writing out clever messages or children just learning their ABCs. But taking around your fridge to write a little message or pass some time is just a bit impractical - until now.

Fridgemags is a refrigerator in your pocket complete with magnets. Starting with the ABCs and a few extra vowels and consonants you can spell messages and save them to your photos to email to friends.

With Fridgemags young children can interact with their ABCs and are instantly engaged with and audible, visual and tactile experience.

Fridgemags is great for for anyone and available in the App Store.

Fridgemags 1.1 features include:

  • Universal Application—works on iPhone, iPad and iPod touch.
  • Letter Viewer—lets you know which letter you have selected.
  • ...and Minor bug fixes



Click here to see our complete list of apps.

Thursday, October 14, 2010

A Fix for a Seemingly Random iOS App Network Failure

Or How do I display the WiFi connection dialog?

If you're writing an iPhone, iPod touch or iPad app that uses the network, it's important that you set the UIRequiresPersistentWiFi key in your Info.plist file, otherwise your app may occasionally fail to connect to any network resources it requires. You will never see this failure in the simulator, or on an iPhone that has cellular service activated. Let me explain.

In order to conserve battery, iOS devices disconnect any active Wi-Fi connection after 30 minutes if the device is idle or asleep, unless the currently running app has the UIRequiresPersistentWiFi key set. If an app does not have this key set, the system doesn't automatically try to reestablish a Wi-Fi connection, even when your app tries to connect to the network.

The simulator uses your Mac's network connection—it never prompts you to connect via Wi-Fi. An iPhone with active cellular service will automatically use the cellular data network if the Wi-Fi transmitter is asleep.

You can test this on an iPod touch or Wi-Fi iPad, or on an iPhone in Airplane Mode with Wi-Fi turned on. In the Settings app, tell the device to forget any current Wi-Fi network; this will disconnect the Wi-Fi transmitter and turn it off. Then run your app. If you don't have UIRequiresPersistentWiFi set, the device won't prompt you to establish a Wi-Fi connection and any attempts your app makes to connect will fail.

When your app has UIRequiresPersistentWiFi set, the device will automatically connect to known Wi-Fi networks or pop up the standard Wi-Fi connection dialog if no known Wi-Fi network is available, and will maintain the connection while your app is active. This is especially critical for users of Wi-Fi only devices. If users complain that they sometimes have to open Safari or another app in order to get the network to connect, you forgot to set UIRequiresPersistentWiFi in your Info.plist.

One little annoyance: in Xcode (currently at version 3.2.4), the Info.plist editor doesn't include UIRequiresPersistentWiFi in the drop-down list of keys. In order to add it, create a new row and just type UIRequiresPersistentWiFi into the Key field, then right-click on the Value field and choose Value Type -> Boolean from the menu. Alternately, in the Groups & Files tree, right click on the Info.plist file and select Open As -> Source Code File from the menu. Then you can simply add
  <key>UIRequiresPersistentWiFi</key>
  <true/>
to the <dict> tag in the <plist> tag.

Wednesday, October 13, 2010

Apple to Announce OS X 10.7 Lion

Apple sent out invitations to the press today for a Mac related event on October 20th. With a lion peeking out of the invitation, there's no doubt that the next version of OS X will be announced and be code-named "Lion".

Let the speculation begin on what other cool new things will be announced.

Monday, October 11, 2010

12 Great Tips for iPhone Web Development

I just ran across this great article on SitePoint by Stoyan Stefanov, a Yahoo engineer and author of Object-Oriented JavaScript. It's called iPhone Development: 12 Tips To Get You Started. Since SitePoint is all about web development, they left the Web out of iPhone Development, but it's a great article nonetheless.

Stoyan covers just about everything you might want to do with HTML, CSS and JavaScript to customize your site for the small screen:
  1. use the iPhone Simulator and SDK documentation
  2. add the correct CSS @media declaration
  3. set the viewport meta tag
  4. handle orientation changes with JavaScript
  5. set orientation specific styles
  6. hide the Mobile Safari toolbar
  7. use CSS to create rounded corners
  8. handle touch events
  9. handle gestures
  10. add links to make voice calls and send text messages
  11. add an app icon
  12. debug using JavaScript and Xcode
Unfortunately he doesn't cover anything specific to the iPad—the article is actually from April 2009. Still, whether you want to optimize your site for iPhone and iPod touch users or need to show some custom web content in a UIWebView in your native app, just about everything you need to know is summarized right here. Check it out!

Friday, October 8, 2010

iPad Friday: October 8, 2010

Hello and happy Friday.  Today's collection of iPad wallpapers are from a experimental project and soon to be iPhone app.  These wallpapers make great backgrounds so you can easily see your icons and labels.  Cheers!

(click an image for the full-size wallpaper)












iPhone Friday: October 8, 2010

Hello and happy Friday.  Today's collection of iPhone wallpapers are from a experimental project and soon to be iPhone app.  These wallpapers make great backgrounds so you can easily see your icons and labels.  Cheers!

(click an image for the full-size wallpaper)












Thursday, October 7, 2010

Xcode Analyzer Error: "Analyzer skipped this file due to parse errors"

Apple integrated the Clang Static Analyzer into Xcode a while back. It's a part of the LLVM project and it uses the clang C/C++/Objective-C compiler front-end to the LLVM compiler to perform static analysis. The static analyzer (or "clang checker") is really useful for finding common retain/release errors in Objective-C code. You run the analyzer by building your project using the Build and Analyze item under the Build menu.

When I recently went to run the static analyzer on one of my projects using the recently released iOS 4.1 SDK, I got a series of the following types of errors:
Analyzer skipped this file due to parse errors

 '/var/folders/p9/p9X0YndXGHyxgsdRDDYre++++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders/PrecompiledHeaders-cbytywsinixhviaxvbooriusnxyo/PrecompiledHeaders.pch' file not found
I found the following workaround for the problem in the Apple developer forums (registration required).

On the Project menu, select Edit Active Target "MyProject" to bring up the Target Info dialog. Edit the Other C Flags setting and add -D__IPHONE_OS_VERSION_MIN_REQUIRED=030000, where 030000 corresponds to the iOS Deployment Target setting:
  • 3.0 -> 030000
  • 3.1 -> 030100
  • 3.2 -> 030200
  • 4.0 -> 040000
  • 4.1 -> 040100
Then the analyzer should be able to run successfully.

Wednesday, October 6, 2010

iOS SDK 4.1 Breaks Unit Tests

I ran into this problem a couple of weeks ago, but didn't get around to blogging about it until today. If you use the OCUnit test framework that's part of Xcode to write unit tests, upgrading to iOS SDK 4.1 will give you a rude surprise:

Run unit tests for architecture 'i386' (GC OFF) did not finish

An internal error occurred when handling command output: -[XCBuildLogCommandInvocationSection testName]: unrecognized selector sent to instance 0x2010cff80

An internal error occurred when handling command output: -[XCBuildLogCommandInvocationSection setTestsPassedString:]: unrecognized selector sent to instance 0x2010cff80

An internal error occurred when handling command output: -[XCBuildLogCommandInvocationSectionRecorder endMarker]: unrecognized selector sent to instance 0x2009b8580

It seems there's a mismatch between Xcode and OCUnit in the 4.1 SDK release. At first I wasn't able to find a workaround. I was going to install iOS 4.2 SDK beta 1 anyway, so I went ahead and did that and found that the problem had been fixed. The beta SDK has been working fine for me (though you should still use the 4.1 release SDK if you're building for submission to the app store).

Checking back on this problem, there are now a couple of workarounds. Apple posted some Objective-C code in their developer forums that monkey patches the problem. And Andy W posted a simple workaround on Stack Overflow.

This isn't the first time that Apple has broken their officially supported unit testing framework with an update to Xcode. It's kinda ironic, but I guess they don't have good test coverage of their test framework.

Tuesday, October 5, 2010

Objective-C Tuesdays: replacing in strings

Welcome back to Objective-C Tuesdays! Today we follow closely on last week's topic of searching in strings with it's sibling, replacing in strings.

It's a nightmare in C
In our series on strings in Objective-C, we've usually started by looking at C strings then moved on to NSStrings. Today is no different. In most cases, using NSString is easier than doing the equivalent operation on C strings. When it comes to replacing characters in a string, using NSString is significantly easier and safer. The standard C library doesn't provide much support for doing common string replacement operations, so you have to implement them yourself. Because of all the manual memory management required when working with C strings, this code is very error prone -- writing off the end of a buffer and forgetting to add the null terminator are two very common types of errors you have to watch out for when working with C strings.

Replacing a character
The only replacement operation that's fairly straightforward on C strings is replacing a single character with another character. Since C strings are just pointers to arrays of chars, you simply calculate the pointer to the char you want to change, dereference the pointer and assign the new char value.

There are two variations of this. The first one uses array notation and the second pointer operations. In both examples below, we use the strdup() function to make a copy of our original C string. The strdup() function isn't part of the C standard library, but most systems have one available (possibly named _strdup()) and it's easy to write one if it's missing on your system (it's available on iOS). You own the string returned by strdup() and are responsible for calling free() when you're done with it.

Here's how you change a character in a C string by treating it as an array of chars:
char const *source = "foobar";

char *copy = strdup(source); // make a non-const copy of source

copy[3] = 'B';               // change char at index 3

NSLog(@"copy = %@", copy);
// prints "copy = fooBar"

free(copy);                  // free copy when done
The alternative way uses pointer arithmetic:
char const *source = "foobar";

char *copy = strdup(source); // make a non-const copy of source

char *c3 = copy + 3;         // get pointer to char at index 3

*c3 = 'B';                   // change char at address of c3

NSLog(@"copy = %@", copy);
// prints "copy = fooBar"

free(copy);                  // free copy when done
As far as the compiler is concerned, this is basically the same code so use whichever method makes the most sense. If you know the index of the char you want to change, use array notation. If you already have a pointer to the char, perhaps from calling strchr(), use the pointer directly.

Replacing a substring
Replacing a substring of a C string is harder. In the case where the original and the replacement have the same number of chars, you can call strncpy() to copy over the characters.
// replacing a substring of equal length
char const *source = "foobar";

char *copy = strdup(source); // make a non-const copy of source

char *c2 = copy + 2;         // get pointer to char at index 2

strncpy(c2, "OBA", 3);       // copy 3 chars

NSLog(@"copy = %s", copy);
// prints "copy = foOBAr"

free(copy);                  // free copy when done
Replacing a substring with a different sized one is even more complex. There are three special cases that need to be handled: the substring to replace is at the start of the original, in the middle, or at the end. When the replacement substring is smaller than the original, there are some short cuts you can take to make the code a little simpler, but we'll only show the general case.

We'll look at the second case, replacing a substring in the middle of the original. With a little extra logic, this code can be adapted to handle all three of our cases.
char const *source = "The rain in Spain";
char const *original = "rain";     // substring to find
char const *replacement = "plane"; // substring to replace

// calculate the required buffer size
// including space for the null terminator
size_t size = strlen(source) - strlen(original) 
            + strlen(replacement) + sizeof(char);

// allocate buffer
char *buffer = calloc(size, sizeof(char));
if ( ! buffer) {
  // handle allocation failure
}

// find original substring in source and
// calculate the length of the unchanged prefix
char *originalInSource = strstr(source, original);
size_t prefixLength = originalInSource - source;

// copy prefix "The " into buffer
strncpy(buffer, source, prefixLength);

// calculate where the replacement substring goes in the buffer
char *replacementInBuffer = buffer + prefixLength;

// copy replacement "plane" into buffer
strcpy(replacementInBuffer, replacement);

// find position of unchanged suffix in source and
// calculate where it goes in the buffer
char const *suffixInSource = originalInSource + strlen(original);
char *suffixInBuffer = replacementInBuffer + strlen(replacement);

// copy suffix " in Spain" into buffer
strcpy(suffixInBuffer, suffixInSource);

NSLog(@"buffer = %s", buffer);
// prints "buffer = The plane in Spain"

free(buffer); // free buffer when done
I won't even waste your time explaining this in detail. No one programming in a modern computer language should have to write this code! It's extremely error prone and is one of the main causes of security vulnerabilities. If you find yourself doing this, stop immediately and seek out one of the many managed string libraries for C that are available. If you're writing code for iOS, you should be using NSString to do this.

Replacing using NSString
The NSString class has a number of useful methods for replacing characters and substrings in an NSString. Because NSString is immutable, these methods all return a new NSString instance containing the replacements, leaving the source NSString unchanged.

When you know the exact area of the string you want to replace, you can use the -stringByReplacingCharactersInRange:withString: method with an NSRange structure, which has fields for location (the zero-based index to start at) and length (the number of characters in the source string to replace). Because NSString does all the memory management for you and returns a new autoreleased NSString, it's child's play compared to doing this with C strings.
// replace a range in an NSString
NSString *source = @"The rain in Spain";
NSRange range;

range.location = 4; // starting index in source
range.length = 3;   // number of characters to replace in source

NSString *copy = [source stringByReplacingCharactersInRange:range 
                                                 withString:@"trai"];

NSLog(@"copy = %@", copy);
// prints "copy = The train in Spain"

// no need to release anything
// copy is autoreleased
This is a definite improvement over working with C strings. You might actually do this in real code without tearing your hair out or causing a buffer overrun bug. We can make this code even more compact by using the NSMakeRange() function to create the NSRange structure.
// replace a range in an NSString
NSString *source = @"The rain in Spain";

// create range in line
NSString *copy = [source stringByReplacingCharactersInRange:NSMakeRange(4, 3)
                                                 withString:@"trai"];

NSLog(@"copy = %@", copy);
// prints "copy = The train in Spain"

// no need to release anything
// copy is autoreleased
If you don't know ahead of time what part of the string you want to replace, you can do a find and replace in one method. The -stringByReplacingOccurrencesOfString:withString: method will find all occurrences of one NSString in another and replace them, returning a new autoreleased NSString.
// find and replace one substring with another
NSString *source = @"The rain in Spain";

NSString *copy = [source stringByReplacingOccurrencesOfString:@"ain"
                                                   withString:@"oof"];

NSLog(@"copy = %@", copy);
// prints "copy = The roof in Spoof"
There is another variation of this method that gives you more control over how substrings are found and replaced. The -stringByReplacingOccurrencesOfString:withString:options:range: method allows you to specify a mask containing one or more options and an NSRange structure allowing you to restrict the operation to a section of the string. The most common option is NSCaseInsensitiveSearch, which matches the substring without regard to case.
// case insensitive replace
NSString *source = @"<BR>The rain<BR>in Spain";

NSString *copy = [source stringByReplacingOccurrencesOfString:@"<br>"
                                                   withString:@"<p>"
                                                      options:NSCaseInsensitiveSearch
                                                        range:NSMakeRange(0, [source length])];

NSLog(@"copy = %@", copy);
// prints "copy = "<p>The rain<p>in Spain"
Another handy search option is NSAnchoredSearch, which searches only at the start of the source string. Notice that you use the bitwise or (|) operator to combine multiple options together.
// anchored, case insensitive replace
NSString *source = @"<BR>The rain<BR>in Spain";

NSString *copy = [source stringByReplacingOccurrencesOfString:@"<br>"
                                                   withString:@"<p>"
                                                      options:NSAnchoredSearch | NSCaseInsensitiveSearch
                                                        range:NSMakeRange(0, [source length])];

NSLog(@"copy = %@", copy);
// prints "copy = "<p>The rain<BR>in Spain"
You can combine the NSBackwardsSearch with NSAnchoredSearch to only replace the substring if it occurs at the end of the source instead of at the beginning.

Replacing in NSMutableString
If you're working with an NSMutableString, you can still call any of the -stringByReplacing... methods to produce a new NSString, but you have the option of making the replacements in the NSMutableString directly. The method -replaceCharactersInRange:withString: is very similar to the -stringByReplacingCharactersInRange:withString method:
// replace a range in an NSMutableString
NSMutableString *source = [NSMutableString stringWithString:@"The rain in Spain"];

[source replaceCharactersInRange:NSMakeRange(4, 3)
                      withString:@"trai"];

NSLog(@"source = %@", source);
// prints "source = The train in Spain"
The method -replaceOccurrencesOfString:withString:options:range: works similarly.

In most cases, there's not much of an advantage to replacing in place in an NSMutableString versus creating a new NSString containing the replacement. Use whichever operation is most convenient. If you need to make many replacements on a very long string, there may be an advantage to replacing in place rather than creating many large temporary NSString instances that live in the autorelease pool.

So far, the searching and replacing methods we've seen have done only simple string matching. Next week, we'll look at more powerful string matching using regular expressions.

Monday, October 4, 2010

iPhone Code to Learn From

Programmers learn in different ways. Some need to read a step-by-step "how to" guide, others get by fine just using the official documentation and header files. Some are more comfortable attending a workshop or watching a video, others prefer to just dive in and write code.

Reading other programmers' code is another great way to learn about developing in a particular language or framework. A lot of programmers find reading strange code to be difficult, but it's a skill that I think is really important and I encourage every programmer to become comfortable with.

The folks at Web Resources Depot recently published 20+ Open Source iPhone Applications To Learn From which links to a bunch of open source iPhone apps that run the gamut from the official WordPress app to small utilities and games. If you learn best by reading code, or you want to improve your code reading skills, check it out!

Friday, October 1, 2010

iPad Friday: October 1, 2010

Hello and happy Friday.  Today's collection of iPad wallpapers continue our look at photos from around the neighborhood.  Cheers!

(click an image for the full-size wallpaper)






iPhone Friday: October 1, 2010

Hello and happy Friday.  Today's collection of iPhone wallpapers continue our look at photos from around the neighborhood.  Cheers!

(click an image for the full-size wallpaper)






Thursday, September 30, 2010

Creating a GUID or UUID in Objective-C

I recently needed to generate unique IDs to be sent from an iPhone app to a web service. Rather than come up with my own scheme, I looked around for a way to generate a UUID (or GUID if you're from the Windows world) on iOS.

Turns out that Core Foundation includes a set of functions for working with UUIDs naturally called CFUUID. I needed a string representation of the UUID so I quickly rolled this method to generate it:
// return a new autoreleased UUID string
- (NSString *)generateUuidString
{
  // create a new UUID which you own
  CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);

  // create a new CFStringRef (toll-free bridged to NSString)
  // that you own
  NSString *uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
  
  // transfer ownership of the string
  // to the autorelease pool
  [uuidString autorelease];

  // release the UUID
  CFRelease(uuid);

  return uuidString;
}
Not too hard to do if you're familiar with Core Foundation conventions.

Tuesday, September 28, 2010

Objective-C Tuesdays: searching in strings

Last week we looked at creating substrings of C strings and NSStrings. Today we look at another common string operation: searching within a string.

Find a character in a C string
As with all operations on C strings, searching requires you to deal with pointers. To find the first occurrence of a character in a C string, use the strchr() function. If the character is found, a pointer to that character is returned. If the character isn't present in the string, NULL is returned.
// find a character in a C string
char const *s = "foobar";

char const *character = strchr(s, 'b');
if (character) {
  NSLog(@"Found b");
} else {
  NSLog(@"Didn't find b");
}
// prints "Found b"
As we saw last week when we looked at substrings, the pointer returned by strchr() is effectively a substring of the source string starting at the first occurrence of the character you were searching for:
char const *s = "foobar";

char const *substring = strchr(s, 'b');
if (substring) {
  NSLog(@"The substring is %s", substring);
}
// prints "The substring is bar"
Once you find the character you're looking for, it's common to want to create a substring containing everything up to that position in the string:
char const *filename = "myfile.txt";

char const *dot = strchr(filename, '.');
if (dot) {
  size_t length = dot - filename;
  char *baseFilename = calloc(length + 1, sizeof(char));
  if (baseFilename) {
    strncpy(baseFilename, filename, length);
    NSLog(@"The base filename is %s");
  }
}
// prints "The base filename is myfile"
You use the difference between the two string pointers to calculate the number of chars up to (but not including) the character you searched for. After allocating a buffer to hold the new substring (and the null terminator), you use the strncpy() function to copy the first part of the source string. Because we called calloc(), the last char in our buffer is already set to zero; if you use malloc() or a fixed buffer instead, you need to remember to set the null terminator since strncpy() isn't guaranteed to do it for you.

Very often, you want to find the last occurrence of a character; you can use the strrchr() function to search in reverse:
// find a character in reverse
char const *filename = "myfile.txt";

char const *extension = strrchr(filename, '.');
if (extension) {
  NSLog(@"The extension is %s", extension);
}
// prints "The extension is .txt"

Find one C string in another
To find the first occurrence of one C string in another, use the strstr() function. Like strchr(), it returns a pointer to the first occurrence of the string, or NULL if it wasn't found.
// find one C string in another
char const *s1 = "The quick brown fox";

char const *s2 = strchr(s1, "ick");
if (s2) {
  NSLog(@"Found ick");
} else {
  NSLog(@"Didn't find ick");
}
// prints "Found ick"
Unfortunately the C standard library doesn't have a strrstr() function to search for the last occurrence of one string in another. You'll need to roll your own by calling strstr() in a loop until you reach the end of the string. (The implementation of this is left as an exercise for the reader, or better yet convert your C string to an NSString and keep reading :-)

C string encoding issues
The standard library functions for searching C strings work great with ASCII and similar single byte encodings. If you need to search inside UTF-8 encoded C strings, you'll quickly realize that strchr() and strrchr() are only useful for finding the basic ASCII characters (which are also valid UTF-8 characters). If you need to find non-ASCII characters like 'é', you'll need to use strstr() to search for the byte sequence that UTF-8 uses to represent it ("\xc3\xa9" for 'é'). Even then, Unicode characters like 'é' can be represented two ways: as the single Unicode character 'é' or as the base character 'e' followed by the combining character '´'. In general, it's better to use a C library designed to deal with the encoding such as the International Components for Unicode for handling UTF-8 encoded strings. Or if you're developing for iOS or Mac OS X, use NSString instead.

Find one NSString in another
The NSString class doesn't have separate methods to search for a single character or a string; you use -rangeOfString: to do either:
// find a character in an NSString
NSString *s = @"foobar";

NSRange range = [s rangeOfString:@"b"];
if (range.location != NSNotFound) {
  NSLog(@"Found b at %u", range.location);
}
// prints "Found b at 3"
Searching for the last occurrence of a string is done using the related method -rangeOfString:options: with the NSBackwardsSearch option.
// find last occurrence in an NSString
NSString *s = @"The rain in Spain falls mainly on the plain";

NSRange range = [s rangeOfString:@"ain" options:NSBackwardsSearch];
if (range.location != NSNotFound) {
  NSLog(@"Found ain at %u", range.location);
}
// prints "Found ain at 40"
The options are a combination of the following bit flags: NSCaseInsensitiveSearch, NSLiteralSearch, NSBackwardsSearch and NSAnchoredSearch. You use the bitwise or (|) operator to combine them together, or pass in zero for no options.

Use the NSCaseInsensitiveSearch option to find the first match, ignoring the case of both strings. The NSLiteralSearch option is used when you want to match a specific Unicode string form, such as the single character 'é' (Unicode character U+00E9) and not match equivalent character sequences like 'e' + '´' (Unicode characters U+0065 and U+0301). Most applications won't care about this option, but it's really handy when you need it.

NSAnchoredSearch checks for a match only at the start of the string (or the end if combined with NSBackwardsSearch). This option is occasionally handy, but the methods -hasPrefix: and -hasSuffix: are easier to read equivalents.
// anchored search
NSString *s = @"The rain in Spain falls mainly on the plain";

NSRange range = [s rangeOfString:@"ain" 
                         options:NSAnchoredSearch];
if (range.location == NSNotFound) {
  NSLog(@"Doesn't start with ain");
}
// prints "Doesn't start with ain"

// same thing using -hasPrefix:
if ( ! [s hasPrefix:@"ain"]) {
  NSLog(@"Doesn't have prefix ain");
}
// prints "Doesn't have prefix ain"


// now from the end
range = [s rangeOfString:@"ain"
                 options:NSAnchoredSearch | NSBackwardsSearch];
if (range.location != NSNotFound) {
  NSLog(@"Ends with ain");
}
// prints "Ends with ain"

// same thing using -hasSuffix:
if ([s hasSuffix:@"ain"]) {
  NSLog(@"Has suffix ain");
}
// prints "Has suffix ain"
There are two other variations of -rangeOfString:. The first, -rangeOfString:options:range:, allows you to search within a section of a larger string without having to create a substring.

The second, -rangeOfString:options:range:locale:, allows you to specify a locale as well as a range. In most cases you want to use the current locale, which is taken from the language setting on the user's device. The other variations of -rangeOfString: use the current locale, and you can pass nil for the locale to use the current one. Sometimes you know that the string contains text in a particular language, in an app that teaches German for instance. In this case you should specify a locale when searching the string; the locale can affect how text is matched, especially when using the NSCaseInsensitiveSearch option.

Next week, we'll look at replacing characters in C strings and NSStrings.

Friday, September 24, 2010

iPad Friday: September 24, 2010

Hello and happy Friday.  Today's collection of iPad wallpapers continue our look at photos from around the neighborhood.  Cheers!

(click an image for the full-size wallpaper)






iPhone Friday: September 24, 2010

Hello and happy Friday.  Today's collection of iPhone wallpapers continue our look at photos from around the neighborhood.  Cheers!

(click an image for the full-size wallpaper)






Tuesday, September 21, 2010

Objective-C Tuesdays: slicing and dicing strings

Last time, we looked at C string and NSString comparison and equality. Today we'll examine functions and methods for creating substrings of C strings and NSStrings.

Substrings of C strings
Creating a C string requires you to explicitly manage the memory the string lives in. Depending on how long you need to keep the C string around, you can use either a fixed buffer or a dynamically allocated one. As always with C strings, you need to be careful not to write past the end of the buffer.

Creating a substring that starts at the beginning of the source string is straight forward: use the strncpy() function. There's a big gotcha when using strncpy() to copy a substring: it doesn't automatically add a null terminator to the destination. Here's an example of copying the first three characters of a C string into a fixed buffer:
// copy substring from start of source
// using a fixed buffer
char const *source = "foobar";
char buffer[4];                // make sure buffer includes
                               // space for null terminator

strncpy(buffer, source, 3);    // copy first 3 chars from source
buffer[3] = '\0';              // remember to add null terminator
Using a dynamic buffer is similar, but requires explicit memory management.
// copy substring from start of source
// using a dynamic buffer
char const *source = "foobar";
char *buffer = malloc(4 * sizeof(char)); // make sure buffer includes
                                         // space for null terminator

if ( ! buffer) {
  // must handle allocation failure
}

strncpy(buffer, source, 3); // copy first 3 chars from source
buffer[3] = '\0';           // remember to add null terminator

// use buffer ...

// don't forget to free() buffer when done
free(buffer);
You can make this a little more compact by using calloc() instead of malloc(). The calloc() function allocates memory using malloc(), then clears all the bytes to zero. As long as you make sure to include an extra byte at the end, your new substring will be null terminated:
// copy substring from start of source
// using a dynamic buffer 
// allocated with calloc()
char const *source = "foobar";
char *buffer = calloc(4, sizeof(char)); // make sure buffer includes
                                        // space for null terminator

if ( ! buffer) {
  // handle allocation failure
}

strncpy(buffer, source, 3); // copy first 3 chars from source
                            // last char in buffer is already '/0'

// use buffer ...

// don't forget to free() buffer when done
free(buffer);
There's not a huge difference between malloc() and calloc(), so choose whichever one you're more used to using, or use calloc() if you don't have a strong preference. The cost of clearing a range of memory to zeros is so tiny as to not be worth considering in most circumstances, and knowing that your buffer is initialized to zeros can be handy.

There's no standard C function for getting a substring that starts somewhere in the middle of the source string, because one isn't needed -- you simply move the pointer from the start of the string. Here's an illustration:
// C strings are pointers
char const *string = "foobar";

NSLog(@"'%s'", string);
// prints out 'foobar'

char const *substring = string + 3;
NSLog(@"'%s'", substring);
// prints out 'bar'
You can add an integer value to the C string pointer to get a pointer to the middle of the source string -- just be careful not to go off the end of the string! If you only need the substring for a short period of time, or if you know that the source string will live longer than the substring and never change, it's safe to simply create a substring this way. However, you can introduce weird bugs if you get this wrong. When in doubt, copy the substring to a new buffer:
// create a substring from the middle of a string
char const *source = "foobar";
char const *substringSource = source + 3;
size_t charCount = strlen(substringSource) + 1;
char *buffer = calloc(charCount, sizeof(char));

if ( ! buffer) {
  // handle allocation failure
}

strcpy(buffer, substringSource);

// use buffer ...

free(buffer);
Here we calculate the starting point by simply adding 3 to the string pointer source. Then we figure out the number of chars we need to allocate using the strlen() function, remembering to add 1 for the null terminator character. After allocating memory, the strcpy() function copies all the characters from substringSource into buffer. Unlike strncpy(), strcpy() will copy the null terminator, so this code will be the same whether we use calloc() or malloc() to allocate the buffer.

If you need to grab a substring that falls between the beginning and end of a longer string, you combine these two techniques: use pointer arithmetic to get a pointer to the start of the substring, then use strncpy() to copy just the characters you need.

Warning: beware encoding issues!
Slicing and dicing C strings is easy when you're using a single byte encoding like ASCII. If you're using a multibyte encoding like UTF-8, you need to be aware that one logical character may require two or more bytes. If you want to omit the first three logical characters in a string, you need to examine each byte from the start of a string to determine if it's part of a multibyte sequence, and adjust your string pointer accordingly. If you need to work with multibyte encodings, I recommend finding an appropriate library for the encoding, such as the International Components for Unicode for working with Unicode encodings. Or better yet, transform your C strings into NSStrings.

Substrings of NSStrings
There are three ways to get a substring of an NSString. First we'll look at taking a substring from the start of an NSString:
// create a substring from the start of source
NSString *source = @"foobar";

NSString *substring = [source substringToIndex:3];
// substring is "foo"
The substring returned by -substringToIndex: is autoreleased. You should -retain or -copy it if you need to hold on to it.

Similarly, to get a substring that starts in the middle of an NSString and goes to the end:
// create a substring to the end of source
NSString *source = @"foobar";

NSString *substring = [source substringFromIndex:3];
// substring is "bar"
Finally, the general purpose way to create a substring of an NSString is the -substringWithRange: method, which uses an NSRange structure, which is defined something like this:
// NSRange structure
struct NSRange {
  NSUInteger location;
  NSUInteger length;
}
When used with -substringWithRange: method, the NSRange's location field is the zero-based index of the first character to be included in the substring, and the length field is the number of characters to include in the substring. Here are some examples:
// -substringWithRange: examples
NSString *source = @"foobar";
NSRange range;

range.location = 0;
range.length = 3;
NSString *frontHalf = [source substringWithRange:range];
// frontHalf is "foo"

range.location = 3;
range.length = 3;
NSString *backHalf = [source substringWithRange:range];
// backHalf is "bar"

range.location = 2;
range.length = 2;
NSString *middle = [source substringWithRange:range];
// middle = "ob"
One word of caution: if the range you give falls outside the receiver (the source string), this method will raise an NSRangeException.

Setting the fields of NSRange is fairly verbose; it's generally more convenient to use the NSMakeRange() function to create the NSRange structure instead.
// NSMakeRange() example
NSString *source = @"foobar";

NSString *frontHalf = [source substringWithRange:NSMakeRange(0, 3)];
// frontHalf is "foo"

NSString encoding mostly not a worry
Internally, NSString uses UTF-16 encoding. Although UTF-16 is a variable length encoding like UTF-8, characters from the basic multilingual plane are all two bytes (one word) in length. If you're certain that your NSString contains only basic multilingual plane characters, then methods like -length and -substringWithRange: will work exactly as you expect them. However, if your NSString includes characters outside the basic multilingual plane, it will contain surrogate pairs, which are multi-word sequences that represent a single character. You'll find that -length tells you the number of words rather than logical characters, and if you're not careful, methods like -substringWithRange: can split a surrogate pair in half, leaving you with an invalidly encoded string.

Unless your application needs to work with characters outside the basic multilingual plane, the easiest solution is to filter out such characters when you accept data from a source outside your app. Since the basic multilingual plane contains all the characters in common use in most modern languages, this is sufficient for many applications. The standard iOS input keyboards limit the user to characters in the basic multilingual plane, but if your app reads data from the network, such as an RSS feed you don't control, you need to watch out for this.

Next time, we'll look at searching in C strings and NSStrings.

Tuesday, September 14, 2010

Objective-C Tuesdays: string comparison and equality

Welcome back after an end-of-Summer hiatus. Last time we looked at concatenating strings in Objective-C. Today we look at another common string operation: comparison.

Identity
Comparing two variables or objects can sometimes be a tricky proposition. There are several different senses of equality. The most fundamental type of equality is identity: do two variables represent the same thing in memory. Identity only makes sense for reference types, like C strings, NSStrings and other pointer types. Value types like ints always designate separate things in memory. In C and Objective-C, identity equality is determined by comparing pointer values using the == operator.
// comparing two strings for identity
char const s1 = "foo";
char const s2 = s1;
if (s1 == s2) {
  NSLog(@"s1 is identical to s2");
}

NSString *s3 = @"foo";
NSString *s4 = @"bar";
if (s3 != s4) {
  NSLog(@"s3 is not identical to s4");
}

Equivalence
A more useful type of equality is equivalence of value: do two variables represent equivalent data. Equivalence is useful when comparing value types as well as reference types, and is usually what programmers think of when comparing two strings.

For C strings, the primary equivalence test is done with the strcmp() function. The strcmp() function compares the data of two C strings char by char; if two C strings represent the same sequence of char values in memory, they are equivalent and strcmp() returns zero.
// checking two C strings for equal value
char const *s1 = "foo";
char const *s2 = "bar";

if (strcmp(s1, s2) == 0) {
  NSLog(@"s1 is equivalent to s2");
} else {
  NSLog(@"s1 is not equivalent to s2");
}
In addition to checking for equivalence, strcmp() also categorizes the sort order of the two C strings. If the first argument comes before the second, a negative value is returned; if the first argument comes after the second, a positive value is returned. The strcmp() function uses a lexicographic comparison, which means that the comparison is strictly on the basis of the integer values of the chars in the C strings. For ASCII strings, the string "2" (ASCII code 50) comes before "A" (ASCII code 64), which precedes "a" (ASCII code 97). Many sorting algorithms, including the qsort() function in the C standard library, require a function like strcmp().
// using strcmp() result

int compareResult = strcmp(s1, s2);
if (compareResult < 0) {
  NSLog(@"s1 comes before s2");
} else if (compareResult > 0) {
  NSLog(@"s1 comes after s2");
}

Sometimes you only want to see if two strings have a common prefix, or you're working with character buffers that aren't null terminated. The strncmp() function will compare a limited number of characters, stopping early if it encounters a null terminator in either string. Thus these two strings are equivalent when the first three characters are compared:
if (strncmp("foo", "fooey", 3) == 0) {
  NSLog(@"both start with foo");
}
// prints "both start with foo"

When sorting with strncmp(), short strings come first:
if (strncmp("foo", "fooey", 5) < 0) {
  NSLog(@"foo comes before fooey");
}
// prints "foo comes before fooey"

Case Insensitive
In languages that have upper and lower case letters, you often need to do a case insensitive comparisons. The C standard library doesn't define a case insensitive string comparison function, but one is part of the POSIX standard, and most compiler vendors and operating systems include one. The POSIX version is called strcasecmp(). Most modern Unix and Linux systems (including iOS and Mac OS X) have strcasecmp() available in the standard library. Older Unix systems and other operating systems may call this function stricmp() or strcmpi(). There is usually also a length limited version called strncasecmp() or strnicmp().

The case insensitive comparison functions usually compare only ASCII characters, which limits their usefulness.
// case insensitive comparison
char const *s = "<HTML><HEAD>...";

if (strncasecmp(s, "<html>", 6) == 0) {
  NSLog(@"looks like HTML");
}

Encoding Issues
The strcmp() function was created in the era when most computers used ASCII or other simple single byte encodings. In ASCII, there is only one byte sequence that represents any particular character sequence. This isn't true of many modern encodings, including Unicode. The Unicode character set contains both accented characters such as "é" as well as a combining accent character "´", so there are two ways to represent "é" in UTF-8 encoding:

Address646566
Character'é'
Value195169
Character'e''´'
Value101204129
Obviously a lexicographic comparison function like strcmp() will not see these two strings as equivalent. Accounting for this requires performing normalization on the Unicode characters in the string before doing the comparison. Unicode has several different types of normalization, which we won't dive into here. If you need to do a lot of low level processing of UTF-8 or other Unicode encoded text, you should look at the International Components for Unicode, a library of C functions for Unicode processing that is included as part of iOS. Better yet, in most cases you should use NSStrings when working with text.

NSString equality
The NSString class defines the -isEqualToString: instance method for testing if an NSString is equivalent to another NSString:
// compare two NSStrings
NSString *s1 = @"foo";
NSString *s2 = @"bar";

if ( [s1 isEqualToString:s2] ) {
  NSLog(@"The strings are equivalent.");
}
You can also use the -isEqual: instance method defined by NSObject to compare two NSStrings, or to compare an NSString with any other object:
// compare two NSStrings using -isEqual:
NSString *s1 = @"foo";
NSString *s2 = @"bar";

if ( [s1 isEqual:s2] ) {
  NSLog(@"The strings are equivalent.");
}
The difference between the two methods is in their declarations. The -isEqualToString: method is only for comparing one NSString to another; it's declaration looks like:
// declaration of -isEqualToString:
- (BOOL)isEqualToString:(NSString *)aString
The -isEqual: method is for comparing any kind of NSObject to another object; it's declaration looks like:
// declaration of -isEqual:
- (BOOL)isEqual:(id)anObject
It's possible to use -isEqual: to compare an NSString with an object of a different type, such as an NSNumber:
NSString *fiveString = @"5";
NSNumber *fiveNumber = [NSNumber numberWithInt:5];

if ( [fiveString isEqual:fiveNumber] ) {
  NSLog(@"fiveString equals fiveNumber");
} else {
  NSLog(@"Strings aren't equivalent to numbers, silly!");
}
You might hope that the NSString "5" is equivalent to the NSNumber "5" but unfortunately they are not; the code above will print out "Strings aren't equivalent to numbers, silly!". In general, objects of different classes aren't considered to be equivalent with one common exception: immutable classes like NSString can be equivalent to their mutable subclasses (NSMutableString in this case) and vice versa.
NSString *fiveString = @"5";
NSMutableString *fiveMutableString = [NSMutableString stringWithString:@"5"];

if ( [fiveString isEqual:fiveMutableString] ) {
  NSLog(@"immutable and mutable strings can be equivalent");
}
And since NSMutableString is a subclass of NSString, you can also use -isEqualToString: to compare them:
if ( [fiveString isEqualToString:fiveMutableString] ) {
  NSLog(@"immutable and mutable strings can be equivalent");
}

-compare:
In addition to testing for equivalence using -isEqual: or -isEqualToString:, you can also discover the relative order of two NSString objects using the -compare: family of methods. The -compare: method is very similar to the strcmp() method in C. The -compare: method returns a NSComparisonResult value, which is simply an integer value. Similar to strcmp(), -compare: will return zero if the two NSStrings are equivalent, though you can also use the constant NSOrderedSame instead of zero:
// compare two NSStrings
NSString *s1 = @"foo";
NSString *s2 = @"bar";

if ( [s1 compare:s2] == NSOrderedSame] ) {
  NSLog(@"s1 is equivalent to s2");
} else {
  NSLog(@"s1 is not equivalent to s2");
}
Like strcmp(), if the receiver of the -compare: message (the first NSString) comes before the first argument (the second NSString), negative one is returned; if the receiver comes after the first argument, positive one is returned. The constants NSOrderedAscending and NSOrderedDescending can be used instead of -1 and 1 respectively.
// using NSComparisonResult

NSComparisonResult comparisonResult = [s1 compare:s2];
if (comparisonResult == NSOrderedAscending) {
  NSLog(@"s1 comes before s2");
} else if (comparisonResult == NSOrderedAscending) {
  NSLog(@"s1 comes after s2");
}

Case Insensitive -compare:
To test the equivalence of two NSString objects in a case insensitive manner, use -compare:options: with the NSCaseInsensitiveSearch flag.
// case insensitive compare
NSString *s1 = @"foo";
NSString *s2 = @"FOO";

if ( [s1 compare:s2 options:NSCaseInsensitiveSearch] == NSOrderedSame) {
  NSLog(@"s1 is equivalent to s2");
}
Since case insensitive comparison is a common operation, NSString has a convenience method, -caseInsensitiveCompare: which does the same thing.
// case insensitive compare
NSString *s1 = @"foo";
NSString *s2 = @"FOO";

if ( [s1 caseInsensitiveCompare:s2] == NSOrderedSame) {
  NSLog(@"s1 is equivalent to s2");
}

Unicode and -compare:
By default, NSString is pretty smart about Unicode and automatically understands things like Unicode combining characters. For instance, you can represent é two ways, but NSString knows that they represent equivalent strings:
// comparing equivalent Unicode strings
NSString *eAcute = @"\u00e9";      // single character 'é'
NSString *ePlusAcute = @"e\u0301"; // 'e' + combining '´'

if ( [eAcute isEqualToString:ePlusAcute] ) {
  NSLog(@"'é' is equivalent to 'e' + '´'");
}
This can be surprising if you've only worked with ASCII or other single byte encodings. With NSString, you can't assume that equivalent strings have the same length and character sequence. Usually you don't care about the Unicode representation, but occasionally it's important. You can use the NSLiteralSearch flag along with -compare:options: to do a lexicographic comparison that compares strings character value by character value.

// lexicographic comparison of Unicode strings

if ( [eAcute compare:ePlusAcute options:NSLiteralSearch] != NSOrderedSame) {
  NSLog(@"'é' is not lexicographically equivalent to 'e' + '´'");
}

combining options
The options constants used in the -compare:options: method are bit flags. You combine them using the bitwise or operator (|).
// using multiple options
NSString *eAcute = @"\u00e9";        // 'é'
NSString *capitalEAcute = @"\u00c9"; // 'É'

if ( [eAcute compare:capitalEAcute 
             options:NSCaseInsensitiveSearch | NSLiteralSearch] 
         != NSOrderedSame) 
{
  NSLog(@"'é' is equivalent to 'É'");
}

comparing substrings
If you only want to compare parts of two NSString objects, you can use -compare:options:range: method and specify an NSRange structure. The NSRange structure is composed of two parts: a starting location field named loc and a length field named len. Usually it's convenient to use the NSMakeRange() function to generate the NSRange.
// compare substrings
NSString *s1 = @"foo";
NSString *s2 = @"fooey";

if ( [s1 compare:s2 
         options:0 
           range:MakeRange(0, 3)] == NSOrderedSame)
{
  NSLog(@"both strings start with 'foo'");
}
You pass in zero for the options to use the default comparison. -compare:options:range: is similar to strncmp() with one important difference: the NSRange you give must fall completely inside the receiver (the first string) or an NSRangeException will be thrown.

comparing using a specific locale
By default, the -compare: methods use the current locale to determine the ordering of two strings. The current locale is controlled by the user when they set their language and region for their iOS device. Most of the time you should respect the user's settings, but sometimes it's appropriate to compare strings using a fixed locale. Perhaps your app teaches French vocabulary and you want your French word list to sort in standard French order whether the user's phone is set to English, German or Japanese. In French, accented letters at the end of a word sort before accented letters earlier in a word, thus "coté" should come before "côte". If you use the default locale, the result of comparing "coté" and "côte" varies but will probably not give you the correct ordering.
// compare using default locale
NSString *coteAcute = @"cot\u00e9";      // "coté"
NSString *coteCircumflex = @"c\u00f4te"; // "côte"

if ( [coteAcute compare:coteCircumflex] == NSOrderedAscending) {
  NSLog(@"Not using a French locale");
}
To remedy this, you can set the locale explicitly when you do your comparison:
// compare using specific locale
NSLocale *frenchLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"] autorelease];
NSComparisonResult comparisonResult = [coteAcute compare:coteCircumflex 
                                                 options:0 
                                                   range:NSMakeRange(0, 4)
                                                  locale:frenchLocale];
if (comparisonResult == NSOrderedDescending) {
  NSLog(@"Using a French locale");
}

That sums up the options for comparing C strings and NSStrings. Next time, we'll look at slicing and dicing strings by creating substrings.

Friday, September 10, 2010

iPad Friday: September 10, 2010

Hello and happy Friday.  Today's collection of iPad wallpapers continue our look at photos from around the neighborhood.  Cheers!

(click an image for the full-size wallpaper)