25

I would like to convert my response from the NSHTTPURLResponse type to String:

let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) -> Void in 
     println("Response: \(response)")
     var responseText: String = String(data: response, encoding: NSUTF8StringEncoding)
})

The line below outputs the response message to the console.

println("Response: \(response)")

But this line renders me an error: Extra argument 'encoding' in Call.

var responseText: String = String(data: response, encoding: NSUTF8StringEncoding)

How can I successfully convert this "response" into a String?

Karl Ivar
  • 287
  • 1
  • 3
  • 6
  • The compiler error is confusing. `data` needs to be of type `NSData` but you are passing it an `NSHTTPURLResponse`. The method that is called (and returns a string) is `NSHTTPURLResponse`'s `description` method. – HAS Jan 25 '15 at 21:21
  • You probably want to convert `data` to a string, not `response`. – Martin R Jan 25 '15 at 21:25
  • yes but that isnt the response but a description ;) not good – Daij-Djan Jan 25 '15 at 21:25
  • I want to use the JSESSIONID found in the response and parse it, then pass it to a new dataTaskWithRequest. – Karl Ivar Jan 25 '15 at 21:26
  • it is a header field then? – Daij-Djan Jan 25 '15 at 21:31
  • Yes it is a header field. `headers { "Content-Length" = 4730; "Content-Type" = "text/html;charset=ISO-8859-1"; Date = "Sun, 25 Jan 2015 21:25:28 GMT"; Server = "Apache-Coyote/1.1"; "Set-Cookie" = "JSESSIONID=83A31742591DD2714A090FC53D55EEED; Path=/talkmore3/; Secure; HttpOnly"; }` – Karl Ivar Jan 25 '15 at 21:35

6 Answers6

45

body

grab the data and make it utf string if you want. The response's description is not the response body

let responseData = String(data: data, encoding: NSUTF8StringEncoding)

header field

if you want a HEADER FIELD instead:

let httpResponse = response as NSHTTPURLResponse
let field = httpResponse.allHeaderFields["NAME_OF_FIELD"]
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • note: _parsing_ a description is almost like screen-scraping – Daij-Djan Jan 25 '15 at 21:39
  • see `let httpResponse = response as NSHTTPURLResponse` => you have to cast it – Daij-Djan Jan 25 '15 at 21:40
  • I never intended to grab the data from the body. I was only interested in the header field, which also was included in the response description. However I understand it would be cumbersome to parse the description instead of reading the header field. Marked as the most correct answer. – Karl Ivar Jan 25 '15 at 21:44
6

Updated Answer:

As is turns out you want to get a header field's content.

if let httpResponse = response as? NSHTTPURLResponse {
    if let sessionID = httpResponse.allHeaderFields["JSESSIONID"] as? String {
        // use sessionID
    }
}

When you print an object its description method gets called.

This is why when you println() it you get a textual representation.

There are two ways to accomplish what you want.

  1. The easy way

    let responseText = response.description
    

However, this is only good for debugging.

  1. The localized way

    let localizedResponse = NSHTTPURLResponse.localizedStringForStatusCode(response.statusCode)
    

Use the second approach whenever you need to display the error to the user.

HAS
  • 19,140
  • 6
  • 31
  • 53
  • he wants the sessionID .. dont get why he should call description or (even more unrelated) NSHTTPURLResponse.localizedStringForStatusCode – Daij-Djan Jan 25 '15 at 21:32
  • The response-'description' contains http response headers which contain a JSESSIONID I have to parse. edit: If I could access the JSESSIONID directly, that would of course be the optimal solution. – Karl Ivar Jan 25 '15 at 21:33
  • the description has almost NO use and especially not for parsing data from it – Daij-Djan Jan 25 '15 at 21:33
  • [response valueForHTTPHeader:] (or what it is called) -- this is simply BAD advice – Daij-Djan Jan 25 '15 at 21:34
  • @Daij-Djan I changed my answer to reflect the changes. The question did not say anything about a header field, just printing the response. – HAS Jan 25 '15 at 21:41
  • yes responseData -- which is also not the response description -- IMO description has NO use except maybe debugging – Daij-Djan Jan 25 '15 at 21:42
  • @Daij-Djan That's exactly what I wrote 12 minutes ago. – HAS Jan 25 '15 at 21:43
  • whatever - I still find it wrong to even write this because it was CLEARLY not the real issue :D (especially no 2) anyway, revoked the vote, ciao – Daij-Djan Jan 25 '15 at 21:48
4

For a newer version in swift

   let task = session.dataTask(with: url) {(data, response, error) in

        let httpResponse = response as! HTTPURLResponse

        let type = httpResponse.allHeaderFields["Content-Type"]
        print("Content-Type", type)

        let l = httpResponse.allHeaderFields["Content-Length"]
        print("Content-Length", l)

        if let response = response {   // Complete response
            print(response)
        }


            }catch {
                print(error)
            }
        }
        }.resume()

}
user3826696
  • 1,045
  • 12
  • 13
2

You'll need the code below, because the response data from your data task is stored in data. response is the http response, with status codes etc, for more info about http response go here

var responseString: String = String(data: data, encoding: NSUTF8StringEncoding)
Marius Fanu
  • 6,589
  • 1
  • 17
  • 19
1

If you want to see the answer json as a string, in Swift 5

let httpResponse = response as? HTTPURLResponse

if let jsonResponse = String(data: data!, encoding: String.Encoding.utf8) {
    print("JSON String: \(jsonResponse)")
}
-1

It was as simple as var responseText: String = response.description.

Karl Ivar
  • 287
  • 1
  • 3
  • 6
  • as I said, the description is not necessarily the responseData – Daij-Djan Jan 25 '15 at 21:28
  • 2
    I'm actually not looking for the data, or responseData. I need to get the response 'description' as a String that I can parse. – Karl Ivar Jan 25 '15 at 21:31
  • Apple gives no guarantees about the format of object descriptions (beyond NSString and NSNumber). They are only intended for debugging and subject to change. As such, you do _not_ want to make your app rely on the format of an object's description. – uliwitness May 11 '18 at 11:26