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 Signleteile wie cid=241
und aufteilen &avg_rating=4.82280613104
. Ich habe das mit gemacht, substringWithRange:
aber die Werte werden in zufälliger Reihenfolge zurückgegeben, so dass es durcheinander kommt. Gibt es eine Klasse, die eine einfache Analyse ermöglicht, in der Sie sie grundsätzlich in NSDictionary konvertieren können, um den Wert für einen Schlüssel lesen zu können (z. B. ValueForKey: cid
sollte zurückgeben 241
). Oder gibt es nur einen anderen einfacheren Weg, es zu analysieren, als NSMakeRange
einen Teilstring zu erhalten?
quelle
NSArray *urlComponents = [urlString componentsSeparatedByString:@"&"]; NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] initWithCapacity: urlComponents.count];
NSRange range = [keyValuePair rangeOfString:@"="]; NSString *key = [keyValuePair substringToIndex:range.location]; NSString *value = [keyValuePair substringFromIndex:range.location+1];
Ich habe dies auch unter https://stackoverflow.com/a/26406478/215748 beantwortet .
Sie können
queryItems
in verwendenURLComponents
.let url = "http://example.com?param1=value1¶m2=param2" let queryItems = URLComponents(string: url)?.queryItems let param1 = queryItems?.filter({$0.name == "param1"}).first print(param1?.value)
Alternativ können Sie der URL eine Erweiterung hinzufügen, um die Arbeit zu vereinfachen.
extension URL { var queryParameters: QueryParameters { return QueryParameters(url: self) } } class QueryParameters { let queryItems: [URLQueryItem] init(url: URL?) { queryItems = URLComponents(string: url?.absoluteString ?? "")?.queryItems ?? [] print(queryItems) } subscript(name: String) -> String? { return queryItems.first(where: { $0.name == name })?.value } }
Sie können dann über den Namen auf den Parameter zugreifen.
let url = URL(string: "http://example.com?param1=value1¶m2=param2")! print(url.queryParameters["param1"])
quelle
Ich bin etwas spät dran, aber die bisherigen Antworten haben nicht so funktioniert, 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; }
Wo
url
ist die URL, die Sie analysieren möchten? Sie haben alle Abfragezeichenfolgen imqueryStrings
veränderlichen Wörterbuch maskiert.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 } }
quelle
=
wird zum Auffüllen verwendet und erscheint=
erst am Ende, wenn es dekodiert wird. Abfrageparameter ohne Wert werden jedoch nicht unterstützt.http://example.org/?base64=ZGF0YT1bMTUyLCAyNDI2LCAyMzE1XQ==
mit dem Antwortcode . Es wirdZGF0YT1bMTUyLCAyNDI2LCAyMzE1XQ
nicht zurückkehrenZGF0YT1bMTUyLCAyNDI2LCAyMzE1XQ==
. Natürlich dekodieren einige base64-Decoder korrekt, geben jedoch beispielsweise eineNSData initWithBase64EncodedString:options:
leere Zeichenfolge ohne Auffüllen zurück=
. Daher sollten Sie vorsichtig sein, wenn Sie mit base64-Zeichenfolgen mit Antwortcode umgehen.http://example.org/?base64=ZGF0YT1bMTUyLCAyNDI2LCAyMzE1XQ==
, es wäre so,http://example.org/?base64=ZGF0YT1bMTUyLCAyNDI2LCAyMzE1XQ%3D%3D
wie der Wert URL-codiert sein sollteFü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]; }
quelle
Wenn Sie das Gleiche schnell 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 } }
quelle
Wenn Sie
NSURLComponents
die folgende prägnante Erweiterung verwenden, reicht dies ebenfalls aus:extension NSURLComponents { func getQueryStringParameter(name: String) -> String? { return (self.queryItems? as [NSURLQueryItem]) .filter({ (item) in item.name == name }).first? .value() } }
quelle
func getQueryStringParameter(name: String) -> String? { return self.queryItems?.filter({ (item) in item.name == name }).first?.value }
Seit iOS 8 können Sie Eigenschaften direkt
name
undvalue
weiter verwendenNSURLQueryItem
.Beispiel, wie eine URL analysiert und bestimmte Werte für einen Schlüssel in analysierten 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);
quelle
Swift 5
extension URL { func queryParams() -> [String:String] { let queryItems = URLComponents(url: self, resolvingAgainstBaseURL: false)?.queryItems let queryTuples: [(String, String)] = queryItems?.compactMap{ guard let value = $0.value else { return nil } return ($0.name, value) } ?? [] return Dictionary(uniqueKeysWithValues: queryTuples) } }
quelle
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]; } }
quelle
-(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 diese Funktion nur URL übergeben und Sie erhalten alle Elemente der Abfrage.
quelle
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
quelle
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"]];
quelle
So erhalten Sie Abfrageparameter als Diktat:
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 optional zurücksenden, wenn dies in Ihrem Fall bequemer ist.
quelle
Die Abfrageeigenschaft in der NSURL gibt die Abfragezeichenfolge an. Anschließend 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"];
quelle
- (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"]; }
quelle
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 } }
Laden Sie Gist herunter
quelle