3

I need to parse some data from rss and open related links from parsed rss in swift 2, for example i want to check this link is valid or not:

rtmp://185.23.131.187:1935/live/jomhori1

or this one :

http://185.23.131.25/hls-live/livepkgr/_defint_/liveevent/livestream.m3u8

My code to check the validation of the 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
                            }

I've searched the web but all the method I found wasn't helpful for my issue.

anonymox
  • 419
  • 1
  • 9
  • 32

4 Answers4

6

The answer by @sschale is nice, but NSURLConnection is deprecated, it's better to use NSURLSession now.

Here's my version of an URL testing class:

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)
        }
    }

}

And you use it by calling the class method with a trailing closure:

URLTester.verifyURL("http://google.com") { (isOK) in
    if isOK {
        print("This URL is ok")
    } else {
        print("This URL is NOT ok")
    }
}

Swift 3.0 with URLSession

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)
    }
  }
}

This is better than your answer because it only downloads the response headers instead of the whole page (also, it's better because asynchronous).

aBikis
  • 323
  • 4
  • 16
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
3

I found a solution here in Objective C, so I ported the code to Swift (though you'll need to test it):

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
                }
            }
    }

}
Community
  • 1
  • 1
sschale
  • 5,168
  • 3
  • 29
  • 36
1

An Obj-C variation for answer provided by @Moritz:

Note: I was preferring a function instead of a class, but the behavior is the same:

+(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);
    }
}

and here is a call with timestamps:

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);
}];
ishahak
  • 6,585
  • 5
  • 38
  • 56
0

For easy use I wrote below code and It's working perfectly.

var video_Url = ""
    if let url  = NSURL(string: Response),
    data = NSData(contentsOfURL: url)
    {
        video_Url = Response
    }
    else
    {
        video_Url = ""
    }
anonymox
  • 419
  • 1
  • 9
  • 32