Objective-C 및 Swift URL 인코딩


137

나는 NSString이와 같은 것을 가지고있다 :

http://www.

그러나 나는 그것을 다음과 같이 바꾸고 싶다 :

http%3A%2F%2Fwww.

어떻게해야합니까?


1
암호화 된 문자열 ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~이 있습니다. 아래 해결책 중 어느 것도 이것을 해결하지 못하는 것 같습니다!
Mahendra Liya

답변:


324

당신이 원하는 캐릭터를 탈출하는 것은 조금 더 일입니다.

예제 코드

iOS7 이상 :

NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);

NSLog 출력 :

escapedString : http % 3A % 2F % 2Fwww

다음은 유용한 URL 인코딩 문자 세트입니다.

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

위의 모든 것을 결합한 문자 집합 만들기 :

NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];

Base64 만들기

Base64 문자 집합의 경우 :

NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];

스위프트 3.0 :

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)

스위프트 2.x의 경우 :

var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())

참고 : stringByAddingPercentEncodingWithAllowedCharacters인코딩이 필요한 UTF-8 문자도 인코딩합니다.

iOS7 이전 버전에서는
ARC와 함께 Core Foundation을 사용하여 Core Foundation 사용 :

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));

ARC없이 핵심 기반 사용 :

NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (CFStringRef)unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8);

참고 : -stringByAddingPercentEscapesUsingEncoding올바른 인코딩을 생성하지 않습니다 . 이 경우 동일한 문자열을 반환하는 것은 인코딩되지 않습니다.

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding 14 개의 문자를 인코딩합니다 :

`# % ^ {} [] | \ "<> 및 이스케이프 된 공백 문자.

testString :

" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  

encodeString :

"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"  

참고 : 필요에 따라 변경하지 않으면이 문자 세트가 사용자의 요구를 충족시키는 지 고려하십시오.

인코딩이 필요한 RFC 3986 문자 (인코딩 접두사 문자이므로 %가 추가됨) :

"! # $ & '() * +, / :; =? @ [] %"

일부 "예약되지 않은 문자"는 추가로 인코딩됩니다.

"\ n \ r \"%-. <> \ ^ _`{|} ~ "


1
또한 NSString의 -stringByAddingPercentEscapesUsingEncoding방법을 사용할 수 있습니다 .
Mike Weller

2
아 네, 이제 나는 펑키 stringByAddingPercentEscapesUsingEncoding행동을 기억합니다 . '&'및 '='또는 이와 유사한 말만 인코딩합니다.
Mike Weller

2
RFC1738 에 따르면 추가 문자도 인코딩해야합니다. 따라서 이것이 OP의 질문에 대답하지만 범용 URL 인코더로서의 유용성은 제한적입니다. 예를 들어 독일어 움라우트와 같은 영숫자가 아닌 문자는 처리하지 않습니다.
Alex Nauda

3
이것은 작동하지 않습니다 (iOS 7 부분의 경우). &를 % 26으로 변환하지 않습니다.
coolcool1994

1
NSStringwith로 필요한 문자 세트를 characterSetWithCharactersInString만들고 inverse를 invertedSet사용하여로 사용하십시오 stringByAddingPercentEncodingWithAllowedCharacters. 예를 들어이 SO 답변을 참조하십시오 .
zaph

22

이를 URL 인코딩 이라고 합니다. 더 여기에 .

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
           (CFStringRef)self,
           NULL,
           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
           CFStringConvertNSStringEncodingToEncoding(encoding));
}

3
게시 한 링크의 일부 내용이 답변에 포함 된 경우 훨씬 유용합니다.
chown

1
CFURLCreateStringByAddingPercentEscapes()더 이상 사용되지 않습니다. [NSString stringByAddingPercentEncodingWithAllowedCharacters:]대신 사용하십시오 .
Pang

7

이것은 내 해결책이 아닙니다. 다른 사람이 stackoverflow로 작성했지만 방법을 잊어 버렸습니다.

어떻게 든이 솔루션은 "잘 작동"합니다. 분음 부호, 한자 등을 처리합니다.

- (NSString *) URLEncodedString {
    NSMutableString * output = [NSMutableString string];
    const char * source = [self UTF8String];
    int sourceLen = strlen(source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = (const unsigned char)source[i];
        if (false && thisChar == ' '){
            [output appendString:@"+"];
        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
                   (thisChar >= 'a' && thisChar <= 'z') ||
                   (thisChar >= 'A' && thisChar <= 'Z') ||
                   (thisChar >= '0' && thisChar <= '9')) {
            [output appendFormat:@"%c", thisChar];
        } else {
            [output appendFormat:@"%%%02X", thisChar];
        }
    }
    return output;
}

누군가이 코드를 작성한 사람을 말하면 정말 감사하겠습니다. 기본적으로 그는이 인코딩 된 문자열이 원하는대로 정확하게 해독되는 이유에 대해 설명합니다.

나는 그의 해결책을 조금 수정했다. 공간이 +가 아닌 % 20으로 표시되는 것을 좋아합니다. 그게 다야.



[self UTF8String]은 무엇입니까?
Yuchao Zhou

1
@yuchaozh 이것은 NSString 범주에 넣는 함수입니다. 따라서 self는 NSStirng이고 [self UTF8String]은 문자열을 UTF8 형식으로 가정합니다.
Kelsey

4
 NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );

NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];

1
encodeString 및 url을 해제하십시오. 이 코드는 인코딩 매개 변수에 관한 것입니다. "매개 변수"대신 전체 주소 패스 문자열을 인코딩합니다.
Zahi

이것은 나를 위해 일했습니다 ... 문제가있는 & 문자조차도 인코딩했습니다.
Виктор Иванов

3

이것은 Objective C ARC에서 작동 할 수 있습니다. CFBridgingRelease를 사용하여 Core Foundation 스타일 객체를 Objective-C 객체로 캐스팅하고 객체의 소유권을 ARC로 이전 하십시오. 여기에서 CFBridgingRelease 함수를 참조 하십시오.

+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
                         (kCFAllocatorDefault,
                          (__bridge CFStringRef)string,
                          NULL,
                          CFSTR("!*'();:@&=+$,/?%#[]"),
                          kCFStringEncodingUTF8)
                         );}

2

스위프트 iOS :

단지 정보를 위해 : 나는 이것을 사용했다 :

extension String {

    func urlEncode() -> CFString {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }

}// end extension String

1
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                             NULL,
                             (CFStringRef)yourString, 
                             NULL, 
                             CFSTR("/:"), 
                             kCFStringEncodingUTF8);

str직접 릴리스하거나 자동 릴리스해야합니다 .


1

여기 내가 사용하는 것이 있습니다. 이 @autoreleasepool기능 을 사용해야합니다. 그렇지 않으면 프로그램이 충돌하거나 IDE를 잠글 수 있습니다. 수정 사항을 알 때까지 IDE를 세 번 다시 시작해야했습니다. 이 코드는 ARC를 준수하는 것으로 보입니다.

이 질문은 여러 번 요청되어 왔으며 많은 답변이 주어졌지만 슬프게도 선택된 모든 질문 (그리고 다른 사람들이 제안한 것)은 모두 잘못되었습니다.

내가 사용한 테스트 문자열은 다음과 같습니다. This is my 123+ test & test2. Got it?!

이들은 Objective C ++ 클래스 메소드입니다.

static NSString * urlDecode(NSString *stringToDecode) {
    NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "];
    result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return result;
}

static NSString * urlEncode(NSString *stringToEncode) {
    @autoreleasepool {
        NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
                NULL,
                (CFStringRef)stringToEncode,
                NULL,
                (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                kCFStringEncodingUTF8
            ));
        result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"];
        return result;
    }
}

0

Google 은 Mac 용 Google 도구 상자 에서이를 구현합니다 . 그래서 그들이하는 일을 최고조로하기 좋은 곳입니다. 또 다른 옵션은 도구 상자를 포함하고 해당 도구를 구현하는 것입니다.

여기 에서 구현을 확인 하십시오 . (사람들이 여기에 올린 내용과 정확히 일치합니다).


0

이것이 내가 신속하게하는 일입니다.

extension String {
    func encodeURIComponent() -> String {
        return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    }

    func decodeURIComponent() -> String {
        return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
    }
}

-1

// 다음과 같이 NSString 인스턴스 메소드를 사용하십시오.

+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

요청한 모든 URL이 아니라 매개 변수 값에 대해서만 인코딩 또는 디코딩해야합니다.


2
stringByReplacingPercentEscapeusingencoding : 이스케이프 & & = :-(
Sébastien Stormacq

1
+와 같은 것은 필요할 때 인코딩되지 않습니다. 따라서 위의 답변을 사용하지 마십시오
John Ballinger

-8
int strLength = 0;
NSString *urlStr = @"http://www";
NSLog(@" urlStr : %@", urlStr );
NSMutableString *mutableUrlStr = [urlStr mutableCopy];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.