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

IOS: проанализировать URL-адрес в сегментах

Какой эффективный способ взять объект NSURL, например следующее:

foo://name/12345 

и разбить его на одну строку и одно целое без знака, где строка val - это "имя", а unsigned int - 12345?

Я предполагаю, что алгоритм включает преобразование NSURL в NSString, а затем использование некоторых компонентов NSScanner для завершения остальных?

4b9b3361

Ответ 1

NSURL имеет метод pathComponents, который возвращает массив со всеми различными компонентами пути. Это должно помочь вам получить целую часть. Чтобы получить имя, я бы использовал метод host для NSURL. Документы говорят, что он должен работать, если URL правильно отформатирован, может также дать ему попробовать то.

В общем, нет необходимости конвертировать в строку, похоже, существует множество методов для разработки компонентов URL-адреса из самого объекта NSURL.

Ответ 2

Я могу только добавить пример здесь, класс NSURL - это тот, который нужно пройти. Это не полно, но даст вам подсказку о том, как использовать NSURL:

NSString *url_ = @"foo://name.com:8080/12345;param?foo=1&baa=2#fragment";
NSURL *url = [NSURL URLWithString:url_];

NSLog(@"scheme: %@", [url scheme]); 
NSLog(@"host: %@", [url host]); 
NSLog(@"port: %@", [url port]);     
NSLog(@"path: %@", [url path]);     
NSLog(@"path components: %@", [url pathComponents]);        
NSLog(@"parameterString: %@", [url parameterString]);   
NSLog(@"query: %@", [url query]);       
NSLog(@"fragment: %@", [url fragment]);

выход:

scheme: foo
host: name.com
port: 8080
path: /12345
path components: (
    "/",
    12345
)
parameterString: param
query: foo=1&baa=2
fragment: fragment

Этот параметр Q & A NSURL parameterString с использованием ';' vs '&' также интересен в отношении URL-адресов.

Ответ 3

На самом деле есть лучший способ разобрать NSURL. Используйте NSURLComponents. Вот пример simle:

Swift:

extension URL {
    var params: [String: String]? {
        if let urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: true) {
            if let queryItems = urlComponents.queryItems {
                var params = [String: String]()
                queryItems.forEach{
                    params[$0.name] = $0.value
                }
                return params
            }
        }
        return nil
    }
}

Objective-C:

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
    NSArray *queryItems = [components queryItems];

    NSMutableDictionary *dict = [NSMutableDictionary new];

    for (NSURLQueryItem *item in queryItems)
    {
        [dict setObject:[item value] forKey:[item name]];
    }

Ответ 4

Спасибо Нику за то, что он указал мне в правильном направлении.

Я хотел сравнить URL-адреса файлов, но имел проблемы с дополнительными косой чертой, делающей isEqualString бесполезным. Вы можете использовать мой пример ниже для сравнения двух URL-адресов, сначала деконструируя их, а затем сравнивая части друг с другом.

- (BOOL) isURLMatch:(NSString*) url1 url2:(NSString*) url2
{
    NSURL *u1 = [NSURL URLWithString:url1];
    NSURL *u2 = [NSURL URLWithString:url2];

    if (![[u1 scheme] isEqualToString:[u2 scheme]]) return NO;
    if (![[u1 host] isEqualToString:[u2 host]]) return NO;
    if (![[url1 pathComponents] isEqualToArray:[url2 pathComponents]]) return NO;

    //check some properties if not nil as isEqualSting fails when comparing them
    if ([u1 port] && [u2 port])
    {
        if (![[u1 port] isEqualToNumber:[u2 port]]) return NO;
    }

    if ([u1 query] && [u2 query])
    {
        if (![[u1 query] isEqualToString:[u2 query]]) return NO;
    }
    return YES;
}