Strings and Runes in Objective-C

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // s is an NSString assigned a literal value
        // representing the word "hello" in the Thai language.
        // Objective-C string literals are UTF-8 encoded text.
        NSString *s = @"สวัสดี";
        
        // Since strings are objects in Objective-C, we use the length method
        // to get the number of characters in the string.
        NSLog(@"Len: %lu", (unsigned long)[s length]);
        
        // To iterate over the bytes of the string, we need to convert it to UTF8String
        const char *utf8String = [s UTF8String];
        for (int i = 0; i < strlen(utf8String); i++) {
            printf("%x ", (unsigned char)utf8String[i]);
        }
        printf("\n");
        
        // To count how many characters are in a string, we can use
        // the length property of NSString.
        NSLog(@"Character count: %lu", (unsigned long)[s length]);
        
        // To iterate over characters in a string, we can use NSString's
        // enumerateSubstringsInRange:options:usingBlock: method
        [s enumerateSubstringsInRange:NSMakeRange(0, [s length])
                              options:NSStringEnumerationByComposedCharacterSequences
                           usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
            NSLog(@"%@ starts at %lu", substring, (unsigned long)substringRange.location);
        }];
        
        NSLog(@"\nUsing rangeOfComposedCharacterSequenceAtIndex:");
        NSUInteger index = 0;
        while (index < [s length]) {
            NSRange range = [s rangeOfComposedCharacterSequenceAtIndex:index];
            NSString *character = [s substringWithRange:range];
            NSLog(@"%@ starts at %lu", character, (unsigned long)index);
            [self examineCharacter:character];
            index = NSMaxRange(range);
        }
    }
    return 0;
}

void examineCharacter(NSString *character) {
    // We can compare an NSString value to a string literal directly.
    if ([character isEqualToString:@"t"]) {
        NSLog(@"found tee");
    } else if ([character isEqualToString:@"ส"]) {
        NSLog(@"found so sua");
    }
}

This Objective-C code demonstrates working with strings and characters, which is analogous to the concept of strings and runes in the original example.

Objective-C uses NSString for string manipulation, which is quite different from the raw byte slices used in the original example. Here are some key points:

  1. String length in Objective-C gives the number of characters, not bytes.
  2. To work with raw bytes, we need to convert the string to UTF-8 encoding.
  3. Objective-C doesn’t have a direct equivalent to runes. Instead, we work with composed character sequences.
  4. The enumerateSubstringsInRange:options:usingBlock: method is used to iterate over characters in a string.
  5. rangeOfComposedCharacterSequenceAtIndex: is used to get the range of each character, which can then be extracted using substringWithRange:.

To run this program, save it as a .m file (e.g., StringsAndCharacters.m) and compile it with:

$ clang -framework Foundation StringsAndCharacters.m -o StringsAndCharacters
$ ./StringsAndCharacters

This will output information about the Thai string, including its length, byte representation, and individual characters.