Ошибка при разборе данных JSON, полученных через Alamofire (Swift) - PullRequest
0 голосов
/ 09 мая 2018

Я работаю с некоммерческой организацией, чтобы помочь им разработать мобильное приложение для своего веб-сайта (поэтому они предоставили мне бэкэнд-сервисы и т. Д.)

Их служба PHP входа в систему принимает данные в формате JSON,и возвращает значение true или false в виде данных JSON, но у меня возникают проблемы при обработке ответа в Swift.Я использую Alamofire для подключения к службе HTTP.

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

func authenticateUser (un: String, pw: String)  -> Bool
{
    var checker = false
    let jsonDict : [String: String] = ["volunteer_email": un, "volunteer_pass": pw]

     Alamofire.request("www.sampleurl.com/login.php", method: .post, parameters: jsonDict, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

        switch(response.result) {
        case .success(_):
            if response.result.value != nil{
                print (response.result.value)
                let resp = response.result.value as! NSDictionary
                let results = resp["status"] as! [[String:Any]]
                //Change the boolean value of checker based on the value of the results constant
                print (results)
            }
            break

        case .failure(_):
            print(response.result.error)
            break
        }
    }

    return checker;
}

Журнал:

Необязательно (<__NSSingleObjectArrayI 0x600000009b50> ({status = false;})) Невозможно привести значение типа '__NSSingleObjectArrayI' (0x10e28c528) к 'NSDictionary' (0x10e28d1a8).2018-05-09 12: 13: 00.177091 + 0530 TestApp1 [16680: 817883] Не удалось преобразовать значение типа «__NSSingleObjectArrayI» (0x10e28c528) в «NSDictionary» (0x10e28d1a8).(lldb)

Журнал response.result.value:

Примечание: «status»: «false» / ​​«true» - это выходной сигнал веб-службы

Необязательно (<__ NSSingleObjectArrayI 0x60400001b160> ({status = false;}))

Примечание. Я провел небольшое исследование и понял, что такое NSSingleObjectArray и что его вызывает, но яЯ застрял здесь, поскольку сервис передает только одно значение JSON моему приложению.Есть ли способ справиться с этим, не прося организацию изменить свой код?По логике вещей, я не должен быть в состоянии привести ответ в NSDictionary независимо от его размера?

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

Другой вопрос StackOverflow

Заранее большое спасибо :)

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Используйте NSArray вместо NSDictionary

func authenticateUser (un: String, pw: String)  -> Bool{
var checker = false
let jsonDict : [String: String] = ["volunteer_email": un, "volunteer_pass": pw]

 Alamofire.request("www.sampleurl.com/login.php", method: .post, parameters: jsonDict, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

    switch(response.result) {
    case .success(_):
        if response.result.value != nil{
            print (response.result.value)
            let resp = response.result.value as! NSArray
            let results = resp["status"] as! [[String:Any]]
            //Change the boolean value of checker based on the value of the results constant
            print (results)
        }
        break

    case .failure(_):
        print(response.result.error)
        break
      }
   }

return checker;
 }
0 голосов
/ 09 мая 2018

Поскольку вы используете .responseJSON Alamofire, вы должны использовать параметризованные перечисления Alamofire. Он предоставляет объект json в .success. Так что case .success(_) расточительно.

Продолжайте в том же духе, и вам вообще не нужно вводить типы response.result.value.

Alamofire
    .request("www.sampleurl.com/login.php",
             method: .post,
             parameters: jsonDict,
             encoding: JSONEncoding.default,
             headers: nil)
    .responseJSON { (response) in            
        switch(response.result) {
        case .success(let responseJSON):
            print(responseJSON)

            /*
             As an improvement:
             To obtain an easy-access object, convert responseJSON to either a:
              1. Codable model:
                 let model = JSONDecoder().decode(SomeModel.self, 
                                                  from: responseJSONData)
              2. SwiftyJSON object: (available on GitHub)
                 let json = JSON(responseJSON)

             Doing so will basically make accessing the inner elements easier.
             */...

        case .failure(let error):
            print(error)
        }
}

Кстати, только к вашему сведению: ответ представляет собой массив словарей, а не словарь массива словарей.

...