ios - cómo verificar si existen rtmp o hls urls o van a dar error 404 en swift
validation rss (4)
Para un uso fácil, escribí el código a continuación y funciona perfectamente.
var video_Url = ""
if let url = NSURL(string: Response),
data = NSData(contentsOfURL: url)
{
video_Url = Response
}
else
{
video_Url = ""
}
Necesito analizar algunos datos de rss y abrir enlaces relacionados de rss analizados en swift 2, por ejemplo, quiero verificar que este enlace sea válido o no:
rtmp://185.23.131.187:1935/live/jomhori1
o este :
http://185.23.131.25/hls-live/livepkgr/_defint_/liveevent/livestream.m3u8
Mi código para verificar la validación de la url:
let urlPath: String = "http://185.23.131.25/hls-live/livepkgr/_defint_/liveevent/livestream.m3u8"
let url: NSURL = NSURL(string: urlPath)!
let request: NSURLRequest = NSURLRequest(URL: url)
let response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var valid : Bool!
do {
_ = try NSURLConnection.sendSynchronousRequest(request, returningResponse: response)
} catch {
print("404")
valid = false
}
He buscado en la web pero todo el método que encontré no fue útil para mi problema.
Encontré una solución aquí en Objective C, así que transferí el código a Swift (aunque necesitarás probarlo):
class testHandler: NSObject, NSURLConnectionDelegate{
func testURL(urlPath: String){
let url: NSURL = NSURL(string: urlPath)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "HEAD"
let connection = NSURLConnection(request: request, delegate: self)
}
func connection(connection: NSURLConnection,
didReceiveResponse response: NSURLResponse){
if response is NSHTTPURLResponse{
if (response as! NSHTTPURLResponse).statusCode==200{
//url exists
}
}
}
}
Una variación de Obj-C para respuesta proporcionada por @Moritz:
Nota: prefería una función en lugar de una clase, pero el comportamiento es el mismo:
+(void)verifyURL:(NSString*)urlPath withCompletion:(void (^_Nonnull)(BOOL isOK))completionBlock
{
NSURL *url = [NSURL URLWithString:urlPath];
if (url) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"HEAD";
//optional: request.timeoutInterval = 3;
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
BOOL isOK = NO;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
int code = (int)((NSHTTPURLResponse*)response).statusCode;
//note: you may want to allow other http codes as well
isOK = !error && (code == 200);
}
completionBlock(isOK);
}];
[dataTask resume];
} else {
completionBlock(NO);
}
}
y aquí hay una llamada con marcas de tiempo:
NSDate *date1 = [NSDate date];
[AppDelegate verifyURL:@"http://bing.com" withCompletion:^(BOOL isOK) {
NSDate *date2 = [NSDate date];
if (isOK) {
NSLog(@"url is ok");
} else {
NSLog(@"url is currently not ok");
}
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1];
NSLog(@"time to return: %.3f", diff);
}];
La respuesta de @sschale es agradable, pero NSURLConnection está en desuso, es mejor usar NSURLSession ahora.
Aquí está mi versión de una clase de prueba de URL:
class URLTester {
class func verifyURL(urlPath: String, completion: (isOK: Bool)->()) {
if let url = NSURL(string: urlPath) {
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "HEAD"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (_, response, error) in
if let httpResponse = response as? NSHTTPURLResponse where error == nil {
completion(isOK: httpResponse.statusCode == 200)
} else {
completion(isOK: false)
}
}
task.resume()
} else {
completion(isOK: false)
}
}
}
Y lo usa llamando al método de clase con un cierre final:
URLTester.verifyURL("http://google.com") { (isOK) in
if isOK {
print("This URL is ok")
} else {
print("This URL is NOT ok")
}
}
Swift 3.0 con URLSesión
class URLTester {
class func verifyURL(urlPath: String, completion: @escaping (_ isOK: Bool)->()) {
if let url = URL(string: urlPath) {
var request = URLRequest(url: url)
request.httpMethod = "HEAD"
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
if let httpResponse = response as? HTTPURLResponse, error == nil {
completion(httpResponse.statusCode == 200)
} else {
completion(false)
}
})
task.resume()
} else {
completion(false)
}
}
}
Esto es mejor que su respuesta porque solo descarga los encabezados de respuesta en lugar de la página completa (también es mejor porque no es asíncrono).