【问题标题】:How to parse JSON using Alamofire 4.7 in Swift 4如何在 Swift 4 中使用 Alamofire 4.7 解析 JSON
【发布时间】:2018-09-05 12:14:14
【问题描述】:

我知道之前有人问过这个问题,但答案是在 Swift 3 中并使用旧版本的 Alamofire。

问题:无法弄清楚如何从 JSON 响应中检索数据,主要是 api_key

这是我的回复代码:

Alamofire.request(serverLink!, headers: headers).responseJSON{ response in

        if response.value != nil {
            //Some code to get api_key
            print(response)
        } else {
            print("error")
        }

当我print(response) 我得到以下信息:

        SUCCESS: {
    user =     {
        "api_key" = 9a13f31770b80767a57d753961acbd3a18eb1370;
        "created_on" = "2010-09-30T12:57:42Z";
        firstname = Paul;
        id = 4;
        "last_login_on" = "2018-03-27T10:15:10+03:00";
        lastname = Smith;
        login = admin;
        mail = "admin@demo.com";
        status = 1;
    }; 
}

我需要得到的是

“api_key”=9a13f31770b80767a57d753961acbd3a18eb1370;

它可以是数组、字典或仅包含以下内容的字符串:

9a13f31770b807...

有人可以向我解释如何从这个请求中获取(解码)它吗?

编辑

print(response.result.value):

RESPONSE: Optional({ user = { "api_key" = 9a13f31770b80767a57d753961acbd3a18eb1370; "created_on" = "2010-09-30T12:57:42Z"; firstname = Paul; id = 4; "last_login_on" = "2018-03-27T11:10:25+03:00"; lastname = Smith; login = admin; mail = "admin@demo.com"; status = 1; }; })

【问题讨论】:

  • 你可以使用SwiftyJSON库,使用非常简单,非常高效
  • @maku 如果 OP 不知道 如何 解析该工具是无关紧要的。而在 Swift 4 中,Codable 协议比 SwiftyJSON 高效得多。
  • 感谢您的建议,但我正在学习 swift 并且想先熟悉 alamofire

标签: ios json swift alamofire decode


【解决方案1】:

根据docs,这是您访问序列化 JSON 响应的方式:

if let json = response.result.value as? [String: Any] {
    print("JSON: \(json)") // serialized json response
}

要访问api_key,你只需要先解开成功和用户字典,然后你就可以访问用户字典中的api_key属性。

guard let user = json["user"] as? [String: Any],
      let apiKey = user["api_key"] as? String else {

      print("Failed to parse JSON")
      return
}

print(apiKey)

【讨论】:

  • 感谢您的回复,但我在这里遇到错误 - json["SUCCESS"] - 类型 'Any' 没有下标成员
  • 我已经更新了答案中的顶部块。尝试将response.result.value 转换为[String: Any]
  • 它成功了,谢谢,错误现在消失了,但是,当解析新问题出现时,在控制台中,print(json) next 之后 - 解析 JSON 失败。有什么想法吗?
  • 它将无法找到其中一个键或无法转换类型。尝试打印 response.result.value 并在上面的问题中显示输出
  • 这是我收到的内容,当我 print(response.result.value) 时:RESPONSE: Optional({ user = { "api_key" = 9a13f31770b80767a57d753961acbd3a18eb1370; "created_on" = "2010-09-30T12:57:42Z"; firstname = Paul; id = 4; "last_login_on" = "2018-03-27T11:10:25+03:00"; lastname = Smith; login = admin; mail = "admin@demo.com"; status = 1; }; }) 抱歉,我不能再编辑我的问题了..
【解决方案2】:

当您收到回复时,您可以。使用 Mapper 类的 ObjectMapper 库。

创建模型类

import Foundation
import ObjectMapper

public final class LoginModel: Mappable, NSCoding {

// MARK: Declaration for string constants to be used to decode and also serialize.
private struct SerializationKeys {
static let status = "status"
static let login = "login"
static let firstname = "firstname"
static let id = "id"
static let lastname = "lastname"
static let mail = "mail"
static let apiKey = "api_key"
static let createdOn = "created_on"
static let lastLoginOn = "last_login_on"
}

  // MARK: Properties
 public var status: Int?
public var login: String?
public var firstname: String?
public var id: Int?
public var lastname: String?
public var mail: String?
public var apiKey: String?
public var createdOn: String?
public var lastLoginOn: String?

// MARK: ObjectMapper Initializers
/// Map a JSON object to this class using ObjectMapper.
///
 /// - parameter map: A mapping from ObjectMapper.
 public required init?(map: Map){

}

/// Map a JSON object to this class using ObjectMapper.
///
/// - parameter map: A mapping from ObjectMapper.
  public func mapping(map: Map) {
  status <- map[SerializationKeys.status]
  login <- map[SerializationKeys.login]
  firstname <- map[SerializationKeys.firstname]
  id <- map[SerializationKeys.id]
 lastname <- map[SerializationKeys.lastname]
 mail <- map[SerializationKeys.mail]
 apiKey <- map[SerializationKeys.apiKey]
 createdOn <- map[SerializationKeys.createdOn]
 lastLoginOn <- map[SerializationKeys.lastLoginOn]
}

/// Generates description of the object in the form of a NSDictionary.
///
/// - returns: A Key value pair containing all valid values in the object.
 public func dictionaryRepresentation() -> [String: Any] {
 var dictionary: [String: Any] = [:]
 if let value = status { dictionary[SerializationKeys.status] = value }
  if let value = login { dictionary[SerializationKeys.login] = value }
  if let value = firstname { dictionary[SerializationKeys.firstname] = value }
  if let value = id { dictionary[SerializationKeys.id] = value }
  if let value = lastname { dictionary[SerializationKeys.lastname] = value }
  if let value = mail { dictionary[SerializationKeys.mail] = value }
  if let value = apiKey { dictionary[SerializationKeys.apiKey] = value }
  if let value = createdOn { dictionary[SerializationKeys.createdOn] = value }
  if let value = lastLoginOn { dictionary[SerializationKeys.lastLoginOn] = value }
  return dictionary
 }

// MARK: NSCoding Protocol
required public init(coder aDecoder: NSCoder) {
  self.status = aDecoder.decodeObject(forKey: SerializationKeys.status) as? Int
  self.login = aDecoder.decodeObject(forKey: SerializationKeys.login) as? String
  self.firstname = aDecoder.decodeObject(forKey: SerializationKeys.firstname) as? String
  self.id = aDecoder.decodeObject(forKey: SerializationKeys.id) as? Int
  self.lastname = aDecoder.decodeObject(forKey: SerializationKeys.lastname) as? String
  self.mail = aDecoder.decodeObject(forKey: SerializationKeys.mail) as? String
  self.apiKey = aDecoder.decodeObject(forKey: SerializationKeys.apiKey) as? String
  self.createdOn = aDecoder.decodeObject(forKey: SerializationKeys.createdOn) as? String
  self.lastLoginOn = aDecoder.decodeObject(forKey: SerializationKeys.lastLoginOn) as? String
 }

public func encode(with aCoder: NSCoder) {
  aCoder.encode(status, forKey: SerializationKeys.status)
 aCoder.encode(login, forKey: SerializationKeys.login)
 aCoder.encode(firstname, forKey: SerializationKeys.firstname)
 aCoder.encode(id, forKey: SerializationKeys.id)
 aCoder.encode(lastname, forKey: SerializationKeys.lastname)
 aCoder.encode(mail, forKey: SerializationKeys.mail)
 aCoder.encode(apiKey, forKey: SerializationKeys.apiKey)
 aCoder.encode(createdOn, forKey: SerializationKeys.createdOn)
  aCoder.encode(lastLoginOn, forKey: SerializationKeys.lastLoginOn)
}

}

使用此模型类来映射您的响应...

Alamofire.request(serverLink!, headers: headers).responseJSON{ response in

    if let responseData = Mapper< LoginModel>().map(JSONObject: response.result.value)  {

          print(responseData.apiKey)

      } else {
         print("Fail to map data")  
      }

}

【讨论】:

  • 在 Swift 4 中 ObjectMapper 已过时。 Codable 做同样的事情,但更聪明。
猜你喜欢
  • 2019-06-03
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
相关资源
最近更新 更多