web-dev-qa-db-de.com

Swift3.0 Der Wert des Typs 'ClosedRange <Index>' kann nicht in den Typ 'Bereich <Index>' konvertiert werden.

Ich versuche, das Swift 2.3 auf 3.0 zu migrieren und dieses Problem nach der Konvertierung zu beheben. Jeder Vorschlag, was ich falsch mache. 

Swift 3.0:

override func setValue(_ value: AnyObject?, forKey key: String) {
    let uppercasedFirstCharacter = String(key.characters.first!).uppercased()
    let range = key.startIndex...key.index(key.startIndex, offsetBy: 0)
    let selectorString = key.replacingCharacters(in: range, with: uppercasedFirstCharacter)

    let selector = NSSelectorFromString("set\(selectorString):")
    let responds = self.responds(to: selector)

    if !responds {
        return
    }

Error:

selectorString = key.replacingCharacters (in: Bereich, mit: uppercasedFirstCharacter)

Cannot convert value of type 'ClosedRange<Index>' (aka 'ClosedRange<String.CharacterView.Index>') to expected argument type 'Range<Index>' (aka 'Range<String.CharacterView.Index>')

Ursprünglicher Code: Swift 2.3

override func setValue(value: AnyObject?, forKey key: String) {
    let uppercasedFirstCharacter = String(key.characters.first!).uppercaseString

    let range = key.startIndex...key.startIndex.advancedBy(0)
    let selectorString = key.stringByReplacingCharactersInRange(range, withString: uppercasedFirstCharacter)

    let selector = NSSelectorFromString("set\(selectorString):")
    let responds = self.respondsToSelector(selector)

    if !responds {
        return
    }
12
Amit

Sie können ..< anstelle von ... verwenden, damit range vom Typ Range<Index> anstelle von ClosedRange<Index> ist. In diesem Fall führt der Aufruf von stringByReplacingCharactersInRange(...) nicht zu einem Fehler (beachten Sie, dass offsetBy um 1 zunimmt).

let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
// range is now type Range<Index>

Nun, ich bin vielleicht falsch, aber es scheint, als wollten Sie einfach, dass selectorString die Version von key ist, wobei das erste Zeichen in Großbuchstaben steht. Eine alternative Methode zu Ihrer Bereichslösung können Sie z. Verwenden Sie eine String-Erweiterungslösung wie folgt:

extension String { 
   var firstCharacterUppercased: String {
        guard case let c = self.characters,
                   let c1 = c.first else { return self }
        return String(c1).uppercased() + String(c.dropFirst())
    }
}

/* example usage */
let key = "fooBar"
let selectorString = key.firstCharacterUppercased

print(selectorString) // FooBar
13
dfri

Swift 3+

override func setValue(_ value: Any?, forKey key: String) {
        let upperCaseFirstCharacter = String(key.characters.first!).uppercased()
        let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
        let selectorString = key.replacingCharacters(in: range, with: upperCaseFirstCharacter)

        let selector = NSSelectorFromString("set\(selectorString):")
        let responds = self.responds(to: selector)

        if !responds{
            return
        }
        super.setValue(value, forKey: key)
    }

    init(dictionary: [String: Any]){
        super.init()
        setValuesForKeys(dictionary)
    }
0
Dasoga