Привет, я пытаюсь найти способ разобрать JSON в SWIFT, это отлично работает для меня, но у меня возникла проблема.

Я позволяю пользователю вводить имя пользователя, которое используется для URL-адреса JSON -> если пользователь вводит действительное имя пользователя, все работает нормально.

Но если он введет неправильное имя пользователя, мой синтаксический анализ не удастся, это тоже правильно, но пока мое приложение только вылетает, и я ищу способ обойти его.

Это мой код, в котором происходит сбой,

 let url0 = NSURL(string: newUrlPath!)
        let session0 = NSURLSession.sharedSession()
        let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
            if (error != nil) {
                println(error)
            } else {
                let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

Ошибка Xcode

Ошибка домена = NSURLErrorDomain Code = -1002 «Операция не может быть завершена. (Ошибка NSURLErrorDomain -1002.)» UserInfo = 0x7c12d610 {NSErrorFailingURLKey = XX, NSErrorFailingURLStringKey = XX, NSUnderlyingError = 0x7c12c8d0. kCFErrorDomainCFNetwork error -1002.) "} фатальная ошибка: неожиданно обнаружено nil при разворачивании необязательного значения

Все в порядке, потому что это страница возврата, которую я получил из моего запроса

https://br.api.pvp.net/api/lol/br/v1.4/summoner/by-name/smirknaitiax?api_key=5c7d4d4f-f320-43d5-8647-643c9f6ee5de

И да, он не может проанализировать это в NSDirectory, так как он не возвращает JSON (как обычно), есть ли способ позаботиться о том, чтобы, если эта страница появится (чтобы пользователь ввел неправильное имя пользователя), я мог выйти из своего петля / другой путь;)?

0
Fabian Boulegue 24 Ноя 2014 в 12:57

4 ответа

Лучший ответ

Вы используете много операций, которые могут потерпеть неудачу, и Swift не прощает ошибок. Ваш код выйдет из строя, если newURLPath равен нулю, если url0 равен нулю, потому что newURLPath не является допустимым URL.

Таким образом, ваш URL-запрос может вернуть ошибку (сам запрос не удался), но у вас есть случай, когда URL-запрос был успешным, но дает неожиданные результаты (не словарь JSON). Ваш код, оканчивающийся на «как NSDictionary», сообщает Swift: «Я знаю, что могу не получить словарь, но конвертирую то, что вы получаете, в словарь, и вылетает, если это не сработает». Просто измените это на

if let parsedJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
{
    // Will still crash if the server sends a valid JSON array
    let summonorID_JSON = parsedJSON as NSDictionary
}
else
{
    // data wasn't valid JSON, handle it. 
}

Разница в том, что необязательное значение, возвращаемое парсером JSON, будет принято без сбоев, и вы проверяете, получили ли вы действительный JSON или нет.

3
gnasher729 28 Ноя 2014 в 10:45

Поскольку вы получаете 404 по этому запросу, я предполагаю, что это будет происходить каждый раз, когда что-то не так с именем пользователя, вы должны обработать ответ сервера, чтобы он соответствовал этому. Первым делом нужно проверить, какой сервер вернул:

let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons

На этом этапе вы можете получить доступ к свойству statusCode, которое сообщит вам, был ли запрос хорош или нет (404). Имея эту информацию, вы можете решить, что делать, и, например, вы можете изменить свой код примерно так:

let url0 = NSURL(string: newUrlPath!)
let session0 = NSURLSession.sharedSession()
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
    if (error != nil) {
        println(error)
    } else {
        let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons
        httpResp.statusCode != 404 {
            let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
        } else {
            // Handle error at this point, tell user to retype username etc.
        }
    })
2
TheLittleHawk 4 Дек 2014 в 13:19

NSURL - это сбойный инициализатор, и именно это происходит, когда вы указываете недопустимый URL-адрес: он не может инициализироваться.

Так что оберните свой код в условную развёртку:

if let url0 = NSURL(string: newUrlPath!) {
    ...
}
0
zisoft 24 Ноя 2014 в 10:03

url0 становится nil, если пользователь вводит неправильные данные. Если вы используете значение nil в качестве url0!, приложение выйдет из строя.

Когда вы добавляете! после переменной вы сообщаете компилятору, что значение не будет равно нулю.

Поэтому, чтобы избежать сбоя, вы должны проверить условие nil перед вызовом

  let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
-1
Vignesh 24 Ноя 2014 в 10:13