Как проверить URL-адрес и получить код состояния в Swift 3?

Я использую самую последнюю версию Xcode (8.1 на момент написания), в которой используется Swift 3.0.

Все, что я пытаюсь сделать, это взять строку, преобразовать ее в URL-адрес и проверить этот URL-адрес, чтобы увидеть, дает ли он мне ошибку 404. Я смог сделать URL и URLRequest, используя:

    let url = URL(string: fullURL)
    let request = URLRequest(url: url!)

но я обнаружил, что не могу заставить что-либо работать дальше этого. Я искал помощь, но большая часть, если не все, написана на Swift 2.0, который я безуспешно пытался преобразовать. Кажется, что даже если вы измените соглашение об именах, чтобы удалить префикс NS, этого недостаточно. Я пытался использовать:

    let response: AutoreleasingUnsafeMutablePointer<URLRequest> = nil

но это дает мне ошибку, которую «исправить» усугубляет, вставляя везде вопросительные знаки и точки с запятой.

Документация Apple мне тоже не особо помогает. Я серьезно в растерянности.

Кто-нибудь знает, как правильно настроить и проверить URL-адрес для статуса 404 в Swift 3.0?


person DisturbedNeo    schedule 02.11.2016    source источник
comment
stackoverflow.com/a/39099896/1801544?   -  person Larme    schedule 02.11.2016
comment
вы можете проверить это   -  person Ahmad F    schedule 02.11.2016


Ответы (3)


попробуйте это, чтобы дать вам коды состояния ответов - 200, 404 и т. д.:

let url = URL(string: fullURL)

let task = URLSession.shared.dataTask(with: url!) { _, response, _ in
    if let httpResponse = response as? HTTPURLResponse {
        print(httpResponse.statusCode)
    }
}

task.resume()

Вы также можете сделать то же самое, просто заменив with: url! на использование request var, как вы определили в своем примере, например. let task = URLSession.shared.dataTask(with: request) {...} Но в этом примере я не думаю, что вам это действительно нужно.

person Matt Le Fleur    schedule 02.11.2016
comment
Ну работает без сбоев, но до него так и не доходит если пусть httpResponse = response as? HTTPURLResponse, поэтому он никогда не печатает код состояния. - person DisturbedNeo; 02.11.2016
comment
@DisturbedNeo это может быть как-то связано с самим URL. Если нет имени сервера с указанным именем хоста URL-адреса, вы даже не получите ошибку 404. Попробуйте добавить error после ответа, чтобы получить что-то вроде { _, response, error in , а затем попробуйте распечатать ошибку, чтобы увидеть, что вы получаете - person Matt Le Fleur; 02.11.2016
comment
Если вы получаете что-то вроде "A server with the specified hostname could not be found.", это указывает на проблему на стороне сервера. - person Matt Le Fleur; 02.11.2016
comment
Существуют всевозможные другие ошибки, такие как "The Internet connection appears to be offline.", и все они могут привести к сбою ответа, как вы упомянули. - person Matt Le Fleur; 02.11.2016
comment
В том-то и дело, что я не могу распечатать ошибки, это никогда не выходит за рамки задачи. Он позволяет task = URLSession.shared.dataTask(with: url!) { _, response, error in, а затем пропускает его к task.resume(). Я поставил точку останова на if, и цикл проверки разных URL-адресов запустился 100 раз, но ни разу не попал в точку останова. - person DisturbedNeo; 02.11.2016
comment
Как или где вы используете этот код? Для тестирования я поместил все это в viewDidLoad и, кажется, работает нормально, так что, возможно, причина в том, что вы делаете это по-другому? - person Matt Le Fleur; 02.11.2016
comment
Может быть. Мой код не находится в viewDidLoad, потому что нет представления, это просто код, работающий в main.swift. На данный момент программа должна запускаться, запускать цикл for, внутри которого она печатает проверяемый URL-адрес, выполняет проверку, а затем сообщает, был ли этот URL-адрес ошибкой 404. Я не понимаю, почему код находится в отдельная функция должна что-то менять, но тогда Xcode никогда не имел никакого смысла. Спасибо, в любом случае. - person DisturbedNeo; 02.11.2016
comment
Обнаружил проблему, потому что я проверял много URL-адресов в цикле for, поэтому в основном я не давал ему достаточно времени для ответа. Перевод в режим сна (1) или, по крайней мере, usleep (500000) непосредственно перед тем, как задача task.resume() была достаточно длинной, чтобы надежно получать коды состояния с каждого URL-адреса. Спасибо за вашу помощь ^_^ - person DisturbedNeo; 03.11.2016
comment
Нет проблем, рад, что у вас получилось! Я бы предложил использовать что-то другое, кроме сна, хотя это звучит немного ненадежно! Возможно, стоит взглянуть на GCD и обработчики синхронных запросов/завершения :) - person Matt Le Fleur; 03.11.2016
comment
@DisturbedNeo, можете ли вы пометить это как принятый ответ, если вы все еще им довольны? :) просто чтобы внести ясность, когда люди ищут один и тот же вопрос - person Matt Le Fleur; 09.08.2019

Простой пример:

    let url = // whatever
    let session = URLSession.shared
    let task = session.downloadTask(with:url) { loc, resp, err in
        let status = (resp as! HTTPURLResponse).statusCode
        print("response status: \(status)")
    }
    task.resume()
person matt    schedule 02.11.2016
comment
Никогда не используйте принудительную развертку (как!) без проверки значения, отличного от нуля. В противном случае приложение вылетит - person OxyFlax; 14.06.2018
comment
@OxyFlax, вы должны принудительно развернуть, если вы уверены в значении, для этого оно и предназначено. - person Patrick; 08.03.2021

Вот еще один пример из метода делегата

public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome downloadTask: URLSessionDownloadTask){

let responseStatusCode = (dataTask.response as! HTTPURLResponse).statusCode
}

Вот пример https://github.com/ankitthakur/SwiftNetwork/blob/master/Sources/Shared/SwiftNetwork.swift

person Ankit Thakur    schedule 02.11.2016