Swift Возьмите ответ HTTP JSON и проанализируйте его, используя Codable - PullRequest
0 голосов
/ 27 ноября 2018

, поэтому я пытаюсь выполнить вход в систему, отправив http-запрос на внутренний сервер с помощью Alamofire.

У меня есть методы запроса на двух уровнях, например:

class func requestWith(url : URL, method: HTTPMethod, parameters: Parameters?, headers: HTTPHeaders, completion: @escaping (_ response: DataResponse<Any>) -> Void){

    let sessionManager = NetworkManager.sharedInstance
    sessionManager.request(url, method: method, parameters: parameters, encoding: URLEncoding.default, headers: headers)
        .validate(statusCode: 200..<300)
        .responseJSON { (response) in
            if let data = response.data {
                print("RESPONSE ALAMOFIRE: code = \(String(describing: response.response?.statusCode)), response = \(String(decoding: data, as: UTF8.self)) ")
            }
            completion(response)
    }
}

Это был базовый метод для запросов Alamofire, который я использую для каждой функциональности, которую я хочу добавить.Теперь следует фактический метод входа в систему, который адаптирован для базовой аутентификации.

class func loginAccount(usernameOrEmail: String?, password: String?, onSuccess success: @escaping (_ data : Data?) -> Void, onFailure failure: @escaping (_ error: Error?, _ errorData: Data?) -> Void){

    let parameters: Parameters = [
        "username" : usernameOrEmail!,
        "password" : password!,
        "grant_type" : "password"
    ]

    let authUser = "WebClient"
    let authPass = "Parola123"

    let authData = "\(authUser):\(authPass)".data(using: String.Encoding.utf8)
    guard let base64Auth = authData?.base64EncodedString(options: []) else { return }
    let headers = [
        "Authorization": "Basic \(String(describing: base64Auth))",
    "Content-Type" : "application/x-www-form-urlencoded"
    ]

    let url = Constants.urls.URL_LOGIN
    APIRequest.requestWith(url: url!, method: .post, parameters: parameters, headers: headers) { (result) in
        switch result.result {
        case .success( _ ):

            if let jsonValue = result.result.value {
                let json = JSON(jsonValue)
                do {
                    let jsonData = try json.rawData( options: [])
                    success(jsonData)

                } catch {
                    print(error.localizedDescription)
                }
            }

            break

        case .failure(let error):
            print("There was an error in logging in: \(error)")
            failure(error, result.data)
            break
        }
    }
}

Наконец, метод, вызываемый при нажатии кнопки входа в систему в LoginViewController:

@IBAction func signInTapped(_ sender: Any) {
    APIRequest.loginAccount(usernameOrEmail: emailField.text, password: passwordField.text,
      onSuccess: {  (successData) in
        self.startLoadingAnimation()
        if let response = successData {
            print("Response123 is: \(response)")


            do {

                let f = try JSONDecoder().decode(tokenResponse.self, from: response)
                print("access token is: \(f.scope)")

            } catch {
                print(error.localizedDescription)
            }

            self.stopLoadingAnimation()

            if let vc = self.storyboard?.instantiateViewController(withIdentifier: "ChatLogNavi") as? UINavigationController {
                self.present(vc,animated: true, completion: nil)
            }

        } else {
            }

        }, onFailure: { (error, failureData) in
        var json = JSON()
        do {
            json = try JSON(data: failureData!)
        } catch {
        }
        let messageBody = json["message"].stringValue
        let alert = UIAlertController(title: error?.localizedDescription, message: messageBody, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(alert, animated: true)
    })

    print("\n get account \n")
}

Что такоесамое важное, что я не знаю, как мне установить тип данных ответа, когда я отправляю его из одного метода в другой.Наконец, когда я добираюсь до последнего метода, он просто ничего не возвращает, говоря: «Данные не могут быть прочитаны, потому что они не в правильном формате».Что я должен изменить?Я довольно новичок в этом JSON и HTTP-запросов.Спасибо!

РЕДАКТИРОВАТЬ: tokenResponse объявлен так:

 struct tokenResponse: Codable {
    var tokenType: String?
    var expiresIn: String?
    var refreshToken: String?
    var accessToken: String?
    var scope: String?

    enum CodingKeys: String, CodingKey {
        case tokenType = "token_type"
        case expiresIn = "expires_in"
        case refreshToken = "refresh_token"
        case accessToken = "access_token"
        case scope

    }
}

1 Ответ

0 голосов
/ 27 ноября 2018

Я думаю, что вы хотите получить JSON от вашего сервиса!Попробуйте изменить свою первую функцию следующим образом:

class func requestWith(url : URL, method: HTTPMethod, parameters: Parameters?, headers: HTTPHeaders, completion: @escaping (_ response: NSDictionary) -> Void){

    let sessionManager = NetworkManager.sharedInstance
    sessionManager.request(url, method: method, parameters: parameters, encoding: URLEncoding.default, headers: headers)
        .validate(statusCode: 200..<300)
        .responseJSON { (response) in
            if let result = response.result.value {
                let jsonResponse = result as! NSDictionary
                print("Your JSON is \(jsonResponse)")
            }
            completion(jsonResponse)
    }
}

Таким образом, вы можете получить словарь, включающий ваш JSON, в ответ на вашу функцию!После этого вы можете разобрать его для создания ваших объектов

...