2011-12-01 56 views
2

NSURL不支持在URL中使用花括號(即{})。我的應用程序需要與需要在URL中使用大括號的服務器通信。我正在考慮使用橋接器來編寫Python或C++中的網絡代碼,甚至爲NSURL重寫C代碼以使它接受大括號。百分號轉義不被我的遠程服務器接受。帶捲曲花括號的NSURL

我還有其他不錯的選擇嗎?

編輯:解釋爲什麼addingPercentEscapesUsingEncoding之類的不適合我這裏工作。

+0

你可能要更新你的問題標題爲NSURL帶花括號 - 我認爲你假設你需要一個替代方案... – bryanmac

回答

10

如果你躲開大括號,它會適合你嗎?

此代碼:

// escape {} with %7B and %7D 
NSURL *url = [NSURL URLWithString:@"http://somesite.com/%7B7B643FB915-845C-4A76-A071-677D62157FE07D%7D.htm"]; 
NSLog(@"%@", url); 

// {} don't work and return null 
NSURL *badurl = [NSURL URLWithString:@"http://somesite.com/{7B643FB915-845C-4A76-A071-677D62157FE07D}.htm"]; 
NSLog(@"%@", badurl); 

輸出:

2011-11-30 21:25:06.655 Craplet[48922:707] http://somesite.com/%7B7B643FB915-845C-4A76-A071-677D62157FE07D%7D.htm 
2011-11-30 21:25:06.665 Craplet[48922:707] (null) 

所以,逃避似乎工作

這裏是你如何可以以編程方式逃避網址:

NSString *escapedUrlString = [unescaped stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding]; 

編輯:

在您的評論如下,你說你的服務器將不接受編碼括號,是沒有任何其他選擇。首先,我會嘗試修復服務器。如果這是不可能的......我還沒有嘗試過這與括號等...但NS網絡類下面的層是CFNetworking。

看到這個:

http://developer.apple.com/library/ios/#documentation/Networking/Conceptual/CFNetwork/CFHTTPTasks/CFHTTPTasks.html#//apple_ref/doc/uid/TP30001132-CH5-SW2

從這個DOC:

CFStringRef url = CFSTR("http://www.apple.com"); 
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL); 
CFStringRef requestMethod = CFSTR("GET"); 

.... 

再次,還沒有嘗試過了,我跑出來。可能會在稍後嘗試,但如果圖層不工作,則您的第一個選項是向下移動堆棧。

+0

嘿布萊恩,感謝您的迴應!不幸的是,似乎服務器不接受花括號的百分比轉義值。有沒有一種方法可以在目標c中使用顯式花括號來形成GET請求? –

+1

我添加了關於CFNetworking的註釋 - 一種選擇是繼續向下移動堆棧。但是,如果可能的話,我會嘗試並修復服務器:) – bryanmac

+0

感謝您的更新。我們發現這是其他地方的一個小編碼錯誤,正在讓我們失望。問題已解決,但我會保留此代碼以備將來參考,以防其他網絡問題發生。 –

8

布賴恩的回答非常好(對他+1),但另一種解決方案是使用NSString的stringByAddingPercentEscapesUsingEncoding:方法。

像這樣:

NSString * originalURLAsString = [NSString stringWithString: @"http://somesite.com/{7B643FB915-845C-4A76-A071-677D62157FE07D}.htm"]; 
NSString * properlyEncodedString = [originalURLAsString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; 
NSURL * url = [NSURL URLWithString: properlyEncodedString]; 

我希望這個信息可以幫助你!

+1

+1 - 正在編輯我的,因爲你附加了這個答案 - 我們的節省劃線:) – bryanmac

+1

嗨邁克爾,感謝發佈!這個竅門對我來說不起作用,因爲對方希望顯式大括號,而不是百分比轉義值。你知道一種方法來形成一個GET請求,並在目標c中使用明確的大括號嗎? –

+0

您是否可以控制您正在與之通話的服務器?服務器應該總是處理轉義百分比的URL。 –

0

要調用使用CFNetwork的可以使用follwoing

-(void)getDataFromUrl{ 
    CFStringRef tempURLA = CFSTR("http://my.test.server/iostest/index.html?{\"a\":\"b\"}"); 
    CFStringRef tempUrlSting = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)tempURLA,CFSTR("{}"), CFSTR("\""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); 

    CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, tempUrlSting, NULL); 

    CFStringRef requestMethod = CFSTR("GET"); 
    CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL,kCFHTTPVersion1_1); 

    CFStringRef headerFieldName = CFSTR("Accept"); 
    CFStringRef headerFieldValue = CFSTR("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 
    CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue); 


    [self performHTTPRequest:myRequest]; 

} 

-(void)performHTTPRequest:(CFHTTPMessageRef)request { 
    CFURLRef gotdatab = (__bridge CFURLRef)(CFBridgingRelease(CFHTTPMessageCopyRequestURL(request))); 
// NSLog(@"(CFHTTPMessageRef request %@",gotdatab); 

    CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request); 

    CFReadStreamOpen(requestStream); 

    NSMutableData *responseBytes = [NSMutableData data]; 
    NSError *error; 

    while (TRUE) { 

     if (CFReadStreamHasBytesAvailable(requestStream)) { 
      UInt8 streambuffer[1024]; 
      int readBytes = CFReadStreamRead (requestStream,streambuffer,sizeof(streambuffer)); 
      NSLog(@"Read: %d",readBytes); 
      [responseBytes appendBytes:streambuffer length:readBytes]; 
     } 

     if (CFReadStreamGetStatus(requestStream) == kCFStreamStatusError) { 

      error = (NSError*)CFBridgingRelease(CFReadStreamCopyError (requestStream)); 
      if ([error code] == 61) { 
       // connection refused 
       NSLog(@"Error occured: %d",[error code]); 
      } 
      break; 
     } 
     if (CFReadStreamGetStatus(requestStream) == kCFStreamStatusAtEnd) { 
      NSLog(@"Stream reached end!"); 
      error = nil; 
      break; 
     } 

    }// 
    CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader); 

    if (response==NULL) { 
     NSLog(@"response is null"); 
     return; 
    } 
} 

上面用實例進行從herehere

但是,即使上述方法有同樣的問題。即:如果{}未編碼,則URL不會生成。如果{}被編碼,則服務器不會返回適當的值。

任何其他建議來解決這個職位的問題?