-4

I know this question was asked before, but answers were in Swift 3 and using older versions of Alamofire.

Problem: Can't figure out how to retrieve data from JSON response, mainly api_key.

Here is code for my response:

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

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

When I print(response) I get the following:

        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;
    }; 
}

What I need to get is

"api_key" = 9a13f31770b80767a57d753961acbd3a18eb1370;

It could be in form of array, dict or just string containing:

9a13f31770b807...

Could someone please explain to me how to get(decode) it from this request?

EDIT

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; }; })
Scriptable
  • 19,402
  • 5
  • 56
  • 72
Taras Tomchuk
  • 331
  • 7
  • 19
  • you may use SwiftyJSON library, very simple in use and very efficent – Enea Dume Mar 27 '18 at 07:39
  • 2
    @maku If the OP doesn't know **how** to parse the tool is irrelevant. And in Swift 4 the `Codable` protocol is much more efficient than SwiftyJSON. – vadian Mar 27 '18 at 07:43
  • thanks for your suggestion, but i'm studying swift and and would like to get acquainted with alamofire first – Taras Tomchuk Mar 27 '18 at 07:44

2 Answers2

7

As per the docs, this is how you access the serialised JSON response:

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

To access api_key you just need to unwrap the success and user dictionaries first and then you can access the api_key property in the user dictionary.

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

      print("Failed to parse JSON")
      return
}

print(apiKey)
Scriptable
  • 19,402
  • 5
  • 56
  • 72
  • thanks for your reply, but I got error here - `json["SUCCESS"] ` - Type 'Any' has no subscript member – Taras Tomchuk Mar 27 '18 at 07:51
  • I have updated the top block in my answer. try casting `response.result.value` to `[String: Any]` – Scriptable Mar 27 '18 at 07:52
  • it did the trick, thanks, error is gone now, but then, when parsing new issue appeared, in console, after `print(json)` next goes - Failed to parse JSON. Any thoughts? – Taras Tomchuk Mar 27 '18 at 08:04
  • it will be either failing to find one of the keys or failing to cast the type. try to print response.result.value and show the output in your question above – Scriptable Mar 27 '18 at 08:07
  • here's what I receive, when I `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; }; })` Sorry, I can't edit my question anymore.. – Taras Tomchuk Mar 27 '18 at 08:16
  • I dont think success is actually part of the JSON, I updated my answer and removed the Success bit. I will update your question with the response – Scriptable Mar 27 '18 at 08:17
  • success is in response not in response.result.value – Shehata Gamal Mar 27 '18 at 08:24
  • @Scriptable yes, that was the issue! **success** wasn't the part of json, that's why I could not parse it before as well. Many thanks for your help. I'll mark your answer as accepted one! – Taras Tomchuk Mar 27 '18 at 08:25
-3

When you get the response you can. use Mapper class of ObjectMapper library.

Create Model Class

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)
}

}

User this model class to map your response...

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")  
      }

}
Mahendra
  • 8,448
  • 3
  • 33
  • 56