How to validate an url on the iPhone
Solution 1
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
}
Solution 2
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.
Solution 3
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;
}
Solution 4
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
Solution 5
use this-
NSString *urlRegEx = @"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
Thizzer
Software developer at heart. Interested in all things Tech.
Updated on July 08, 2022Comments
-
Thizzer almost 2 years
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?
-
hpique over 13 yearsI might be wrong, but I believe that regex doesn't validate urls with query strings or named anchors.
-
chris about 13 yearsYou have a small typo. Should be
... and candidateURL.host
. Nice solution. -
imnk about 13 yearsbest and most elegant solution
-
Thizzer almost 13 yearsYou could make the prefix part optional by replacing (http|https):// with ((http|https)://)* but this would allow a very wide variety of urls
-
Alex Reynolds over 12 years+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 ornil
, yielding a quick, simple yes/no answer about the validity of the URL. -
Diego Barros over 12 yearsI 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.
-
Thizzer almost 12 yearsThis solution doesn't prevent all malformed urls from being returned as nil
-
ThE uSeFuL almost 12 yearsThis only works for urls of type "webr.ly" does not work for urls with parameters like youtube.com/watch?v=mqgExtdNMBk
-
Vaibhav Saran almost 12 yearsi copied it simply for asp.net regular expression validator ;)
-
uɥƃnɐʌuop over 11 years@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.
-
Aaron Brager over 11 years@DonamiteIsTnt The URL
http://www.aol.comhttp://www.nytimes.com
passes this test. -
capikaw over 11 yearsIs there an iOS flavour of this?
-
Mike Abdullah over 11 yearsIt should work just fine on iOS. If it doesn't, fix it up and send me a pull request, or file an issue
-
denil over 11 yearsThe code will not check for malformed url. Ex: <code>afasd</code>, the url will still pass the test
-
newbcoder over 11 yearsThe 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. -
MuhammadBassio about 11 yearsperfect, the only problem is that it doesn't recognize
www.google.com/+gplusname
-
Tony over 10 yearsIf I enter URL like : "file://localhost/...", is it valid?
-
Yeung over 10 years
((http|https)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
.It should make http:// or https:// is optiional. -
Revinder over 9 yearsnot working for google.com, www.google.com and also for //www.google.com
-
Fattie over 9 yearsExtremely clever. Real engineering. {You know, I had a weird problem where if I send it the string literally "<null>", it crashes! Could never figure it out.}
-
Fattie over 9 yearsAh - it was "<null>" in the son, which apple usefully supplies as an NSNull! :O
-
bdmontz over 9 yearsUnfortunately hashtags get turned into NSURLs by this API. As an example "#hashtag" becomes an NSURL.
-
Sandy Chapman over 9 yearsI'm not sure why this has so many upvotes. This method accepts an empty string as a valid URL.
-
Yevhen Dubinin about 9 yearsI created a gist where I started adding test cases for this snipped. Fill free to add more. gist.github.com/b35097bad451c59e23b1.git
-
Vincil Bishop almost 9 yearsunfortunately it will return as valid a nil hostname as http://(null)...elegant solution but won't validate even the most basic scenarios.
-
Supertecnoboff over 8 yearsThis seems very interesting. Is it 100% bullet proof?
-
julianwyz over 8 yearsI've been using it for a while now and it seems to work fine. It also seems to play nice with the new TLDs (namecheap.com/domains/new-tlds/explore.aspx).
-
DJtiwari over 8 yearsfollowing urls are not working in my case. money.cnn.com/2015/10/19/technology/apple-app-store/…
-
newDeveloper over 8 yearsthis 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.
-
Hamza MHIRA over 8 years@DJtiwari +1 yes it's not working did you find any fix for that?
-
Legoless almost 8 yearsThis 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. -
DaNLtR almost 8 years@newDeveloper if you add http:// to tp:/fdfdfsfdsf - it passes... check -rocode- answer in the bottom - i think its the best over here.
-
Brett over 7 years@Legoless could just use a try...catch around it?
-
Krystian over 6 yearsNot sure where all the upvotes are coming from, but simple check: 123.123.123.123qwe:6001 passes this validation. Quite invalid ;)
-
AnLT over 6 years52.88.111.0/API/public/uploads/facilities/images/2585/…. Not working in my case
-
zero3nna over 6 yearsthis is not working for more complex url's or fails to get invalid url's like in the comments above shown
-
ekashking almost 6 yearsAll this goes through:
www.ailive
wwwailive.
I'm not even includingcom
or any extentions.!!! ??????? -
Michael over 3 years@Legoless Which version do you work on? This solution works well in my situation.