Search code examples
swiftrangensrange

Convert a given UTF8 NSRange in a string to a UTF16 NSRange


Converting any given UTF8 NSRange in a string to a UTF16 NSRange

Examples:

let str = #"let 🎁🇵🇷 = "hello world""#

//The UTF8 NSRange of 🎁🇵🇷 is: {4, 12}
//The UTF16 NSRange of 🎁🇵🇷 is: {4, 6}

//The UTF8 NSRange of let 🎁🇵🇷 is: {0, 16}
//The UTF16 NSRange of let 🎁🇵🇷 is: {0, 10}

Testing count:

print("🎁🇵🇷".utf8.count) //12
print("🎁🇵🇷".utf16.count) //6

print("let 🎁🇵🇷".utf8.count) //16
print("let 🎁🇵🇷".utf16.count) //10

I have only the UTF8 ranges, so what I need is to convert any of them to UTF16 range.

Thank you in advance.


Solution

  • Similar to how you would use index(_:offsetBy:) to get the nth index when finding the nth character of a string, you can use the same method here, except on the UTF8View of the string.

    Find both the start and end indices of the range as String.Index, then create a Range<String.Index>. Then you can create a NSRange from that.

    let str = #"let 🎁🇵🇷 = "hello world""#
    let utf8Range = NSRange(location: 4, length: 12)
    let startIndex = str.utf8.index(str.utf8.startIndex, offsetBy: utf8Range.lowerBound)
    let endIndex = str.utf8.index(startIndex, offsetBy: utf8Range.length)
    let stringRange = startIndex..<endIndex
    let utf16Range = NSRange(stringRange, in: str)
    print(utf16Range)