Search code examples
objective-cunicodensstringmultilingualstring-length

How to find string length for the multi language sentence in IOS


I am developing an application that needs to restrict user from entering string text unto 200 characters.

The user is allowed to enter string value in any language.

I am able to get the string length for the english characters but not for the other languages.

Can any one help me.

Expected Result:

  • 'Roger is a nice guy' -19
  • 'रॉजर एक छान माणूस आहे' - 16
  • '罗杰是一个好人' - 7

Solution

  • You are probably looking for extended grapheme clusters, which is a good definition of a user perceived character. Swift String's character view provides this conveniently.

    Cocoa's NSString provides enumerateSubstringsInRange:options:usingBlock: which can be used to count "composed character sequences", which is similar:

    @interface NSString (ComposedCharacterSequenceCount)
    @property (nonatomic, readonly, getter=nr_composedCharacterSequenceCount) NSInteger composedCharacterSequenceCount;
    @end
    
    @implementation NSString (ComposedCharacterSequenceCount)
    - (NSInteger)nr_composedCharacterSequenceCount
    {
        __block NSInteger count = 0;
        [self enumerateSubstringsInRange:(NSRange){0, self.length}
                                 options:NSStringEnumerationByComposedCharacterSequences | NSStringEnumerationSubstringNotRequired
                              usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
                                  count += 1;
                              }];
        return count;
    }
    @end
    

    This snippet adds a category to NSString that lets your easily calculate the number of characters:

    NSLog(@"count: %@", @(@"Roger is a nice guy".composedCharacterSequenceCount));
    NSLog(@"count: %@", @(@"रॉजर एक छान माणूस आहे".composedCharacterSequenceCount));
    NSLog(@"count: %@", @(@"罗杰是一个好人".composedCharacterSequenceCount));
    

    prints:

    count: 19
    count: 16
    count: 7