As an exercise I am rewriting one of my apps using Swift.
In Objective-C I had the following line of code:
NSRange extendedRange = NSUnionRange(range, [[self.backingStore string]lineRangeForRange:NSMakeRange(NSMaxRange(range), 0)]);
In swift it looks like this:
let str = backingStore.string
let extendedRange: NSRange = NSUnionRange(range, str.lineRangeForRange(NSMakeRange(NSMaxRange(range), 0)))
However, for some reason I am getting 'Int' is not identical to 'String.Index' and I can't figure out why. Any help / insight would be appreciated.
If I bridge my string, it works:
let str = backingStore.string
let extendedRange: NSRange = NSUnionRange(range, str.bridgeToObjectiveC().lineRangeForRange(NSMakeRange(NSMaxRange(range), 0)))
Swift strings are not the same as Foundation strings: they can be bridged, and they may have method names in common, but that does not mean they should be treated as being compatible. Here are two views of the type definition of Swift.String.lineRangeForRange
.
Swift.String.lineRangeForRange (Swift.String)(Swift.Range<Swift.String.Index>) -> Swift.Range<Swift.String.Index>
String -> (Range<String.Index>) -> Range<String.Index>
Note also that Swift's Range<T>
is start/end while Foundation's NSRange
is location/length. There are ways to convert between NSRange
and Range<Int>
, but a Range<String.Index>
is a different story: String.Index
is more like an "iterator" than an "index".
What I'd say (and I'm highly pragmatic about this sort of thing) is that if you have a block of code that is based on the semantics of Objective-C strings it might be good to keep using them for a while: get your code working, and then evaluate changing to Swift's String later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With