1

I don't understand what's going on here:

let strA = "0123456789"
let fromA = String.Index(encodedOffset: 2)
let toA = String.Index(encodedOffset: 8)
print("\(String(strA[fromA..<toA]))") // Prints "234567".

let strB = "01235689"
let fromB = String.Index(encodedOffset: 2)
let toB = String.Index(encodedOffset: 8)
print("\(String(strB[fromB..<toB]))") // Prints "23".

I would expect the bottom line to print "2356" but it prints "23". This seems to be an issue to do with unicode code points and partially chopping off part of the last unicode emoji character.

How can I get my expected "2356" string using the offsets of the visible characters?

My issue stems from Twitter's API and its extended tweets JSON objects that require you to chop the tweet text down to size using display_text_range values. Right now my code crashes whenever there is an emoji in the tweet as my substring code, as above, corrupts the string.

Dan
  • 5,013
  • 5
  • 33
  • 59
  • Why so complicated? What about `let truncatedString = String(str.prefix(maximalLength))` ? – Martin R Nov 15 '18 at 10:10
  • @MartinR he will not able to get substring with prefix method. – Jaydeep Vyas Nov 15 '18 at 10:24
  • @Dan: Have a look at [How does String substring work in Swift](https://stackoverflow.com/questions/39677330/how-does-string-substring-work-in-swift), it explains the issue and shows various solutions to your problem. – Martin R Nov 15 '18 at 18:34
  • @MartinR thank you! That answer did help. I will answer my own question now. – Dan Nov 15 '18 at 20:43

1 Answers1

0

The following does what I want and prints "2356".

let strB = "01235689"
print("String count \(strB.count).")
let fromB = strB.index(strB.startIndex, offsetBy: 2)
let toB = strB.index(strB.startIndex, offsetBy: 8)
print("\(String(strB[fromB..<toB]))")

Note instead of using:

let fromB = String.Index(encodedOffset: 2)
let toB = String.Index(encodedOffset: 8)

I use:

let fromB = strB.index(strB.startIndex, offsetBy: 2)
let toB = strB.index(strB.startIndex, offsetBy: 8)
Dan
  • 5,013
  • 5
  • 33
  • 59