Get HTTP Status using swift

2020-03-30 06:44发布

问题:

I am sorry, I haven't found an answer for my question(( Please, don't be very harsh, I am not a professional programmer, but I keep learning and hope once I will be able to answer someone's question))

I am trying to get HTTP Status of the link (I am sort of generating links depending on one database entries code, like ABCDEF, I keep them in an array and then generate a link to second database, like www.blablabla.ABCDEF.net), so I can see whether the page exists in database or not.

I have written this code, but something is wrong. So maybe it's a question like: "What's wrong with my code?" But on the stack they also say, you have to show your attempts of problem solving...

I wish I could keep it all swift, without any additional modules or something, I think NSHTTPURLResponse must be enough, but I am using it somehow wrong.

Looking forward to help and replies))

var err: NSError!

NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData!, error: err) -> Void in

    if (err != nil) {
        let httpStatus: NSHTTPURLResponse = response as NSHHTPURLResponse
        for myLink in allLinks {
            println("HERE IS THE CURRENT STATUS CODE" + httpStatus.statusCode + "OF A LINK:" + myLink)
            if httpStatus.statusCode == 200 {println("SUCCESS!!!!!")}
        }
    }
}

回答1:

The fundamental issue here is that you appear to be looking at the statusCode only if the err is not nil. But if you have error, you probably don't have status code. The error parameter to the closure indicates fundamental network issue that probably prevented you from getting to the page in question. The statusCode is generally only meaningful if the error was nil (i.e. you succeeded in connecting to the server), in which case the statusCode is how the server informs you of its ability to service the HTTP request.

A couple of minor things:

  1. You don't need the var err: NSError! line (because the error object is passed as parameter to the closure). This variable you've declared is not used here.

  2. I don't see how error: err as the third parameter to the closure could have worked. The syntax is "variableName: variableType", but there is no type of err.

  3. Likewise, your code is referring to a non-existent class, NSHHTPURLResponse. In Swift 3 and later, it's HTTPURLResponse.

  4. It's probably prudent to do if let for the retrieval of the HTTPURLResponse in order to get the statusCode.

  5. I'm unclear as to your intent in iterating through allLinks, because this connection is just for a given request, not a bunch of links. Just look at the statusCode in light of the particular request. If you need to test multiple URLs, then you do a separate request for each.

  6. We should consider any codes between 200 and 299 as success, not just 200. I'd suggest using the range 200 ..< 300.

Thus:

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, let httpResponse = response as? HTTPURLResponse, error == nil else {
        print("No valid response")
        return
    }

    guard 200 ..< 300 ~= httpResponse.statusCode else {
        print("Status code was \(httpResponse.statusCode), but expected 2xx")
        return
    }

    // everything OK, process `data` here
}
task.resume()

I also made a few other changes (updated for Swift 3 and later; use URLSession rather than URLConnection; I think error is fine choice for the variable name; I prefer the trailing closure syntax; I tend to use inferred types for closure parameters to make the declaration a little more concise, etc.), but all of that is immaterial to the question at hand: Hopefully this illustrates how one checks the status code.

For Swift 2 rendition, see previous revision of this answer.



回答2:

[Swift 5.2] Hi there, you can try this one:

    let task = URLSession.shared.dataTask(with: yourRequest) {
      (data, response, error) in
      guard let response = response else {
        print("Cannot found the response")
        return
      }
      let myResponse = response as! HTTPURLResponse
      print("Status Code:", myResponse.statusCode)
    }
    task.resume()

Here is the output

Status Code: 200

(This is your StatusCode)