Question or problem in the Swift programming language:
I’m upgrading code from Swift 2 to Swift 3 and ran across this error:
In Swift 2, this method comes from a String extension of which the compiler is aware.
I have not been able to locate this method in the Swift 3 library. It appears in the documentation for Foundation here:
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/occ/instm/NSString/enumerateSubstringsInRange:options:usingBlock:
My entire script is:
import Foundation var counts = [String: Int]() while let line = readLine()?.lowercased() { let range = line.characters.indices line.enumerateSubstringsInRange(range, options: .ByWords) {w,_,_,_ in guard let word = w else {return} counts[word] = (counts[word] ?? 0) + 1 } } for (word, count) in (counts.sorted {$0.0 < $1.0}) { print("\(word) \(count)") }
It works with Swift 2.2 (modulo the changes I have already made for Swift 3, such as lowercase -> lowercased and sort -> sorted) but fails to compile with Swift 3.
And very strangely, neither the Swift 3 command line compiler nor the Swift Migration assistant in XCode 8 Beta suggests a replacement, as it does for many other renamed methods. Perhaps enumerateSubstringsInRange is deprecated or its parameter names changed?
How to solve the problem:
If you type str.enumerateSubstrings
in a Playground, you'll see the following as a completion option:
enumerateSubstrings(in: Range, options: EnumerationOptions, body: (substring: String?, substringRange: Range, enclosingRange: Range, inout Bool) -> ())
In addition to addressing the new enumerateSubstrings(in:options:body:)
syntax, you need to also change how you get the range
for the string:
import Foundation var counts = [String: Int]() while let line = readLine()?.lowercased() { let range = line.startIndex ..< line.endIndex line.enumerateSubstrings(in: range, options: .byWords) {w,_,_,_ in guard let word = w else {return} counts[word] = (counts[word] ?? 0) + 1 } } for (word, count) in (counts.sorted {$0.0 < $1.0}) { print("\(word) \(count)") }