带花括号的NSURL



NSURL不支持在url中使用花括号(即{})。我的应用程序需要与需要在URL中使用花括号的服务器进行通信。我正在考虑使用桥接器在Python或c++中编写网络代码,甚至重写NSURL的C代码以使其接受花括号。我的远程服务器不接受百分号转义。

我有其他好的选择吗?

编辑:解释了为什么添加percentescapesusingencoding等不适合我这里

如果您转义大括号,它会为您工作吗?

这个代码:

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

所以,转义似乎有效

以下是如何通过编程转义url的方法:
NSString *escapedUrlString = [unescaped stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];
编辑:

在你的评论下面,你说你的服务器不会接受编码大括号,有没有其他的选择。首先,我会尝试修复服务器。如果这是不可能的……我还没有试过用牙套等等……但是NS网络类下面的层是CFNetworking。

看到这个:

http://developer.apple.com/library/ios/文档/网络/概念/CFNetwork/CFHTTPTasks CFHTTPTasks.html #//apple_ref/doc/uid/TP30001132-CH5-SW2

From the doc:

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

再说一次,我还没试过,快用完了。可能以后会尝试,但如果一个层不工作,你的第一个选择是向下移动堆栈

Bryan的回答非常好(给他+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];

我希望这个信息能帮助你!

使用CFNetwork调用可以使用下面的

-(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;
    }
}

以上是用这里和这里的例子完成的

但是即使上面的方法也有同样的问题。也就是说:如果{}未被编码,则不会生成URL。如果{}被编码,服务器不会返回正确的值。

还有其他解决这个帖子问题的建议吗?

最新更新