Ошибка Swift 3: тип ‘Any’ не имеет элементов подстрочного индекса

#swift

#swift

Вопрос:

Итак, я знаю, что этот вопрос задавался и на него отвечали много раз раньше, но я только что перенес свой проект на Swift 3, и я получаю массу этих ошибок в своем коде, который анализирует JSON, и я не мог найти ответы, которые помогли бы мне понять, как решить мою конкретную проблему.

 guard let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject] else {
        return
    }
    guard let responseData = result["Data"] else { return }
    guard let userData = responseData["UserProfile"] else { return }

    var userProfileFieldsDict = [String: String]()

    if let sessionToken = userData!["CurrentSessionToken"] as? NSString {
        userProfileFieldsDict["sessionToken"] = String(sessionToken)

    }
}
  

if let sessionToken Строка выдает вышеупомянутую ошибку, но не совсем уверен, как вы должны справиться с этим в Swift 3? Может ли кто-нибудь объяснить и предложить исправление наилучшей практики?

Большое спасибо!

Ответ №1:

Если responseData["UserProfile"] это также словарь, вы, вероятно, захотите использовать его как таковой в you guard, сказав guard let userData = responseData["UserProfile"] as? [String : AnyObject] else { return } . Я подозреваю, что это решит вашу проблему.

В качестве небольшого отступа, вам не нужно принудительно разворачивать userData в вашем if let, потому что вы уже развернули его в guard.

Комментарии:

1. Хм, круто. Но как и почему это поведение изменилось со времен Swift 2?

2. Честно говоря, это всегда должно было быть проблемой — если вы не приводите responseData [«UserProfile»], все, что знает компилятор, это то, что это AnyObject, который вы не можете индексировать. Я не могу сказать наверняка, не запустив код самостоятельно.

3. В конечном счете Swift хочет, чтобы вы действительно четко указывали типы объектов, поэтому, безусловно, лучше всего проверять тип в вашем операторе guard так, как я описал, если вы не используете дженерики или что-то в этом роде. Это немного больше ввода, но оно того стоит, чтобы избежать подобных ошибок.

4. Спасибо, я полностью согласен с вашим аргументом, хотя и вызывает недоумение, что Swift 2 не отреагировал на это. Приветствия!

5. Я не уверен, имеет ли это какое-либо отношение, но в Swift2 многие типы были созданы автоматически, AnyObject тогда как в Swift3 многие из них были изменены с AnyObject на Any . Я имел дело с рядом случаев, которые работали в Swift2, потому что something был AnyObject, который является более конкретным и удобным, чем Any. Не вдаваясь в подробности вашей конкретной ошибки, я могу сказать, что она пахнет похоже, учитывая регрессию от Swift2 к Swift3