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!!!!!")}
}
}
}
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:
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.
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
.
Likewise, your code is referring to a non-existent class, NSHHTPURLResponse
. In Swift 3 and later, it's HTTPURLResponse
.
It's probably prudent to do if let
for the retrieval of the HTTPURLResponse
in order to get the statusCode
.
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.
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.
[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)