90 votes

Comment valider une URL sur l'iPhone

Dans une application iPhone que je développe, il existe un paramètre dans lequel vous pouvez entrer une URL. En raison de la forme et de la fonction, cette URL doit être validée en ligne et hors ligne.

Jusqu'à présent, je n'ai pas trouvé de méthode pour valider l'URL, donc la question est:

Comment valider une entrée d'URL sur l'iPhone (Objective-C) en ligne et hors ligne?

239voto

Vincent Guerci Points 8619

Pourquoi ne pas plutôt se contenter Foundation.framework?

Qui fait le travail et ne nécessite pas d' 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)
}

Selon la documentation d'Apple :

URLWithString: Crée et renvoie une NSURL objet initialisé avec une à condition de chaîne.

+ (id)URLWithString:(NSString *)URLString

Paramètres

URLString : La chaîne d'initialiser le NSURL objet. Doit être conforme à la RFC 2396. Cette méthode d'analyse URLString selon Rfc 1738 et 1808.

Valeur De Retour

Un NSURL objet initialisé avec URLString. Si la chaîne a été mal formé, retourne zéro.

100voto

lefakir Points 1637

Grâce à ce post , vous pouvez éviter d'utiliser RegexKit. Voici ma solution (fonctionne pour le développement iphone avec 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];
}
 

32voto

Anthony Points 153

Au lieu d'écrire vos propres expressions régulières, comptent sur Apple. J'ai été en utilisant une catégorie sur NSString qui utilise NSDataDetector pour tester la présence d'un lien au sein d'une chaîne. Si la plage du lien trouvé par NSDataDetector est égale à la longueur de l'ensemble de la chaîne, alors que c'est une URL valide.

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

26voto

Gabriel.Massana Points 2096

Ma solution avec 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)
}
 

Pour le 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")
 

Résultats:

 false
false
false
true
false
false
true
true
false
false
false
 

16voto

andrey Points 414

Si vous voulez éviter d'utiliser des expressions régulières, vous pouvez essayer l'API native:

 - (BOOL)isValidUrl:(NSString *)urlString{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    return [NSURLConnection canHandleRequest:request];
 } 
 

Exécutez quelques tests:

 - (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"];
    [self testUrl:@"http://google.de/search?q=foobar"];
}
 

Sortie:

 INVALID: google
INVALID: google.de
INVALID: www.google.de
VALID: http://www.google.de
VALID: http://google.de
VALID: http://google.de/search?q=foobar
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X