距离(从:至:)'不可用:任何String视图索引转换都可能在Swift 4中失败;请打开可选索引

时间:2017-09-20 23:30:38

标签: swift swift4

我试图将我的应用程序迁移到Swift 4,Xcode 9.我收到此错误。它来自第三方框架。

  

距离(距离:至:)'不可用:任何String视图索引转换都可能在Swift 4中失败;请打开可选索引

func nsRange(from range: Range<String.Index>) -> NSRange {
    let utf16view = self.utf16
    let from = range.lowerBound.samePosition(in: utf16view)
    let to = range.upperBound.samePosition(in: utf16view)
    return NSMakeRange(utf16view.distance(from: utf16view.startIndex, to: from), // Error: distance(from:to:)' is unavailable: Any String view index conversion can fail in Swift 4; please unwrap the optional indices
                       utf16view.distance(from: from, to: to))// Error: distance(from:to:)' is unavailable: Any String view index conversion can fail in Swift 4; please unwrap the optional indices
}

3 个答案:

答案 0 :(得分:13)

你可以简单地打开这样的可选索引:

func nsRange(from range: Range<String.Index>) -> NSRange? {
    let utf16view = self.utf16
    if let from = range.lowerBound.samePosition(in: utf16view), let to = range.upperBound.samePosition(in: utf16view) {
       return NSMakeRange(utf16view.distance(from: utf16view.startIndex, to: from), utf16view.distance(from: from, to: to))
    }
    return nil
}

答案 1 :(得分:-1)

错误表示您生成的距离是选项,需要打开。试试这个:

func nsRange(from range: Range<String.Index>) -> NSRange {
    let utf16view = self.utf16
    guard let lowerBound = utf16view.distance(from: utf16view.startIndex, to: from), let upperBound = utf16view.distance(from: from, to: to) else { return NSMakeRange(0, 0) }
    return NSMakeRange(lowerBound, upperBound)
}

但是,guard语句可以更好地处理返回。我建议创建函数NSRange?的返回类型,并在调用函数时检查nil,以避免返回不准确的值。

答案 2 :(得分:-1)

请检查:

$opts

//这是使用Range

let dogString = "Dog‼"
let range = dogString.range(of: "")!

//这是使用NSRange

let strRange = dogString.range(range: range)
print((dogString as NSString).substring(with: strRange!)) // 

extension String {
    func range(range : Range<String.Index>) -> NSRange? {
        let utf16view = self.utf16
        guard
            let from = String.UTF16View.Index(range.lowerBound, within: utf16view),
            let to = String.UTF16View.Index(range.upperBound, within: utf16view)
        else { return nil }
        let utf16Offset = utf16view.startIndex.encodedOffset
        let toOffset = to.encodedOffset
        let fromOffset = from.encodedOffset
        return NSMakeRange(fromOffset - utf16Offset, toOffset - fromOffset)
    }
}