So I've found issues relating to the case of converting NSRange
to Range<String.Index>
, but I've actually run into the opposite problem.
Quite simply, I have a String
and a Range<String.Index>
and need to convert the latter into an NSRange
for use with an older function.
So far my only workaround has been to grab a substring instead like so:
func foo(theString: String, inRange: Range<String.Index>?) -> Bool {
let theSubString = (nil == inRange) ? theString : theString.substringWithRange(inRange!)
return olderFunction(theSubString, NSMakeRange(0, countElements(theSubString)))
}
This works of course, but it isn't very pretty, I'd much rather avoid having to grab a sub-string and just use the range itself somehow, is this possible?
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.