18

I'm using Alamofire library for connecting with an API in iOs. I have a problem in one of the connection, and I don't know if it is because of the data encoded in the body or any other thing. In order to detect my error, I'm trying to print in the console the request body for checking if I'm sending the correct data structure.

My code is the following:

func updateUser (#user: User, completionHandler: (responseObject: User?, error: AnyObject?) -> ()) {
    let parameters = [
        "_id": "\(user._id!)",
        "email": "\(user.email!)",
        "media": "\(Mapper().toJSONArray(user.media!))",
        "blogs": "\(Mapper().toJSONArray(user.blogs!))"
    ]

    var manager = Alamofire.Manager.sharedInstance
    manager.request(.PUT, apiUrl + "/route/to/api", parameters: parameters, encoding: .JSON)
        .responseObject{ (req: NSURLRequest, res: NSHTTPURLResponse?, user: User?, data: AnyObject?, error: NSError?) in
            if(error != nil) {
                NSLog("Error API updateUser: \(error)")
            }
            else {
                completionHandler(responseObject: user as User?, error: data)
            }
    }
}

User is a Mappable object, since I'm using ObjectMapper combined with Alamofire. User is defined by the following code:

class User: Mappable {
   var _id: String?
   var name: String?
   var media: [Media]?

   init(_id: String, name: String, media: [Media]){
      self._id = _id;
      self.name = name;
      self.media = media
   }

   required init=(_ map: Map){
      mapping(map)
   }

   func mapping(map: Map){
      _id <- map["_id"]
      name <- map["name"]
      media <- map["media"]
   }
}

Media is defined like User, but with different variables.

Also, I would like to know, in addition of printing request body, if I could include the parameters to Alimofire request in a more efficient way (something like parsing the User object and substituting it for the parameters variable)

Any idea about my problems?

EDIT:

Following the suggestion of @Travis, finally I found the solution for printing the request body. Below you could find the code:

println("request body: \(NSString(data:req.HTTPBody!, encoding:NSUTF8StringEncoding) as String?)")

About passing as parameters an object I couldn't work it, I followed the official documentation, but I could do it.

Alfonso
  • 197
  • 1
  • 1
  • 10
  • For logging request/response there is: https://github.com/konkab/AlamofireNetworkActivityLogger – neoneye Sep 07 '17 at 12:52

7 Answers7

44

For Swift 3+

print(NSString(data: (response.request?.httpBody)!, encoding: String.Encoding.utf8.rawValue))
Dasoga
  • 5,489
  • 4
  • 33
  • 40
12

The answer to your first question is,

println("request body: \(request.HTTPBody)")

As far as your 2nd question goes, there's a whole section on API Parameter Abstraction as well as CRUD & Authorization on the Alamofire main page.

Travis
  • 3,373
  • 20
  • 19
  • 2
    Thank you for your answer, but request.HTTBody return NSData object, and I cannot know if it is the string that I expect to have. I expect to obtain something like this: _// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}_ (with my own variables), and I obtain the following: _<7b225f69 64223a22 35353962 61656165..._ – Alfonso Jul 15 '15 at 19:24
  • 1
    There are a myriad of ways to convert NSData to a string (or JSON). I'd suggest using the search on here to find one of them. – Travis Jul 15 '15 at 19:53
  • 1
    How do I print the request body of `Alamofire.upload()` method? I am doing multipart. – Anirudha Mahale Aug 08 '19 at 04:40
6

Added the below extension for the Request class for printing the logs.

extension Request {
    public func debugLog() -> Self {
        #if DEBUG
            debugPrint("=======================================")
            debugPrint(self)
            debugPrint("=======================================")
        #endif
        return self
    }
}

To use the extension, just use debugLog() after defining your request, like so:

Alamofire.request(url).debugLog()
            .responseJSON( completionHandler: { response in
   })

reference url : link

Kartheek
  • 7,104
  • 3
  • 30
  • 44
3

Swift 5

print(response.debugDescription)
denisx
  • 31
  • 1
2

For Swift 4 & Swift 5, just like that :

String(data: data!, encoding: String.Encoding.utf8)

If not in DefaultDataResponse extension or object, replace data with yourObject.response.data

Medhi
  • 2,656
  • 23
  • 16
2

From Alamofire documentation here https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#curl-command-output

You can get curl request description

AF.request("https://httpbin.org/get")
    .cURLDescription { description in
        print(description)
    }
    .responseDecodable(of: DecodableType.self) { response in
        debugPrint(response.metrics)
    }
kirhgoff
  • 185
  • 6
  • 13
1

Just to turn it a bit easier.

    if let requestBody = request.request?.HTTPBody {
        do {
            let jsonArray = try NSJSONSerialization.JSONObjectWithData(requestBody, options: [])
            print("Array: \(jsonArray)")
        }
        catch {
            print("Error: \(error)")
        }
    }
Antonio Carlos
  • 770
  • 9
  • 19