-
-
Save siuying/680ecf56b99c3da906ee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NSString+UnicodeLength.h" | |
@implementation NSString (UnicodeLength) | |
/** | |
* @param range a unicode codepoint range, as described in twitter | |
* @return rante a NSRange for the string | |
* @see https://dev.twitter.com/overview/api/counting-characters | |
*/ | |
- (NSRange)composedRangeWithRange:(NSRange)range { | |
__block NSRange adjustedRange = range; | |
// adjust location | |
for (NSUInteger i = 0; i < range.location + 1; i++) { | |
unichar theChar = [self characterAtIndex:i]; | |
if (CFStringIsSurrogateHighCharacter(theChar)) { | |
adjustedRange.location++; | |
} | |
} | |
// adjust length | |
__block NSInteger count = 0; | |
for (NSUInteger i = adjustedRange.location; i < self.length; i++) { | |
unichar theChar = [self characterAtIndex:i]; | |
if (CFStringIsSurrogateHighCharacter(theChar)) { | |
adjustedRange.length++; | |
} else { | |
// Add one to the count | |
count++; | |
// If we have iterated as many times as the original length, stop. | |
if (range.length == count) { | |
break; | |
} | |
} | |
} | |
return adjustedRange; | |
} | |
- (NSString *)composedSubstringWithRange:(NSRange)range { | |
// Return a substring using a composed range so surrogate unicode pairs (composed characters) count as 1 in the | |
// range instead of however many unichars they actually are. | |
return [self substringWithRange:[self composedRangeWithRange:range]]; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
#import <XCTest/XCTest.h> | |
#import <Expecta/Expecta.h> | |
#import "NSString+UnicodeLength.h" | |
@interface NSStringUnicodeLengthTests : XCTestCase | |
@end | |
@implementation NSStringUnicodeLengthTests | |
- (void)testRangeForComposedCharacterSequencesRangeThai { | |
// emoji + hashtag | |
// status_id = 580031725297782784 | |
NSString* input = @"ผมนี่น้ำตาไหลจริงใจกะตอน25มาก 😭 ทำไมพี่เอมไม่ฟังน้ำทำไมต้องทำร้ายจิตใจทำร้ายร่างกายขนาดนั้นด้วย 😭 พี่เอมใจร้าย เกลียดไอ้โอม 😫 #รักของเรา"; | |
NSRange range = NSMakeRange(126, 10); | |
NSString* substring = [input ig_composedSubstringWithRange:range]; | |
BOOL isEqual = [substring isEqualToString:@"#รักของเรา"]; | |
expect(isEqual).to.beTruthy(); | |
input = @"ผมนี่น้ำตาไหลจริงใจกะตอน25มาก 😭 ทำไมพี่เอมไม่ฟังน้ำทำไมต้องทำร้ายจิตใจทำร้ายร่างกายขนาดนั้นด้วย 😭 พี่เอมใจร้าย เกลียดไอ้โอม 😫 #😭รักของเรา"; | |
range = NSMakeRange(126, 11); | |
substring = [input ig_composedSubstringWithRange:range]; | |
isEqual = [substring isEqualToString:@"#😭รักของเรา"]; | |
expect(isEqual).to.beTruthy(); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment