문제

내가 작성 중인 애플리케이션에는 다음과 같은 코드가 있습니다.

NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSString* myurl = @"http://www.somewebsite.com/method?a=%d";

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

가장 큰 차이점은 myurl 내 통제 밖의 어딘가에서 온다.URL의 %d는 완전히 정확하지 않으며 URLWithString이 실패하고 반환됨을 의미합니다. .

이것을 처리하는 "올바른" 방법은 무엇입니까?문자열을 구문 분석하고 인수를 올바르게 인코딩해야 합니까?아니면 나를 위해 모든 노력을 다해 주는 어떤 영리한 방법이 Cocoa에 있습니까?

도움이 되었습니까?

해결책

이것이 정확히 당신이 찾고 있는 것인지는 모르겠지만 NSString에는 URL을 삭제하는 메서드가 있습니다.

stringByAddingPercentEscapesUsingEncoding:

다른 팁

%d는 URL의 유효한 구성 요소가 아니기 때문에 여기의 동작이 정확하다고 생각합니다(%는 이스케이프이지만 뒤에 오는 두 개의 16진수 문자를 예상함).

주어진 URL을 단순히 URL 인코딩할 수는 없습니다. 왜냐하면 원하지 않는 /s 및 ?s도 인코딩하기 때문입니다.

그래서 질문은, 여기서 올바른 행동은 무엇입니까?

아마도 당신은 그것이 바뀌기를 원할 것입니다 ...

http://www.somewebsite.com/method?a=%25d

(즉.%는 URL에서 %의 인코딩된 버전으로 인코딩되므로 메소드가 입력을 받으면 a가 %d로 설정된 것으로 표시됩니다.

나는 그것을 하는 '올바른' 방법이 없기 때문에 당신을 위해 그런 종류의 일을 할 어떤 라이브러리 함수도 없다고 생각합니다.그가 할 수 있는 유일한 올바른 일은 제공된 URL이 유효하지 않다는 오류 메시지를 반환하는 것입니다(URLWithString과 마찬가지로).


입력을 처리하려면 URL에서 바로 뒤에 두 개의 16진수 문자가 나오지 않는 % 기호를 검색한 다음 이 경우 %를 %25로 바꿔야 할 것 같습니다.정규식을 사용하면 꽤 가능할 것입니다. 하지만 URL에 ASCII 문자 세트 외부의 인코딩된 문자 버전이 포함되기 시작하면 몇 가지 추가적인 복잡성이 있을 수 있다고 생각됩니다.

안타깝게도 Apple에서 제공하는 것보다 더 똑똑해야 합니다.

stringByAddingPercentEscapesUsingEncoding:

이는 유효하지 않은 모든 URL 문자를 이스케이프하여 유효한 "http://foo.com/hey%20dude/"가 우리가 원하는 것이 아닌 "http://foo.com/hey%2520dud/"가 되도록 합니다. .

사과 문서에 따르면 : http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

나는 옳은 일을 하고 부분 인코딩이 있는 이상한 문자열과 함께 작동하는 NSURL 카테고리를 만들었습니다(예:"http://foo.com/hey 친구/i%20do%20it/").

코드는 다음과 같습니다.

@interface NSURL (SmartEncoding)
+ (NSURL *)smartURLWithString:(NSString *)str;
@end

@implementation NSURL (SmartEncoding)

+ (NSURL *)smartURLWithString:(NSString *)str
{
    CFStringRef preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8);
    if (!preprocessed) 
        preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingASCII);

    if (!preprocessed)
        return [NSURL URLWithString:str];

    CFStringRef sanitized = CFURLCreateStringByAddingPercentEscapes(NULL, preprocessed, NULL, NULL, kCFStringEncodingUTF8);
    CFRelease(preprocessed);
    NSURL *result = (NSURL*)CFURLCreateWithString(NULL, sanitized, NULL);
    CFRelease(sanitized);
    return [result autorelease];
}

@end

UTF8 문자열로 인코딩된 문자열과 ASCII 문자열에서는 잘 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top