2009-12-27 43 views
12

Có bất kỳ đối tượng hoặc hàm chuẩn nào để phân tích cú pháp thành phần của NSURL không? Rõ ràng tôi có thể viết một, nhưng tại sao lại phát minh ra bánh xe?Phân tích đường dẫn NSURL và truy vấn (iphoneOS)

[NSURL path] sẽ trả về một NSString như "argX=x&argY=y&argZ=z" Những gì tôi thà có được trở lại là một cuốn từ điển dân cư với {@"argX" => @"x", @"argY" => @"y", @"argZ" = @"z"}

Đối với con đường, mà trả về một chuỗi như "/ Parta/partB/partC", tôi thà có được một mảng với cấu trúc {[0] => @"partA", [1] => @"partB", [2] => @"partC"}

tôi nhận ra điều này là yêu cầu một khá cụ thể, nhưng nó có vẻ như một cái gì đó có rất nhiều người muốn ...

EDIT - Đây là cho iphoneOS! Rõ ràng NSURL có các chức năng khác nhau trên Mac OS

+0

Câu hỏi hay. Bạn có nghĩa là: Nếu URL là "/ partA/partB/partC", bạn muốn "0 => partA, 1 => partB, 2 => partC". Nếu URL là "/ foo? PartA = A & partB = B" bạn muốn "partA => A, partB => B". Nếu URL là "/ partA/partB/partC? Foo = bar & ooga = booga" thì sao? Trong một ví dụ, thông tin quan trọng cần thiết để xác định thực thể được đề cập đang được chuyển trong chuỗi truy vấn ... trong ví dụ khác, thông tin nhận dạng được chuyển theo kiểu còn lại trong chính đường dẫn. –

+0

Tôi muốn phân tích đường dẫn và truy vấn một cách riêng biệt. Nó không nên là một hàm kết hợp hai nhiệm vụ đó. Xem mã tôi đã đăng bên dưới để làm rõ. Nếu ai đó trả lời với một triển khai hiện tại, tôi sẽ rất vui khi vẫn chấp nhận điều đó. – DougW

+0

Một điều cần lưu ý là đây là chuỗi truy vấn hoàn toàn hợp lệ: "x = 1 & x = 0 & x = foo", vì vậy một NSDictionary có thể không phải là biểu diễn tốt nhất (trừ khi bạn đang sử dụng mảng làm giá trị). – n8gray

Trả lời

9

Bạn có thể muốn xem pathComponents trả về một mảng các thành phần của URL. Xem thêm thông tin here.

+0

Tôi không tin rằng điều này có sẵn trên phiên bản iphone của SDK. Tôi nên làm rõ rằng tôi đang làm việc trên hệ điều hành iPhone. – DougW

+2

[NSString pathComponents] có sẵn trong cả API Cocoa và Cocoa Touch. Trên iPhone, bạn có thể bắt chước [NSURL pathComponents] của OS X 10.6 với [[NSURL path] pathComponents]. –

+0

Ah hoàn hảo, đó là những gì tôi đang tìm kiếm, cho phần đường dẫn ít nhất! – DougW

2

Nếu bạn quyết định viết một (Tôi không chắc chắn có các phương pháp nhận các thành phần bạn muốn), bạn có thể muốn sử dụng số componentsSeparatedByString của NSString.

+0

Cảm ơn, đã cứu tôi một chút công việc! – DougW

12

Được rồi, tôi bị phản đối và viết giải pháp để mở rộng NSString thông qua Danh mục. Tôi chưa thử nghiệm này, nhưng nếu bạn muốn sử dụng nó, đi cho nó.

@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 

Nó được gọi là như thế này:

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

Đối với phân tích phần đường dẫn của NSURL (tức là @ "/ Parta/partB/partC"), chỉ cần gọi này:

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

Lưu ý rằng phân tích cú phápPath [0] sẽ là một chuỗi rỗng vì hàng đầu /!

EDIT - Đây là tiện ích mở rộng danh mục cho NSURL cho niềm vui sử dụng của bạn. Nó bỏ dấu "/" ban đầu để bạn không có chỉ mục 0 trống.

@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 
+0

Không chắc tại sao một người nào đó đã bỏ phiếu này ... điều đó sẽ dạy tôi chia sẻ mã tôi đoán? Tôi sẽ không thực sự phiền nếu bạn để lại một bình luận, nhưng tôi sẽ chỉ cho rằng bạn là một con troll ngẫu nhiên. Hi troll. – DougW

+4

Cảm ơn, điều này làm việc tốt cho tôi.Lưu ý rằng bạn có thể cần phải giải mã URL các giá trị chuỗi truy vấn riêng lẻ của bạn. Tôi đang sử dụng mã sau đây cho điều này, trước tiên phải chăm sóc phần trăm thoát, sau đó để thay thế "+" với không gian, mà người đầu tiên tiếc là không làm: [[value stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding] stringByReplacingOccurrencesOfString: @ "+ "withString: @" "] –

+0

Rất hoan nghênh. Và vâng, tôi đã để lại các vấn đề về giải mã/giải mã từ các chức năng này. – DougW

11

Sam Soffes được tạo duy trì tốt Danh mục cho NSURL/NSDictionary. Nó có thể được tìm thấy ở đây: https://github.com/samsoffes/sstoolkit/

+0

tìm tốt. siêu hữu ích. cảm ơn người đàn ông. – courtsimas

+0

thư viện siêu tuyệt vời, cảm ơn bạn đã chỉ ra – Tony

5

Heres những gì tôi sử dụng để phân tích các chuỗi truy vấn

// 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); 
2

Được giới thiệu vào iOS 8 và OS X 10.10 là NSURLQueryItem, có thể được dùng để xây dựng các truy vấn. Từ tài liệu trên NSURLQueryItem:

Đối tượng NSURLQueryItem đại diện cho một cặp tên/giá trị cho một mục trong phần truy vấn của URL. Bạn sử dụng các mục truy vấn với thuộc tính queryItems của một đối tượng NSURLComponents.

Bạn có thể lấy các mục truy vấn từ một URL bằng cách đầu tiên tạo 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 

Lưu ý rằng họ trở về giá trị so với -queryItems là một mảng, không phải là một từ điển. Điều này là do sau đây là một URL hợp lệ. Lưu ý hai "khóa" giống hệt nhau, foo.

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

Để tạo một URL nào qua tin truy vấn, sử dụng initializer định queryItemWithName:value: và sau đó thêm chúng vào NSURLComponents để tạo ra một NSURL. Ví dụ:

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 

Lưu ý rằng dấu hỏi và ký tự được xử lý tự động. Tạo một NSURL từ một cuốn từ điển các thông số đơn giản như:

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; 

Tôi cũng đã viết một bài đăng blog với nhiều chi tiết, Building NSURLs with NSURLQueryItems.

+0

Tuyệt vời! Chỉ cần một lưu ý để devs - nếu bạn sử dụng các tham số GET trùng lặp bạn đang ở trong một thế giới bị tổn thương. Không có quy định cụ thể nào về cách xử lý chúng và các ngôn ngữ/nền tảng khác nhau tạo nên các quy tắc của riêng chúng. Xem http://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys – DougW

Các vấn đề liên quan