I am trying to add this Extension
to my code in order to enumerate substrings by words. The source of this code was dated 2015, so this is apparently an earlier version of Swift
. I'm using Swift4.2
and I can't figure out how to properly update the code in the line identified below with a note.
extension String {
func words() -> [String] {
let range = Range<String.Index>(start: self.startIndex, end: self.endIndex) // THIS LINE CAUSES ERROR
var words = [String]()
self.enumerateSubstringsInRange(range, options: NSStringEnumerationOptions.ByWords) { (substring, _, _, _) -> () in
words.append(substring)
}
return words
}
}
I initially get this Error: Incorrect argument labels in call (have 'start:end:', expected '_:in:')
I follow the "Fix" prompt and it changes the line to this:
let range = Range<String.Index>(self.startIndex, in: self.endIndex)
Then, I get this Error with no Fix suggestion:
Cannot convert value of type 'String.Index' to expected argument type 'NSRange' (aka '_NSRange')
The Errors are probably due to a Swift
version update and I can't figure out the proper way to write this line.
The enumerate substrings in range method syntax has changed a bit since Swift3:
The new declaration:
func enumerateSubstrings(in range: R, options opts: String.EnumerationOptions = default, _ body: @escaping (String?, Range, Range, inout Bool) -> Void) where R : RangeExpression, R.Bound == String.Index
extension String {
func words() -> [String] {
var words = [String]()
enumerateSubstrings(in: startIndex..., options: .byWords) { substring, _, _, _ in
words.append(substring!)
}
return words
}
}
"abc def".words() // ["abc", "def"]
Note that in Swift 4 or later you should extend StringProtocol
instead of the type String
itself to support Substring
s as well. You can check how to implement it at the answer I posted here