NSURL извлекает единственное значение для ключа в строке параметра

StackOverflow https://stackoverflow.com/questions/2225814

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть NSURL:

Серверный вызов?x=a & y = b &z =c

Каков самый быстрый и эффективный способ получить значение y?

Спасибо

Это было полезно?

Решение

Обновить:

Похоже, что с 2010 года, когда это было написано, Apple выпустила набор инструментов для этой цели.Пожалуйста, ознакомьтесь с ответами на эти вопросы ниже.

Решение старой школы:

Ну , я знаю , ты сказал "самый быстрый способ" но после того , как я начал проводить тест с NSScanner Я просто не мог остановиться.И хотя это не самый короткий путь, он, несомненно, удобен, если вы планируете часто использовать эту функцию.Я создал URLParser класс, который получает эти переменные, используя NSScanner.Использование является простым, поскольку:

URLParser *parser = [[[URLParser alloc] initWithURLString:@"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
NSString *y = [parser valueForVariable:@"y"];
NSLog(@"%@", y); //b
NSString *a = [parser valueForVariable:@"a"];
NSLog(@"%@", a); //(null)
NSString *flash = [parser valueForVariable:@"flash"];
NSLog(@"%@", flash); //yes

И класс, который это делает, следующий (* исходные файлы внизу сообщения):

URLParser.h

@interface URLParser : NSObject {
    NSArray *variables;
}

@property (nonatomic, retain) NSArray *variables;

- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

URLParser.m

@implementation URLParser
@synthesize variables;

- (id) initWithURLString:(NSString *)url{
    self = [super init];
    if (self != nil) {
        NSString *string = url;
        NSScanner *scanner = [NSScanner scannerWithString:string];
        [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
        NSString *tempString;
        NSMutableArray *vars = [NSMutableArray new];
        [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
        while ([scanner scanUpToString:@"&" intoString:&tempString]) {
            [vars addObject:[tempString copy]];
        }
        self.variables = vars;
        [vars release];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    for (NSString *var in self.variables) {
        if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:@"="]]) {
            NSString *varValue = [var substringFromIndex:[varName length]+1];
            return varValue;
        }
    }
    return nil;
}

- (void) dealloc{
    self.variables = nil;
    [super dealloc];
}

@end

* если вам не нравится копировать и вставлять, вы можете просто загрузить исходные файлы - я сделал краткий пост в блоге об этом здесь.

Другие советы

Здесь так много пользовательских парсеров URL, помните Компоненты NSURL это твой друг!

Вот пример, в котором я извлекаю параметр в кодировке URL для "страницы".

Быстрый

let myURL = "www.something.com?page=2"

var pageNumber : Int?
if let queryItems = NSURLComponents(string: myURL)?.queryItems {
    for item in queryItems {
        if item.name == "page" {
           if let itemValue = item.value {
               pageNumber = Int(itemValue)
           }
        }
    }
}
print("Found page number: \(pageNumber)")

Цель-C

NSString *myURL = @"www.something.com?page=2";
NSURLComponents *components = [NSURLComponents componentsWithString:myURL];
NSNumber *page = nil;
for(NSURLQueryItem *item in components.queryItems)
{
    if([item.name isEqualToString:@"page"])
        page = [NSNumber numberWithInteger:item.value.integerValue];
}

"Зачем изобретать велосипед!" - Кто-то умный

Я почти уверен, что вы должны разобрать это сами.Впрочем, это не так уж плохо:

NSString * q = [myURL query];
NSArray * pairs = [q componentsSeparatedByString:@"&"];
NSMutableDictionary * kvPairs = [NSMutableDictionary dictionary];
for (NSString * pair in pairs) {
  NSArray * bits = [pair componentsSeparatedByString:@"="];
  NSString * key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  NSString * value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  [kvPairs setObject:value forKey:key];
}

NSLog(@"y = %@", [kvPairs objectForKey:@"y"]);

В Swift вы можете использовать NSURLComponents для разбора строки запроса NSURL в [AnyObject].

Затем вы можете создать из него словарь (или получить доступ к элементам напрямую), чтобы получить доступ к парам ключ / значение.В качестве примера это то, что я использую для анализа URL переменной NSURL:

let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
let items = urlComponents?.queryItems as [NSURLQueryItem]
var dict = NSMutableDictionary()
for item in items{
    dict.setValue(item.value, forKey: item.name)
}
println(dict["x"])

Я использовал эту Категорию: https://github.com/carlj/NSURL-Parameters.

Он маленький и простой в использовании:

#import "NSURL+Parameters.h"
...
NSURL *url = [NSURL URLWithString:@"http://foo.bar.com?paramA=valueA&paramB=valueB"];
NSString *paramA = url[@"paramA"];
NSString *paramB = url[@"paramB"];

Вы можете использовать Google Toolbox для Mac.Он добавляет функцию в NSString для преобразования строки запроса в словарь.

http://code.google.com/p/google-toolbox-for-mac/

Это работает как заклинание

        NSDictionary * d = [NSDictionary gtm_dictionaryWithHttpArgumentsString:[[request URL] query]];

Вот расширение Swift 2.0, которое обеспечивает простой доступ к параметрам:

extension NSURL {
    var params: [String: String] {
        get {
            let urlComponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)
            var items = [String: String]()
            for item in urlComponents?.queryItems ?? [] {
                items[item.name] = item.value ?? ""
            }
            return items
        }
    }
} 

Пример использования:

let url = NSURL(string: "http://google.com?test=dolphins")
if let testParam = url.params["test"] {
    print("testParam: \(testParam)")
}

Я написал простую категорию для расширения NSString / NSURL, которая позволяет извлекать параметры запроса URL по отдельности или в виде словаря пар ключ / значение:

https://github.com/nicklockwood/RequestUtils

Я сделал это, используя метод категории, основанный на решении @Dimitris

#import "NSURL+DictionaryValue.h"

@implementation NSURL (DictionaryValue)
-(NSDictionary *)dictionaryValue
{
NSString *string =  [[self.absoluteString stringByReplacingOccurrencesOfString:@"+" withString:@" "]
                     stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];

NSString *temp;
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:@"&" intoString:&temp]) 
{
    NSArray *parts = [temp componentsSeparatedByString:@"="];
    if([parts count] == 2)
    {
        [dict setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
    }
}

return dict;
}
@end

Ты можешь сделать это легко :

- (NSMutableDictionary *) getUrlParameters:(NSURL *) url
{
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSString *tmpKey = [url query];
    for (NSString *param in [[url query] componentsSeparatedByString:@"="])
    {
        if ([tmpKey rangeOfString:param].location == NSNotFound)
        {
            [params setValue:param forKey:tmpKey];
            tmpKey = nil;
        }
        tmpKey = param;
    }
    [tmpKey release];

    return params;
}

Это возвращает Словарь, подобный этому :Ключ = значение

Я немного отредактировал код Димитриса для лучшего управления памятью и эффективности.Кроме того, это работает в ARC.

URLParser.h

@interface URLParser : NSObject

- (void)setURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

URLParser.m

#import "URLParser.h"

@implementation URLParser {
    NSMutableDictionary *_variablesDict;
}

- (void)setURLString:(NSString *)url {
    [_variablesDict removeAllObjects];

    NSString *string = url;
    NSScanner *scanner = [NSScanner scannerWithString:string];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
    NSString *tempString;

    [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
    while ([scanner scanUpToString:@"&" intoString:&tempString]) {
        NSString *dataString = [tempString copy];
        NSArray *sepStrings = [dataString componentsSeparatedByString:@"="];
        if ([sepStrings count] == 2) {
            [_variablesDict setValue:sepStrings[1] forKeyPath:sepStrings[0]];
        }
    }
}

- (id)init
{
    self = [super init];
    if (self) {
        _variablesDict = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    NSString *val = [_variablesDict valueForKeyPath:varName];
    return val;
    return nil;
}

-(NSString *)description {
    return [NSString stringWithFormat:@"Current Variables: %@", _variablesDict];
}

@end

Все текущие ответы зависят от конкретной версии или являются излишне расточительными.Зачем создавать словарь, если вам нужно только одно значение?

Вот такой простой ответ, который поддерживает все версии iOS:

- (NSString *)getQueryParam:(NSString *)name  fromURL:(NSURL *)url
{
    if (url)
    {
        NSArray *urlComponents = [url.query componentsSeparatedByString:@"&"];
        for (NSString *keyValuePair in urlComponents)
        {
            NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
            NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];

            if ([key isEqualToString:name])
            {
                return [[pairComponents lastObject] stringByRemovingPercentEncoding];
            }
        }
    }
    return nil;
}

Самый быстрый - это:

NSString* x = [url valueForQueryParameterKey:@"x"];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top