How To Check Response.statusCode in sendSynchronousRequest on Swift
Asked Answered
V

10

84

How To check response.statusCode in SendSynchronousRequest in Swift The Code is Below :

let urlPath: String = "URL_IS_HERE"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil

var error: NSErrorPointer? = nil
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: nil) as NSData?

before and in objective c , we check response.statusCode With this : (long)response.statusCode but in swift i have no idea how can check response status Code

Velutinous answered 4/10, 2014 at 9:18 Comment(0)
E
117

you pass in a reference to response so it is filled THEN you check the result and cast it to a HTTPResponse as only http responses declare the status code property.

let urlPath: String = "http://www.google.de"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var response: NSURLResponse?

var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?

if let httpResponse = response as? NSHTTPURLResponse {
    println("error \(httpResponse.statusCode)")
}

note: in objC you would also use the same approach but if you use squared brackets, the compiler doesn't enforce the cast. Swift (being type safe) does enforce the cast always

Elect answered 4/10, 2014 at 9:58 Comment(3)
You can combine/simplify the if and let statements to if let httpResponse = response as? NSHTTPURLResponse { ... }.Washy
yip right Im not that used to the if let construct but it is cleaner! -- editedElect
All types in your answer that begin with NS have now dropped the NS. NSHTTPURLResponse -> HTTPURLResponse This is a note for future programmers.Adamsen
M
86

Swift 3 version for @GarySabo answer:

let url = URL(string: "https://apple.com")!
let request = URLRequest(url: url)

let task = URLSession.shared().dataTask(with: request) {data, response, error in

    if let httpResponse = response as? HTTPURLResponse {
        print("statusCode: \(httpResponse.statusCode)")
    }

}
task.resume()
Mclean answered 16/6, 2016 at 10:50 Comment(0)
D
20

I use an extension to URLResponse to simplify this one (Swift 3):

extension URLResponse {

    func getStatusCode() -> Int? {
        if let httpResponse = self as? HTTPURLResponse {
            return httpResponse.statusCode
        }
        return nil
    }
}
Defilade answered 10/8, 2017 at 23:1 Comment(2)
And how do you use it? An example would have been niceTenpins
usage: if let statusCode = urlResponse.getStatusCode() { /*...*/ }Defilade
D
18

Swift 3+

let dataURL = "https://myurl.com"
        var request = URLRequest(url: URL(string: dataURL)!)
        request.addValue("Bearer \(myToken)", forHTTPHeaderField: "Authorization")
        URLSession.shared.dataTask(with: request) { (data, response, error) in
            // Check if the response has an error
            if error != nil{
                print("Error \(String(describing: error))")
                return
            }

            if let httpResponse = response as? HTTPURLResponse{
                if httpResponse.statusCode == 401{
                    print("Refresh token...")
                    return
                }
            }

            // Get data success

        }.resume()
Dodson answered 26/8, 2017 at 13:55 Comment(0)
M
14

Create extension to check valid/invalid response -

extension HTTPURLResponse {
     func isResponseOK() -> Bool {
      return (200...299).contains(self.statusCode)
     }
}

Get response from request -

let task = URLSession.shared.dataTask(with: request) { (jsonData, response, error) in

                // post result on main thread
                DispatchQueue.main.async {

                    if let response = response as? HTTPURLResponse, response.isResponseOK() {
                        // assume if we don't receive any error then its successful
                        handler(true)
                    } else {
                        handler(false)
                    }
                }

            }
            task.resume()
        }
Mummery answered 31/8, 2019 at 8:22 Comment(0)
L
11

Cleaned up for Swift 2.0 using NSURLSession

let urlPath: String = "http://www.google.de"
let url: NSURL = NSURL(string: urlPath)!
let request: NSURLRequest = NSURLRequest(URL: url)
var response: NSURLResponse?


let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {urlData, response, reponseError in

         if let httpResponse = response as? NSHTTPURLResponse {
             print("error \(httpResponse.statusCode)")  
          }

 }
 task.resume()
 //You should not write any code after `task.resume()`
Luisaluise answered 1/1, 2016 at 4:57 Comment(0)
S
7

For Swift 5.5 with await

        let (data, response) = try await URLSession.shared.data(for: request)

        if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 {
            print ("httpResponse.statusCode: \(httpResponse.statusCode)")

            throw(Error.invalidHttpResponseCode)
        }
Simpleminded answered 10/12, 2021 at 16:48 Comment(0)
K
1

If you use the Just library it'd be as simple as:

Just.get("URL_IS_HERE").statusCode
Kalahari answered 6/6, 2015 at 0:51 Comment(0)
P
0

Swift 5.7 You can try this on the playground:

import Foundation
import PlaygroundSupport

let url = URL(string: "http://stackoverflow.com")!

URLSession.shared.dataTask(with: url) { data, response, error in
    guard let data = data, error == nil else {
        print(error ?? "Unknown error")
        return
    }
    if let httpResponse = response as? HTTPURLResponse {
        print("statusCode: \(httpResponse.statusCode)")
    }
    let contents = String(data: data, encoding: .utf8)
    print(contents!)
}.resume()

PlaygroundPage.current.needsIndefiniteExecution = true
Patton answered 15/10, 2022 at 10:33 Comment(0)
C
0

Swift 5.5+, iOS 15.0+

For Swift concurrency with async-await and handling a diverse set of success response status codes, consider the following implementation:

func sendRequest(_ request: URLRequest) async throws -> Data {
    let (data, response) = try await URLSession.shared.data(for: request)
    guard let httpResponse = (response as? HTTPURLResponse),
            200...299 ~= httpResponse.statusCode else {
        throw NetworkError.failResponse
    }
    return data
}

This function efficiently handles asynchronous requests, ensuring that the response falls within the successful status code range.

Colorful answered 19/1 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.