90 votes

Création de paramètres de requête d'URL à partir d'objets NSDictionary en ObjectiveC

Avec tous les objets de gestion d'URL qui se trouvent dans les bibliothèques Cocoa standard (NSURL, NSMutableURL, NSMutableURLRequest, etc.), je sais que je dois négliger un moyen facile de composer une requête GET par programmation.

Actuellement, j'ajoute manuellement les " ?" suivis des paires nom-valeur jointes par "&", mais toutes mes paires nom-valeur doivent être codées manuellement pour que NSMutableURLRequest n'échoue pas complètement lorsqu'il tente de se connecter à l'URL.

J'ai l'impression que je devrais être en mesure d'utiliser une API préétablie pour cela.... existe-t-il quelque chose de prêt à l'emploi pour ajouter un NSDictionary de paramètres de requête à un NSURL ? Y a-t-il une autre façon d'aborder la question ?

6voto

Ayush Goel Points 156

Si vous utilisez déjà AFNetworking (comme ce fut le cas pour moi), vous pouvez utiliser sa classe AFHTTPRequestSerializer pour créer les NSURLRequest .

[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:@"YOUR_URL" parameters:@{PARAMS} error:nil];

Dans le cas où vous n'avez besoin que de l'URL pour votre travail, utilisez NSURLRequest.URL .

3voto

Zorayr Points 2637

Voici un exemple simple dans Swift (iOS8+) :

private let kSNStockInfoFetchRequestPath: String = "http://dev.markitondemand.com/Api/v2/Quote/json"

private func SNStockInfoFetchRequestURL(symbol:String) -> NSURL? {
  if let components = NSURLComponents(string:kSNStockInfoFetchRequestPath) {
    components.queryItems = [NSURLQueryItem(name:"symbol", value:symbol)]
    return components.URL
  }
  return nil
}

3voto

Can Points 3567

J'ai suivi la recommandation de Joel d'utiliser URLQueryItems et transformé en une extension Swift (Swift 3)

extension URL
{
    /// Creates an NSURL with url-encoded parameters.
    init?(string : String, parameters : [String : String])
    {
        guard var components = URLComponents(string: string) else { return nil }

        components.queryItems = parameters.map { return URLQueryItem(name: $0, value: $1) }

        guard let url = components.url else { return nil }

        // Kinda redundant, but we need to call init.
        self.init(string: url.absoluteString)
    }
}

(Le self.init la méthode est un peu ringarde, mais il n'y avait pas de NSURL init avec les composants)

Peut être utilisé comme

URL(string: "http://www.google.com/", parameters: ["q" : "search me"])

2voto

Chris Points 13472

J'ai une autre solution :

http://splinter.com.au/build-a-url-query-string-in-obj-c-from-a-dict

+(NSString*)urlEscape:(NSString *)unencodedString {
    NSString *s = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
        (CFStringRef)unencodedString,
        NULL,
        (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
        kCFStringEncodingUTF8);
    return [s autorelease]; // Due to the 'create rule' we own the above and must autorelease it
}

// Put a query string onto the end of a url
+(NSString*)addQueryStringToUrl:(NSString *)url params:(NSDictionary *)params {
    NSMutableString *urlWithQuerystring = [[[NSMutableString alloc] initWithString:url] autorelease];
    // Convert the params into a query string
    if (params) {
        for(id key in params) {
            NSString *sKey = [key description];
            NSString *sVal = [[params objectForKey:key] description];
            // Do we need to add ?k=v or &k=v ?
            if ([urlWithQuerystring rangeOfString:@"?"].location==NSNotFound) {
                [urlWithQuerystring appendFormat:@"?%@=%@", [Http urlEscape:sKey], [Http urlEscape:sVal]];
            } else {
                [urlWithQuerystring appendFormat:@"&%@=%@", [Http urlEscape:sKey], [Http urlEscape:sVal]];
            }
        }
    }
    return urlWithQuerystring;
}

Vous pouvez ensuite l'utiliser comme suit :

NSDictionary *params = @{@"username":@"jim", @"password":@"abc123"};

NSString *urlWithQuerystring = [self addQueryStringToUrl:@"https://myapp.com/login" params:params];

2voto

-(NSString*)encodeDictionary:(NSDictionary*)dictionary{
    NSMutableString *bodyData = [[NSMutableString alloc]init];
    int i = 0;
    for (NSString *key in dictionary.allKeys) {
        i++;
        [bodyData appendFormat:@"%@=",key];
        NSString *value = [dictionary valueForKey:key];
        NSString *newString = [value stringByReplacingOccurrencesOfString:@" " withString:@"+"];
        [bodyData appendString:newString];
        if (i < dictionary.allKeys.count) {
            [bodyData appendString:@"&"];
        }
    }
    return bodyData;
}

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