17

I am using the following code to get a String substring from an NSRange:

func substring(with nsrange: NSRange) -> String? {
    guard let range = Range.init(nsrange)
        else { return nil }
    let start = UTF16Index(range.lowerBound)
    let end = UTF16Index(range.upperBound)
    return String(utf16[start..<end])
}

(via: https://mjtsai.com/blog/2016/12/19/nsregularexpression-and-swift/)

When I compile with Swift 4 (Xcode 9b4), I get the following errors for the two lines that declare start and end:

'init' is unavailable
'init' was obsoleted in Swift 4.0

I am confused, since I am not using an init.

How can I fix this?

2 Answers 2

33

Use Range(_, in:) to convert an NSRange to a Range in Swift 4.

extension String {
    func substring(with nsrange: NSRange) -> Substring? {
        guard let range = Range(nsrange, in: self) else { return nil }
        return self[range]
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Xcode forces me to fix the code as follows: func substring(with nsrange: NSRange) -> String? { guard let range = Range(nsrange, in: self) else { return nil } return String(self[range]) }
If you make the function return a Substring instead of a String, you won't have to convert the result.
Ah, I didn't realize Substring is a type, I thought it was a typo.
Substring is a slice type. What that means is that it holds a reference to the original string, as well as the range that the substring represents. The advantage of a slice is that you don't have to make a copy of the data the way you would if you were returning a new String, so performance is better.
5

With Swift 4 we can get substrings this way.

  1. Substring from index

    let originStr = "Test"
    let offset = 1
    let str = String(originStr.suffix(from: String.Index.init(encodedOffset: offset)))
    
  2. Substring to index

    let originStr = "Test"
    let offset = 1
    String(self.prefix(index))
    

2 Comments

Does that second example need some editing? Should index be offset
Also, it's not an answer to the question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.