Reputation: 31
I am trying to construct a function in Swift that sends a http HEAD request to a specified url, and measures the response time from the server. I am not concerned with parsing the response, only that I get a 200 from the server. I can do this in python with the requests module:
import requests
def get_latency():
r = requests.head("http://example.com")
return r.elapsed.total_seconds()
I assume I will need to use NSURL for this, and I've been able to get this far, but can't figure out the best way to actually send the request...
let url = NSURL (string: "http://example.com")
let request = NSURLRequest(URL: url!)
let started = NSDate()
<<<Send http HEAD request, verify response>>> <- need help here
let interval = NSDate().timeIntervalSinceDate(started)
Upvotes: 3
Views: 3487
Reputation: 3903
I wrote this version based on the comments above. I decided to design it as an extension of the URL class. I have tested this code with Swift 4.
extension URL {
/** Request the http status of the URL resource by sending a "HEAD" request over the network. A nil response means an error occurred. */
public func requestHTTPStatus(completion: @escaping (_ status: Int?) -> Void) {
// Adapted from https://stackoverflow.com/a/35720670/7488171
var request = URLRequest(url: self)
request.httpMethod = "HEAD"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let httpResponse = response as? HTTPURLResponse, error == nil {
completion(httpResponse.statusCode)
} else {
completion(nil)
}
}
task.resume()
}
/** Measure the response time in seconds of an http "HEAD" request to the URL resource. A nil response means an error occurred. */
public func responseTime(completion: @escaping (TimeInterval?) -> Void) {
let startTime = DispatchTime.now().uptimeNanoseconds
requestHTTPStatus { (status) in
if status != nil {
let elapsedNanoseconds = DispatchTime.now().uptimeNanoseconds - startTime
completion(TimeInterval(elapsedNanoseconds)/1e9)
}
else {
completion(nil)
}
}
}
}
Usage:
let testURL = URL(string: "https://www.example.com")
testURL?.responseTime { (time) in
if let responseTime = time {
print("Response time: \(responseTime)")
}
}
Upvotes: 4