90

In an iPhone app I am developing, there is a setting in which you can enter a URL, because of form & function this URL needs to be validated online as well as offline.

So far I haven't been able to find any method to validate the url, so the question is;

How do I validate an URL input on the iPhone (Objective-C) online as well as offline?

Gabriel.Massana
  • 8,165
  • 6
  • 62
  • 81
Thizzer
  • 16,153
  • 28
  • 98
  • 139

22 Answers22

239

Why not instead simply rely on Foundation.framework?

That does the job and does not require RegexKit :

NSURL *candidateURL = [NSURL URLWithString:candidate];
// WARNING > "test" is an URL according to RFCs, being just a path
// so you still should check scheme and all other NSURL attributes you need
if (candidateURL && candidateURL.scheme && candidateURL.host) {
  // candidate is a well-formed url with:
  //  - a scheme (like http://)
  //  - a host (like stackoverflow.com)
}

According to Apple documentation :

URLWithString: Creates and returns an NSURL object initialized with a provided string.

+ (id)URLWithString:(NSString *)URLString

Parameters

URLString : The string with which to initialize the NSURL object. Must conform to RFC 2396. This method parses URLString according to RFCs 1738 and 1808.

Return Value

An NSURL object initialized with URLString. If the string was malformed, returns nil.

Vincent Guerci
  • 14,379
  • 4
  • 50
  • 56
  • You have a small typo. Should be `... and candidateURL.host`. Nice solution. – chris Mar 27 '11 at 08:16
  • +1. This is much better than a regex, for the simple reason that a regex is fragile and adds complexity. An `NSURL` instance is either valid or `nil`, yielding a quick, simple yes/no answer about the validity of the URL. – Alex Reynolds Nov 09 '11 at 07:02
  • 1
    I agree with some of the others here. This is a much better solution that fiddling around with regular expressions. This should be the correctly checked answer. – Diego Barros Feb 21 '12 at 01:34
  • This solution doesn't prevent all malformed urls from being returned as nil – Thizzer Jul 01 '12 at 11:18
  • 1
    @MrThys - Any chance you could provide examples of which malformed urls this doesn't catch? Would be great to know.. seems an excellent solution so far. – uɥƃnɐʌuop Nov 08 '12 at 22:18
  • 7
    @DonamiteIsTnt The URL `http://www.aol.comhttp://www.nytimes.com` passes this test. – Aaron Brager Dec 06 '12 at 18:30
  • 1
    The code will not check for malformed url. Ex: http://afasd, the url will still pass the test – denil Jan 09 '13 at 04:52
  • 39
    The docs are wrong. Write a few tests — `NSURL` does not return nil when I pass a string of @"#@#@$##%$#$#", or @"tp:/fdfdfsfdsf". So this method will be useless for checking valid HTTP URLs and the like. – Tony Arnold Jan 29 '13 at 07:00
  • If I enter URL like : "file://localhost/...", is it valid? – Tony Nov 12 '13 at 03:29
  • Unfortunately hashtags get turned into NSURLs by this API. As an example "#hashtag" becomes an NSURL. – bdmontz Feb 09 '15 at 16:06
  • 1
    I'm not sure why this has so many upvotes. This method accepts an empty string as a valid URL. – Sandy Chapman Feb 18 '15 at 17:42
  • unfortunately it will return as valid a nil hostname as http://(null)...elegant solution but won't validate even the most basic scenarios. – Vincil Bishop Jun 25 '15 at 17:34
  • 1
    this seems to work for the test cases @TonyArnold pointed out (iOS 9.1 SDK) but fails for www.microsoft.com because the host is nil. if i do http//www.microsoft.com or http:// microsoft.com, it passes the validation. For an average Joe, www.microsoft.com is a proper url so in my case I've to tweak this solution. Edit: add a ' ' after http:// because SO automatically hyperlinks it. – newDeveloper Dec 12 '15 at 00:06
  • @newDeveloper if you add http:// to tp:/fdfdfsfdsf - it passes... check -rocode- answer in the bottom - i think its the best over here. – DaNLtR Jul 21 '16 at 16:25
  • Not sure where all the upvotes are coming from, but simple check: https://123.123.123.123qwe:6001 passes this validation. Quite invalid ;) – Krystian Aug 29 '17 at 18:48
100

Thanks to this post, you can avoid using RegexKit. Here is my solution (works for iphone development with iOS > 3.0) :

- (BOOL) validateUrl: (NSString *) candidate {
    NSString *urlRegEx =
    @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; 
    return [urlTest evaluateWithObject:candidate];
}

If you want to check in Swift my solution given below:

 func isValidUrl(url: String) -> Bool {
        let urlRegEx = "^(https?://)?(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$"
        let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx)
        let result = urlTest.evaluate(with: url)
        return result
    }
Kishan Suthar
  • 648
  • 1
  • 8
  • 15
lefakir
  • 3,983
  • 4
  • 27
  • 37
  • 7
    This only works for urls of type "http://www.webr.ly" does not work for urls with parameters like http://www.youtube.com/watch?v=mqgExtdNMBk – ThE uSeFuL Jul 18 '12 at 05:44
  • 5
    `((http|https)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"` .It should make http:// or https:// is optiional. – Yeung Nov 14 '13 at 03:26
  • not working for google.com, www.google.com and also for //www.google.com – Revinder Sep 05 '14 at 11:35
  • following urls are not working in my case. http://money.cnn.com/2015/10/19/technology/apple-app-store/index.html?category=home – DJtiwari Oct 20 '15 at 04:45
  • @DJtiwari +1 yes it's not working did you find any fix for that? – Hamza MHIRA Dec 14 '15 at 15:36
  • http://52.88.111.0/API/public/uploads/facilities/images/2585/f6873da52827bbbd-1.png. Not working in my case – AnLT Sep 29 '17 at 03:01
  • this is not working for more complex url's or fails to get invalid url's like in the comments above shown – zero3nna Jan 18 '18 at 16:59
  • All this goes through: `www.ailive` `wwwailive.` I'm not even including `com` or any extentions.!!! ??????? – ekashking May 28 '18 at 00:27
32

Instead of writing your own regular expressions, rely on Apple's. I have been using a category on NSString that uses NSDataDetector to test for the presence of a link within a string. If the range of the link found by NSDataDetector equals the length of the entire string, then it is a valid URL.

- (BOOL)isValidURL {
    NSUInteger length = [self length];
    // Empty strings should return NO
    if (length > 0) {
        NSError *error = nil;
        NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];
        if (dataDetector && !error) {
            NSRange range = NSMakeRange(0, length);
            NSRange notFoundRange = (NSRange){NSNotFound, 0};
            NSRange linkRange = [dataDetector rangeOfFirstMatchInString:self options:0 range:range];
            if (!NSEqualRanges(notFoundRange, linkRange) && NSEqualRanges(range, linkRange)) {
                return YES;
            }
        }
        else {
            NSLog(@"Could not create link data detector: %@ %@", [error localizedDescription], [error userInfo]);
        }
    }
    return NO;
}
Anthony
  • 666
  • 6
  • 8
  • Extremely clever. Real engineering. {You know, I had a weird problem where if I send it the string literally "", it crashes! Could never figure it out.} – Fattie Oct 24 '14 at 17:16
  • Ah - it was "" in the son, which apple usefully supplies as an NSNull! :O – Fattie Oct 24 '14 at 17:19
  • I created a gist where I started adding test cases for this snipped. Fill free to add more. https://gist.github.com/b35097bad451c59e23b1.git – Yevhen Dubinin Mar 26 '15 at 16:06
26

My solution with Swift:

func validateUrl (stringURL : NSString) -> Bool {

    var urlRegEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
    let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[urlRegEx])
    var urlTest = NSPredicate.predicateWithSubstitutionVariables(predicate)

    return predicate.evaluateWithObject(stringURL)
}

For Test:

var boolean1 = validateUrl("http.s://www.gmail.com")
var boolean2 = validateUrl("https:.//gmailcom")
var boolean3 = validateUrl("https://gmail.me.")
var boolean4 = validateUrl("https://www.gmail.me.com.com.com.com")
var boolean6 = validateUrl("http:/./ww-w.wowone.com")
var boolean7 = validateUrl("http://.www.wowone")
var boolean8 = validateUrl("http://www.wow-one.com")
var boolean9 = validateUrl("http://www.wow_one.com")
var boolean10 = validateUrl("http://.")
var boolean11 = validateUrl("http://")
var boolean12 = validateUrl("http://k")

Results:

false
false
false
true
false
false
true
true
false
false
false
Gabriel.Massana
  • 8,165
  • 6
  • 62
  • 81
10

use this-

NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
Vaibhav Saran
  • 12,848
  • 3
  • 65
  • 75
5

I solved the problem using RegexKit, and build a quick regex to validate a URL;

NSString *regexString = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
NSString *subjectString = brandLink.text;
NSString *matchedString = [subjectString stringByMatching:regexString];

Then I check if the matchedString is equal to the subjectString and if that is the case the url is valid :)

Correct me if my regex is wrong ;)

Thizzer
  • 16,153
  • 28
  • 98
  • 139
  • I might be wrong, but I believe that regex doesn't validate urls with query strings or named anchors. – hpique Nov 24 '10 at 22:13
  • You could make the prefix part optional by replacing (http|https):// with ((http|https)://)* but this would allow a very wide variety of urls – Thizzer Aug 15 '11 at 07:20
4

I've found the easiest way to do this is like so:

- (BOOL)validateUrl: (NSURL *)candidate
{
    NSURLRequest *req = [NSURLRequest requestWithURL:candidate];
    return [NSURLConnection canHandleRequest:req];
}
julianwyz
  • 3,104
  • 1
  • 29
  • 34
  • I've been using it for a while now and it seems to work fine. It also seems to play nice with the new TLDs (https://www.namecheap.com/domains/new-tlds/explore.aspx). – julianwyz Oct 19 '15 at 15:39
  • This is pointless. If your URL is invalid string, it will crash while creating a `NSURL`, so that could checked instead of this. And even so it uses old API. – Legoless Jun 05 '16 at 21:36
  • @Legoless could just use a try...catch around it? – Brett Sep 15 '16 at 07:46
  • @Legoless Which version do you work on? This solution works well in my situation. – Michael Dec 24 '20 at 08:53
4

Oddly enough, I didn't really find a solution here that was very simple, yet still did an okay job for handling http / https links.

Keep in mind, THIS IS NOT a perfect solution, but it worked for the cases below. In summary, the regex tests whether the URL starts with http:// or https://, then checks for at least 1 character, then checks for a dot, and then again checks for at least 1 character. No spaces allowed.

+ (BOOL)validateLink:(NSString *)link
{
    NSString *regex = @"(?i)(http|https)(:\\/\\/)([^ .]+)(\\.)([^ \n]+)";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:link];
}

Tested VALID against these URLs:

@"HTTP://FOO.COM",
@"HTTPS://FOO.COM",
@"http://foo.com/blah_blah",
@"http://foo.com/blah_blah/",
@"http://foo.com/blah_blah_(wikipedia)",
@"http://foo.com/blah_blah_(wikipedia)_(again)",
@"http://www.example.com/wpstyle/?p=364",
@"https://www.example.com/foo/?bar=baz&inga=42&quux",
@"http://✪df.ws/123",
@"http://userid:password@example.com:8080",
@"http://userid:password@example.com:8080/",
@"http://userid@example.com",
@"http://userid@example.com/",
@"http://userid@example.com:8080",
@"http://userid@example.com:8080/",
@"http://userid:password@example.com",
@"http://userid:password@example.com/",
@"http://142.42.1.1/",
@"http://142.42.1.1:8080/",
@"http://➡.ws/䨹",
@"http://⌘.ws",
@"http://⌘.ws/",
@"http://foo.com/blah_(wikipedia)#cite-",
@"http://foo.com/blah_(wikipedia)_blah#cite-",
@"http://foo.com/unicode_(✪)_in_parens",
@"http://foo.com/(something)?after=parens",
@"http://☺.damowmow.com/",
@"http://code.google.com/events/#&product=browser",
@"http://j.mp",
@"http://foo.bar/?q=Test%20URL-encoded%20stuff",
@"http://مثال.إختبار",
@"http://例子.测试",
@"http://उदाहरण.परीक्षा",
@"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com",
@"http://1337.net",
@"http://a.b-c.de",
@"http://223.255.255.254"

Tested INVALID against these URLs:

@"",
@"foo",
@"ftp://foo.com",
@"ftp://foo.com",
@"http://..",
@"http://..",
@"http://../",
@"//",
@"///",
@"http://##/",
@"http://.www.foo.bar./",
@"rdar://1234",
@"http://foo.bar?q=Spaces should be encoded",
@"http:// shouldfail.com",
@":// should fail"

Source of URLs: https://mathiasbynens.be/demo/url-regex

kgaidis
  • 14,259
  • 4
  • 79
  • 93
3

You can use this if you do not want http or https or www

NSString *urlRegEx = @"^(http(s)?://)?((www)?\.)?[\w]+\.[\w]+";

example

- (void) testUrl:(NSString *)urlString{
    NSLog(@"%@: %@", ([self isValidUrl:urlString] ? @"VALID" : @"INVALID"), urlString);
}

- (void)doTestUrls{
    [self testUrl:@"google"];
    [self testUrl:@"google.de"];
    [self testUrl:@"www.google.de"];
    [self testUrl:@"http://www.google.de"];
    [self testUrl:@"http://google.de"];
}

Output:

INVALID: google
VALID: google.de
VALID: www.google.de
VALID: http://www.google.de
VALID: http://google.de
Hiren
  • 12,720
  • 7
  • 52
  • 72
3

Lefakir's solution has one issue. His regex can't match with "http://instagram.com/p/4Mz3dTJ-ra/". Url component has combined numerical and literal character. His regex fail such urls.

Here is my improvement.

"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*)+)+(/)?(\\?.*)?"
covernal
  • 329
  • 1
  • 3
  • 20
2

Below code will let you find the valid URLs

      NSPredicate *websitePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"^(((((h|H)(t|T){2}(p|P)s?)|((f|F)(t|T)(p|P)))://(w{3}.)?)|(w{3}.))[A-Za-z0-9]+(.[A-Za-z0-9-:;\?#_]+)+"];
     if ([websitePredicate evaluateWithObject:##MY_STRING##])
     {
       printf"Valid"
     }

for such URLS

Rajesh
  • 10,318
  • 16
  • 44
  • 64
1

The approved answer is incorrect. I have an URL with an "-" in it, and the validation fails.

Leander
  • 612
  • 7
  • 8
1

Tweeked Vaibhav's answer to support G+ links:

NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w-\\+ ./?%&=]*)?";

MuhammadBassio
  • 1,590
  • 10
  • 13
1

Some URL's without / at the end are not detected as the correct one in the solutions above. So this might be helpful.

  extension String {
    func isValidURL() -> Bool{
        let length:Int = self.characters.count
        var err:NSError?
        var dataDetector:NSDataDetector? = NSDataDetector()
        do{
            dataDetector = try NSDataDetector(types: NSTextCheckingType.Link.rawValue)
        }catch{
            err = error as NSError
        }
        if dataDetector != nil{
            let range = NSMakeRange(0, length)
            let notFoundRange = NSRange(location: NSNotFound, length: 0)
            let linkRange = dataDetector?.rangeOfFirstMatchInString(self, options: NSMatchingOptions.init(rawValue: 0), range: range)
            if !NSEqualRanges(notFoundRange, linkRange!) && NSEqualRanges(range, linkRange!){
                return true
            }
        }else{
            print("Could not create link data detector: \(err?.localizedDescription): \(err?.userInfo)")
        }

        return false
    }
}
Pratik Mistry
  • 2,905
  • 1
  • 22
  • 35
1

URL Validation in Swift

Details

Xcode 8.2.1, Swift 3

Code

enum URLSchemes: String

import Foundation

enum URLSchemes: String {
    case http = "http://", https = "https://", ftp = "ftp://", unknown = "unknown://"

    static func detectScheme(urlString: String) -> URLSchemes {

        if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .http) {
            return .http
        }
        if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .https) {
            return .https
        }
        if URLSchemes.isSchemeCorrect(urlString: urlString, scheme: .ftp) {
            return .ftp
        }
        return .unknown
    }

    static func getAllSchemes(separetedBy separator: String) -> String {
        return "\(URLSchemes.http.rawValue)\(separator)\(URLSchemes.https.rawValue)\(separator)\(URLSchemes.ftp.rawValue)"
    }

    private static func isSchemeCorrect(urlString: String, scheme: URLSchemes) -> Bool {
        if urlString.replacingOccurrences(of: scheme.rawValue, with: "") == urlString {
            return false
        }
        return true
    }
}

extension String

import Foundation

extension String {

    var isUrl: Bool {

        // for http://regexr.com checking
        // (?:(?:https?|ftp):\/\/)(?:xn--)?(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[#-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?

        let schemes = URLSchemes.getAllSchemes(separetedBy: "|").replacingOccurrences(of: "://", with: "")
        let regex = "(?:(?:\(schemes)):\\/\\/)(?:xn--)?(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[#-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?"


        let regularExpression = try! NSRegularExpression(pattern: regex, options: [])
        let range = NSRange(location: 0, length: self.characters.count)
        let matches = regularExpression.matches(in: self, options: [], range: range)
        for match in matches {
            if range.location == match.range.location && range.length == match.range.length {
                return true
            }
        }
        return false
    }

    var toURL: URL? {

        let urlChecker: (String)->(URL?) = { url_string in
            if url_string.isUrl, let url = URL(string: url_string) {
                return url
            }
            return nil
        }

        if !contains(".") {
            return nil
        }

        if let url = urlChecker(self) {
            return url
        }

        let scheme = URLSchemes.detectScheme(urlString: self)
        if scheme == .unknown {
            let newEncodedString = URLSchemes.http.rawValue + self
            if let url = urlChecker(newEncodedString) {
                return url
            }
        }

        return nil
    }
}

Usage

 func tests() {

    chekUrl(urlString:"http://example.com")
    chekUrl(urlString:"https://example.com")
    chekUrl(urlString:"http://example.com/dir/file.php?var=moo")
    chekUrl(urlString:"http://xn--h1aehhjhg.xn--d1acj3b")
    chekUrl(urlString:"http://www.example.com/wpstyle/?p=364")
    chekUrl(urlString:"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com")
    chekUrl(urlString:"http://example.com")
    chekUrl(urlString:"http://xn--d1acpjx3f.xn--p1ai")
    chekUrl(urlString:"http://xn--74h.damowmow.com/")
    chekUrl(urlString:"ftp://example.com:129/myfiles")
    chekUrl(urlString:"ftp://user:pass@site.com:21/file/dir")
    chekUrl(urlString:"ftp://ftp.example.com:2828/asdah%20asdah.gif")
    chekUrl(urlString:"http://142.42.1.1:8080/")
    chekUrl(urlString:"http://142.42.1.1/")
    chekUrl(urlString:"http://userid:password@example.com:8080")
    chekUrl(urlString:"http://userid@example.com")
    chekUrl(urlString:"http://userid@example.com:8080")
    chekUrl(urlString:"http://foo.com/blah_(wikipedia)#cite-1")
    chekUrl(urlString:"http://foo.com/(something)?after=parens")

    print("\n----------------------------------------------\n")

    chekUrl(urlString:".")
    chekUrl(urlString:" ")
    chekUrl(urlString:"")
    chekUrl(urlString:"-/:;()₽&@.,?!'{}[];'<>+_)(*#^%$")
    chekUrl(urlString:"localhost")
    chekUrl(urlString:"yandex.")
    chekUrl(urlString:"коряга")
    chekUrl(urlString:"http:///a")
    chekUrl(urlString:"ftps://foo.bar/")
    chekUrl(urlString:"rdar://1234")
    chekUrl(urlString:"h://test")
    chekUrl(urlString:":// should fail")
    chekUrl(urlString:"http://-error-.invalid/")
    chekUrl(urlString:"http://.www.example.com/")
}

func chekUrl(urlString: String) {
    var result = ""
    if urlString.isUrl {
        result += "url: "
    } else {
        result += "not url: "
    }
    result += "\"\(urlString)\""
    print(result)
}

Result

enter image description here

shim
  • 9,289
  • 12
  • 69
  • 108
Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
1

Objective C

- (BOOL)validateUrlString:(NSString*)urlString
{
    if (!urlString)
    {
        return NO;
    }

    NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];

    NSRange urlStringRange = NSMakeRange(0, [urlString length]);
    NSMatchingOptions matchingOptions = 0;

    if (1 != [linkDetector numberOfMatchesInString:urlString options:matchingOptions range:urlStringRange])
    {
        return NO;
    }

    NSTextCheckingResult *checkingResult = [linkDetector firstMatchInString:urlString options:matchingOptions range:urlStringRange];

    return checkingResult.resultType == NSTextCheckingTypeLink && NSEqualRanges(checkingResult.range, urlStringRange);
}

Hope this helps!

Dharmesh Mansata
  • 4,422
  • 1
  • 27
  • 33
0

Selfishly, I would suggest using a KSURLFormatter instance to both validate input, and convert it to something NSURL can handle.

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
0

did you mean to check if what the user entered is a URL? It can be as simple as a regular expression, for example checking if the string contain www. (this is the way that yahoo messenger checks if the user status is a link or not)
Hope that help

phunehehe
  • 8,618
  • 7
  • 49
  • 79
0

I have created inherited class of UITextField which can handle all kind of validation using regex string. In this you just need to give them all the regex string in sequence and their message that you want to show when validation get failed. You can check my blog for more info, it will really help you

http://dhawaldawar.wordpress.com/2014/06/11/uitextfield-validation-ios/

Dhawal Dawar
  • 354
  • 2
  • 8
0

Extending @Anthony's answer to swift, I wrote a category on String which returns an optional NSURL. The return value is nil if the String can not be validated to be a URL.

import Foundation

// A private global detector variable which can be reused.
private let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue)

extension String {
  func URL() -> NSURL? {
    let textRange = NSMakeRange(0, self.characters.count)
    guard let URLResult = detector.firstMatchInString(self, options: [], range: textRange) else {
      return nil
    }

    // This checks that the whole string is the detected URL. In case
    // you don't have such a requirement, you can remove this code
    // and return the URL from URLResult.
    guard NSEqualRanges(URLResult.range, textRange) else {
      return nil
    }

    return NSURL(string: self)
  }
}
Ayush Goel
  • 3,134
  • 27
  • 36
0
func checkValidUrl(_ strUrl: String) -> Bool {
    let urlRegEx: String = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
    let urlTest = NSPredicate(format: "SELF MATCHES %@", urlRegEx)
    return urlTest.evaluate(with: strUrl)
}
Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
Urvish Modi
  • 1,118
  • 10
  • 11
0

My solution in Swift 5:

extension String {
    func isValidUrl() -> Bool {
        do {
            let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
            // check if the string has link inside
            return detector.numberOfMatches(in: self, options: [], range: .init( location: 0, length: utf16.count)) > 0
        } catch {
            print("Error during NSDatadetector initialization \(error)" )
        }
        return false
    }
}
Nazariy Vlizlo
  • 778
  • 7
  • 16