我有一个API调用,它检查UserLogin和密码,并根据用户名和密码对是否正确发送响应。
如果用户名和密码对不正确,API将返回字典,如果用户名和密码正确,则将返回字典数组。
我面临的问题是我无法将Alamofire的响应向下转换为特定的数据类型。
func afLoginDriver(firstName: String,password:String,completion: @escaping ([Dictionary<String, Any>])->Void){
let driverLoginURL = "URL here.."
let parameters = ["firstName" : firstName, "Password" : password]
AF.request(driverLoginURL, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
switch response.result {
case .success:
let driverLoginResponse = response.value as? [Dictionary<String, Any>]
completion(driverLoginResponse)
break
case .failure(let error):
print(error)
}
}
}
如果用户名-密码对不正确,则变量driverLoginResponse会引发错误,因为它只是一个字典,而不是字典数组。
我尝试使用guard let语句,但仍然无法使它正常工作。
if let responseOne = response.value as? [String: Any] {
// ...
} else if let responseTwo = response.value as? [[String: Any]] {
// ...
}
struct Response: Codable {
var valueOne: [String: Any]?
var valueTwo: [[String: Any]]?
}
我将为此使用Codable
和enum
,但请考虑以下因素:
首先,以任何可能的响应实现enum
:
enum LoginDriverResponseValue {
case dictionary([String: Any])
case array([[String: Any]])
case string(String)
case unknown(Any)
}
然后,更改函数签名以适应该枚举:
func afLoginDriver(firstName: String, password: String, completion: @escaping (LoginDriverResponseValue)->Void) {
,,,
}
最后,打开枚举并调用相应的完成:
guard let responseValue = response.value else { return }
switch responseValue {
case let result as [String: Any]: completion(.dictionary(result))
case let result as [[String: Any]]: completion(.array(result))
case let result as String: completion(.string(result))
default: completion(.unknown(responseValue))
}
您可以将responseValue
类型检测封装到enum LoginDriverResponseValue
中:
extension LoginDriverResponseValue {
init(responseValue: Any) {
switch responseValue {
case let result as [String: Any]: self = .dictionary(result)
case let result as [[String: Any]]: self = .array(result)
case let result as String: self = .string(result)
default: self = .unknown(responseValue)
}
}
}
因此,您在函数中唯一需要的是:
guard let responseValue = response.value else { return }
completion(LoginDriverResponseValue(responseValue: responseValue))