所以我试图通过使用Alamofire向后端服务器发出http请求来执行登录。
我有2个级别的请求方法,如下所示:
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
}
}
答案 0 :(得分:0)
我认为您想从服务中接收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的字典,以从函数中返回!之后,您可以解析它以创建对象