Michael
Michael

Reputation: 697

'Int' is not identical to 'String.Index'

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.


EDIT:

If I bridge my string, it works:

let str = backingStore.string
let extendedRange: NSRange = NSUnionRange(range, str.bridgeToObjectiveC().lineRangeForRange(NSMakeRange(NSMaxRange(range), 0)))

Upvotes: 5

Views: 6492

Answers (2)

Erik
Erik

Reputation: 12858

Curious myself, I Cmd+Clicked on String.Index and discovered it is actually defined as a struct in an extension type:

extension String : Collection {
    struct Index : BidirectionalIndex {
        func succ() -> String.Index
        func pred() -> String.Index
    }

BidirectionalIndex is a protocol that inherits from another protocol, ForwardIndex.

I assume the succ() and pred() methods stand for 'successor' and 'predecessor' respectively.

Upvotes: 0

Jay Freeman -saurik-
Jay Freeman -saurik-

Reputation: 1759

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.

Upvotes: 1

Related Questions