Подтвердить что ты не робот

Разобрать путь NSURL и запрос на iOS

Существуют ли какие-либо стандартные объекты или функции для анализа компонентов NSURL? Ясно, что я мог бы написать один, но зачем изобретать велосипед?

[NSURL path] возвращает NSString как "argX=x&argY=y&argZ=z" То, что я предпочел бы получить обратно словарь заселена {@"argX" => @"x", @"argY" => @"y", @"argZ" = @"z"}

Для пути, который возвращает строку типа "/partA/partB/partC", я бы предпочел получить массив со структурой {[0] => @"partA", [1] => @"partB", [2] => @"partC"}

Я понимаю, что это довольно специфический вопрос, но кажется, что многие люди захотят этого.

Это для iOS! Очевидно, NSURL имеет разные функции в macOS.

4b9b3361

Ответ 1

Возможно, вы захотите посмотреть pathComponents, который возвращает массив компонентов URL-адреса. Получите дополнительную информацию здесь.

Ответ 2

Хорошо, я получил antsy и написал решение для расширения NSString через категории. Я еще не тестировал это, но если вы хотите его использовать, перейдите к нему.

@interface NSString (ParseCategory)
- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue;
@end

@implementation NSString (ParseCategory)

- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue {
    // Explode based on outter glue
    NSArray *firstExplode = [self componentsSeparatedByString:outterGlue];
    NSArray *secondExplode;

    // Explode based on inner glue
    NSInteger count = [firstExplode count];
    NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithCapacity:count];
    for (NSInteger i = 0; i < count; i++) {
        secondExplode = [(NSString *)[firstExplode objectAtIndex:i] componentsSeparatedByString:innerGlue];
        if ([secondExplode count] == 2) {
            [returnDictionary setObject:[secondExplode objectAtIndex:1] forKey:[secondExplode objectAtIndex:0]];
        }
    }

    return returnDictionary;
}

@end

Он называется так:

NSMutableDictionary *parsedQuery = [[myNSURL query] explodeToDictionaryInnerGlue:@"=" [email protected]"&"]

Для разбора части пути NSURL (например, @ "/partA/partB/partC" ) просто вызовите это:

NSArray *parsedPath = [[nyNSURL path] componentsSeperatedByString:@"/"];

Помните, что parsedPath [0] будет пустой строкой из-за ведущего /!

РЕДАКТИРОВАТЬ. Это расширение категории для NSURL для вашего удовольствия от использования. Он удаляет исходный "/", поэтому у вас нет нулевого индекса 0.

@implementation NSURL (ParseCategory)

- (NSArray *)pathArray {
    // Create a character set for the slash character
    NSRange slashRange;
    slashRange.location = (unsigned int)'/';
    slashRange.length = 1;
    NSCharacterSet *slashSet = [NSCharacterSet characterSetWithRange:slashRange];

    // Get path with leading (and trailing) slashes removed
    NSString *path = [[self path] stringByTrimmingCharactersInSet:slashSet];

    return [path componentsSeparatedByCharactersInSet:slashSet];
}

- (NSDictionary *)queryDictionary {
    NSDictionary *returnDictionary = [[[[self query] explodeToDictionaryInnerGlue:@"=" outterGlue:@"&"] copy] autorelease];
    return returnDictionary;
}

@end

Ответ 3

Sam Soffes создал хорошо сохранившуюся категорию для NSURL/NSDictionary. Его можно найти здесь: https://github.com/samsoffes/sstoolkit/

Ответ 4

Вот что я использую для синтаксического анализа строки запроса

// Parse the individual parameters
// parameters = @"hello=world&foo=bar";
NSMutableDictionary *dictParameters = [[NSMutableDictionary alloc] init];
NSArray *arrParameters = [parameters componentsSeparatedByString:@"&"];
for (int i = 0; i < [arrParameters count]; i++) {
    NSArray *arrKeyValue = [[arrParameters objectAtIndex:i] componentsSeparatedByString:@"="];
    if ([arrKeyValue count] >= 2) {
        NSMutableString *strKey = [NSMutableString stringWithCapacity:0];
        [strKey setString:[[[arrKeyValue objectAtIndex:0] lowercaseString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
        NSMutableString *strValue   = [NSMutableString stringWithCapacity:0];
        [strValue setString:[[[arrKeyValue objectAtIndex:1]  stringByReplacingOccurrencesOfString:@"+" withString:@" "] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
        if (strKey.length > 0) [dictParameters setObject:strValue forKey:strKey];
    }
}
NSLog(@"Parameters: %@", dictParameters);

Ответ 5

Если вы решите написать один (я не уверен, что существуют существующие методы получения желаемых компонентов), вы можете использовать NSString componentsSeparatedByString.

Ответ 6

Представлено в iOS 8 и OS X 10.10 NSURLQueryItem, которое может использоваться для создания запросов. Из документов на NSURLQueryItem:

Объект NSURLQueryItem представляет собой единую пару имя/значение для элемента в части запроса URL-адреса. Вы используете элементы запроса с свойством queryItems объекта NSURLComponents.

Вы можете получить элементы запроса из URL, сначала создав NSURLComponents:

NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com?q=ios&count=10"];
NSURLComponents *components = [NSURLComponents componentsWithURL:url 
                                               resolvingAgainstBaseURL:YES];
for (NSURLQueryItem *item in components.queryItems) {
    NSLog(@"name: %@, value: %@", item.name, item.value);
}
// name: q, value: ios
// name: count, value: 10

Обратите внимание, что они возвращают значение для -queryItems - это массив, а не словарь. Это связано с тем, что допустимый URL-адрес является следующим. Обратите внимание на две идентичные "клавиши", foo.

http://google.com?foo=bar&foo=baz

Чтобы создать URL-адрес через элементы запроса, используйте назначенный инициализатор queryItemWithName:value:, а затем добавьте их в NSURLComponents, чтобы сгенерировать NSURL. Например:

NSString *urlString = @"http://stackoverflow.com";
NSURLComponents *components = [NSURLComponents componentsWithString:urlString];
NSURLQueryItem *search = [NSURLQueryItem queryItemWithName:@"q" value:@"ios"];
NSURLQueryItem *count = [NSURLQueryItem queryItemWithName:@"count" value:@"10"];
components.queryItems = @[ search, count ];
NSURL *url = components.URL; // http://stackoverflow.com?q=ios&count=10

Обратите внимание, что знак вопроса и амперсанд автоматически обрабатываются. Создание NSURL из словаря параметров так же просто, как:

NSDictionary *queryDictionary = @{ @"q": @"ios", @"count": @"10" };
NSMutableArray *queryItems = [NSMutableArray array];
for (NSString *key in queryDictionary) {
    NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:key 
                                                       value:queryDictionary[key]]; 
    [queryItems addObject:item];
}
components.queryItems = queryItems;

Я также написал сообщение в блоге с более подробной информацией, Создание NSURL с помощью NSURLQueryItems.