it-swarm.com.de

Bester Weg, URL-Zeichenfolge zu analysieren, um Werte für Schlüssel zu erhalten?

Ich muss eine URL-Zeichenfolge wie diese analysieren:

&ad_eurl=http://www.youtube.com/video/4bL4FI1Gz6s&hl=it_IT&iv_logging_level=3&ad_flags=0&endscreen_module=http://s.ytimg.com/yt/swfbin/endscreen-vfl6o3XZn.swf&cid=241&cust_gender=1&avg_rating=4.82280613104

Ich muss den NSString in die Signle-Teile wie cid=241 und &avg_rating=4.82280613104 aufteilen. Ich habe das mit substringWithRange: gemacht, aber die Werte werden in einer zufälligen Reihenfolge zurückgegeben, so dass es durcheinander kommt. Gibt es eine Klasse, die eine einfache Analyse ermöglicht, bei der Sie sie grundsätzlich in NSDictionary konvertieren können, um den Wert eines Schlüssels lesen zu können (beispielsweise ValueForKey: cid sollte 241 zurückgeben) Oder gibt es eine einfachere Methode zum Parsen als NSMakeRange, um einen Teilstring zu erhalten?

67
JonasG

edit (Juni 2018): diese Antwort ist besser . Apple hat NSURLComponents in iOS 7 hinzugefügt.

Ich würde ein Wörterbuch erstellen und ein Array mit den Schlüssel/Wert-Paaren erhalten

NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];
NSArray *urlComponents = [urlString componentsSeparatedByString:@"&"];

Dann füllen Sie das Wörterbuch auf:

for (NSString *keyValuePair in urlComponents)
{
    NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
    NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
    NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];

    [queryStringDictionary setObject:value forKey:key];
}

Sie können dann mit abfragen

[queryStringDictionary objectForKey:@"ad_eurl"];

Dies ist nicht getestet, und Sie sollten wahrscheinlich weitere Fehlertests durchführen.

112
Thomas Joulin

Ich habe dies auch unter https://stackoverflow.com/a/26406478/215748 beantwortet. 

Sie können queryItems in URLComponents verwenden.

Wenn Sie den Wert dieser Eigenschaft abrufen, analysiert die NSURLComponents-Klasse die Abfragezeichenfolge und gibt ein Array von NSURLQueryItem-Objekten zurück, von denen jedes ein einzelnes Schlüsselwertpaar in der Reihenfolge darstellt, in der sie in der ursprünglichen Abfragezeichenfolge angezeigt werden.

Swift 3

let url = "http://example.com?param1=value1&param2=param2"
let queryItems = URLComponents(string: url)?.queryItems
let param1 = queryItems?.filter({$0.name == "param1"}).first
print(param1?.value)

Schnell 2.3

Verwenden Sie NSURLComponents anstelle von URLComponents.

Ziel c

Verwenden Sie NSURLComponents .

NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url 
                                            resolvingAgainstBaseURL:NO];
NSArray *queryItems = urlComponents.queryItems;
NSString *param1 = [self valueForKey:@"param1" 
                  fromQueryItems:queryItems];
NSLog(@"%@", param1);
…

- (NSString *)valueForKey:(NSString *)key
           fromQueryItems:(NSArray *)queryItems
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
    NSURLQueryItem *queryItem = [[queryItems 
                                  filteredArrayUsingPredicate:predicate]
                                 firstObject];
    return queryItem.value;
}
144
Onato

Ich bin etwas spät dran, aber die Antworten, die bis jetzt gegeben wurden, funktionierten nicht so wie ich es brauchte. Sie können dieses Code-Snippet verwenden: 

NSMutableDictionary *queryStrings = [[NSMutableDictionary alloc] init];
for (NSString *qs in [url.query componentsSeparatedByString:@"&"]) {
    // Get the parameter name
    NSString *key = [[qs componentsSeparatedByString:@"="] objectAtIndex:0];
    // Get the parameter value
    NSString *value = [[qs componentsSeparatedByString:@"="] objectAtIndex:1];
    value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
    value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    queryStrings[key] = value;
}

Dabei ist url die URL, die Sie analysieren möchten. Sie haben alle Abfragezeichenfolgen mit Escapezeichen im änderbaren Wörterbuch queryStrings.

EDIT: Swift-Version:

var queryStrings = [String: String]()
if let query = url.query {
    for qs in query.componentsSeparatedByString("&") {
        // Get the parameter name
        let key = qs.componentsSeparatedByString("=")[0]
        // Get the parameter value
        var value = qs.componentsSeparatedByString("=")[1]
        value = value.stringByReplacingOccurrencesOfString("+", withString: " ")
        value = value.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!

        queryStrings[key] = value
    }
}
45

Wenn Sie dasselbe in Swift tun möchten, können Sie eine Erweiterung verwenden.

extension NSURL {
    func queryDictionary() -> [String:String] {
        let components = self.query?.componentsSeparatedByString("&")
        var dictionary = [String:String]()

        for pairs in components ?? [] {
            let pair = pairs.componentsSeparatedByString("=")
            if pair.count == 2 {
                dictionary[pair[0]] = pair[1]
            }
        }

        return dictionary
    }
}
6
apouche

Für iOS8 und höher mit NSURLComponents:

+(NSDictionary<NSString *, NSString *> *)queryParametersFromURL:(NSURL *)url {
    NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
    NSMutableDictionary<NSString *, NSString *> *queryParams = [NSMutableDictionary<NSString *, NSString *> new];
    for (NSURLQueryItem *queryItem in [urlComponents queryItems]) {
        if (queryItem.value == nil) {
            continue;
        }
        [queryParams setObject:queryItem.value forKey:queryItem.name];
    }
    return queryParams;
}

Für iOS 8 unten:

+(NSDictionary<NSString *, NSString *> *)queryParametersFromURL:(NSURL *)url    
    NSMutableDictionary<NSString *, NSString *> * parameters = [NSMutableDictionary<NSString *, NSString *> new];
    [self enumerateKeyValuePairsFromQueryString:url.query completionblock:^(NSString *key, NSString *value) {
        parameters[key] = value;
    }];
    return parameters.copy;
}

- (void)enumerateKeyValuePairsFromQueryString:(NSString *)queryString completionBlock:(void (^) (NSString *key, NSString *value))block {
    if (queryString.length == 0) {
        return;
    }
    NSArray *keyValuePairs = [queryString componentsSeparatedByString:@"&"];
    for (NSString *pair in keyValuePairs) {
        NSRange range = [pair rangeOfString:@"="];
        NSString *key = nil;
        NSString *value = nil;

        if (range.location == NSNotFound) {
            key = pair;
            value = @"";
        }
        else {
            key = [pair substringToIndex:range.location];
            value = [pair substringFromIndex:(range.location + range.length)];
        }

        key = [self decodedStringFromString:key];
        key = key ?: @"";

        value = [self decodedStringFromString:value];
        value = value ?: @"";

        block(key, value);
    }
}

+ (NSString *)decodedStringFromString:(NSString *)string {
    NSString *input = shouldDecodePlusSymbols ? [string stringByReplacingOccurrencesOfString:@"+" withString:@" " options:NSLiteralSearch range:NSMakeRange(0, string.length)] : string;
    return [input stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
6
Yatheesha B L

Wenn Sie NSURLComponents verwenden, führt die folgende kurze Erweiterung auch den Trick aus:

extension NSURLComponents {

    func getQueryStringParameter(name: String) -> String? {
        return (self.queryItems? as [NSURLQueryItem])
            .filter({ (item) in item.name == name }).first?
            .value()
    }

}
4
Gilles De Mey

Dieser Code funktioniert in drei Fällen 

1. http://www.youtube.com/watch?v=VWsl7C-y7EI&feature=youtu.be 2. http://youtu.be/lOvcFqQyaDY
3. http://www.youtube.com/watch?v=VWsl7C-y7EI

NSArray *arr = [youtubeurl componentsSeparatedByString:@"v="];
 NSString *youtubeID;
if([arr count]>0)
{
    if([arr count]==1){
        youtubeID= [[youtubeurl componentsSeparatedByString:@"/"] lastObject];

    }
    else{
        NSArray *urlComponents = [[arr objectAtIndex:1] componentsSeparatedByString:@"&"];
        youtubeID=[urlComponents objectAtIndex:0];
    }
}
3
Rinju Jain
-(NSArray *)getDataOfQueryString:(NSString *)url{
    NSArray *strURLParse = [url componentsSeparatedByString:@"?"];
    NSMutableArray *arrQueryStringData = [[NSMutableArray alloc] init];
    if ([strURLParse count] < 2) {
        return arrQueryStringData;
    }
    NSArray *arrQueryString = [[strURLParse objectAtIndex:1] componentsSeparatedByString:@"&"];

    for (int i=0; i < [arrQueryString count]; i++) {
        NSMutableDictionary *dicQueryStringElement = [[NSMutableDictionary alloc]init];
        NSArray *arrElement = [[arrQueryString objectAtIndex:i] componentsSeparatedByString:@"="];
        if ([arrElement count] == 2) {
            [dicQueryStringElement setObject:[arrElement objectAtIndex:1] forKey:[arrElement objectAtIndex:0]];
        }
        [arrQueryStringData addObject:dicQueryStringElement];
    }

    return arrQueryStringData; 
}

Sie können mit dieser Funktion nur die URL übergeben und Sie erhalten alle Elemente des Querstrings.

3
Crazy Developer

Seit iOS 8 können Sie die Eigenschaften name und value direkt für NSURLQueryItem verwenden.

Beispiel, wie die URL analysiert und bestimmte Werte für einen Schlüssel in geparsten Paaren abgerufen werden.

NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:@"someURL" resolvingAgainstBaseURL:false];
NSArray *queryItems = urlComponents.queryItems;
NSMutableArray *someIDs = [NSMutableArray new];
for (NSURLQueryItem *item in queryItems) {
    if ([item.name isEqualToString:@"someKey"]) {
        [someIDs addObject:item.value];
    }
}
NSLog(@"%@", someIDs);
2
Jakub Truhlář

Als volle Funktion:

+ (NSString *)getQueryComponentWithName:(NSString *)name  fromURL:(NSURL *)url{

NSString *component = nil;
if (url) {
    NSString *query = url.query;

    NSMutableDictionary *queryStringDictionary = [NSMutableDictionary dictionary];
    NSArray *urlComponents = [query componentsSeparatedByString:@"&"];

    for (NSString *keyValuePair in urlComponents){

        NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
        NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
        NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];

        [queryStringDictionary setObject:value forKey:key];
    }

    component = [queryStringDictionary objectForKey:name];
}

return component;
}
[self getQueryComponentWithName:@"example" fromURL:[NSURL URLWithString:@"https://google.es/?example=test"]];
2

Eine späte Lösung hierfür in Form einer Swift 3-Erweiterung auf URL

extension URL {

  func value(for paramater: String) -> String? {

    let queryItems = URLComponents(string: self.absoluteString)?.queryItems
    let queryItem = queryItems?.filter({$0.name == paramater}).first
    let value = queryItem?.value

    return value
  }

}

Kern

2
Damo

Die Query-Eigenschaft in der NSURL gibt die Abfragezeichenfolge an. Dann können Sie die Abfragezeichenfolge mit componentsSeparatedByString analysieren

    NSArray *parameters = [[url query] componentsSeparatedByString:@"&"];

    NSMutableDictionary *keyValuePairs = [NSMutableDictionary dictionary];

    for (NSString *eachParam in parameters)
    {
        NSArray *QryParts = [eachParam componentsSeparatedByString:@"="];
        if ( [QryParts count] == 2 )
        {
            keyValuePairs[QryParts[0]] = QryParts[1];
        }
        else
        {
            keyValuePairs[QryParts[0]] = QryParts[0];
        }
    }

NSString * name = [keyValuePairs valueForKey:@"name"];
NSString * username = [keyValuePairs valueForKey:@"username"];
0
Joe M

Ein Swift-2-Ansatz:

extension NSURL {

  var queryDictionary: [String: String] {
    var queryDictionary = [String: String]()
    guard let components = NSURLComponents(URL: self, resolvingAgainstBaseURL: false), queryItems = components.queryItems else { return queryDictionary }
    queryItems.forEach { queryDictionary[$0.name] = $0.value }
    return queryDictionary
  }

}

Gist herunterladen

0
Scott Gardner

Abfrageparameter als Diktat abrufen:

extension URL {
    var parameters: [String: String] {
        var parameters = [String: String]()
        if let urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: false),
            let queryItems = urlComponents.queryItems {
            for queryItem in queryItems where queryItem.value != nil {
                parameters[queryItem.name] = queryItem.value
            }
        }
        return parameters
    }
}

oder zurückgeben Optional, wenn dies in Ihrem Fall bequemer ist.

0
- (NSString *)getLoginTokenFromUrl:(NSString *)urlString {
    NSURL *url = [NSURL URLWithString:urlString];
    NSArray *queryStrings = [url.query componentsSeparatedByString:@"&"];

    NSMutableDictionary *queryParams = [[NSMutableDictionary alloc] init];
    for (NSString *qs in queryStrings) {
        // Get the parameter name
        NSArray *components = [qs componentsSeparatedByString:@"="];
        NSString *key = [components objectAtIndex:0];

        // Get the parameter value
        NSString *value;
        if (components.count > 1) {
            value = [components objectAtIndex:1];
        }
        else {
            value = @"";
        }
        value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
        value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        queryParams[key] = value;
    }

    return [queryParams objectForKey:@"login_token"];
}
0