Convert String.Index to Int or Range<String.Index> to NSRange
If you look into the definition of String.Index
you find:
struct Index : BidirectionalIndexType, Comparable, Reflectable {
/// Returns the next consecutive value after `self`.
///
/// Requires: the next value is representable.
func successor() -> String.Index
/// Returns the previous consecutive value before `self`.
///
/// Requires: the previous value is representable.
func predecessor() -> String.Index
/// Returns a mirror that reflects `self`.
func getMirror() -> MirrorType
}
So actually there is no way to convert it to Int
and that for good reason. Depending on the encoding of the string the single characters occupy a different number of bytes. The only way would be to count how many successor
operations are needed to reach the desired String.Index
.
Edit The definition of String
has changed over the various Swift versions but it's basically the same answer. To see the very current definition just CMD-click on a String
definition in XCode to get to the root (works for other types as well).
The distanceTo
is an extension which goes to a variety of protocols. Just look for it in the String
source after the CMD-click.
I don't know which version introduced it, but in Swift 4.2 you can easily convert between the two.
To convert Range<String.Index>
to NSRange
:
let range = s[s.startIndex..<s.endIndex]
let nsRange = NSRange(range, in: s)
To convert NSRange
to Range<String.Index>
:
let nsRange = NSMakeRange(0, 4)
let range = Range(nsRange, in: s)
Keep in mind that NSRange
is UTF-16 based, while Range<String.Index>
is Character
based.
Hence you can't just use counts and positions to convert between the two!
let index: Int = string.startIndex.distanceTo(range.startIndex)