programing

목표-c iPhone 백분율로 문자열을 인코딩하시겠습니까?

padding 2023. 9. 5. 19:44
반응형

목표-c iPhone 백분율로 문자열을 인코딩하시겠습니까?

저는 이 특정 문자들에 대한 퍼센트 인코딩 문자열을 얻고 싶은데, 목표-c에서 어떻게 하나요?

Reserved characters after percent-encoding
!   *   '   (   )   ;   :   @   &   =   +   $   ,   /   ?   #   [   ]
%21 %2A %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %23 %5B %5D

백분율 인코딩 위키

이 문자열을 사용하여 테스트하고 작동하는지 확인하십시오.

myURL = @"someurl/somecontent"

다음과 같은 문자열을 원합니다.

myEncodedURL = @"someurl%2Fsomecontent"

저는 그것을 시도했습니다.stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding이미 작동하지 않습니다. 결과는 여전히 원래 문자열과 동일합니다.조언 부탁드립니다.

두 가지 를 찾았습니다stringByAddingPercentEscapesUsingEncoding:그리고.CFURLCreateStringByAddingPercentEscapes()부적절합니다.NSString메소드에는 꽤 많은 문자가 누락되어 있으며, CF 함수에서는 이스케이프할 문자만 말할 수 있습니다.올바른 사양은 작은 집합을 제외한 모든 문자를 이스케이프하는 것입니다.

이 문제를 해결하기 위해, 저는 다음을 만들었습니다.NSString문자열을 올바르게 인코딩하는 범주 메서드입니다.다음을 제외한 모든 항목을 백분율로 인코딩합니다.[a-zA-Z0-9.-_~] 는 또한 공백을 그고공간인것입니다할로 합니다.+( 명세서에 따름).또한 유니코드 문자 인코딩을 올바르게 처리합니다.

- (NSString *) URLEncodedString_ch {
    NSMutableString * output = [NSMutableString string];
    const unsigned char * source = (const unsigned char *)[self UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (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;
}

7는 이제 7 SDK보다 더 대안을 있습니다.stringByAddingPercentEscapesUsingEncoding특정 허용 문자를 제외한 모든 문자를 이스케이프하도록 지정할 수 있습니다.URL을 부분적으로 작성하는 경우에는 잘 작동합니다.

NSString * unescapedQuery = [[NSString alloc] initWithFormat:@"?myparam=%d", numericParamValue];
NSString * escapedQuery = [unescapedQuery stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString * urlString = [[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext%@", escapedQuery];

URL의 다른 부분이 변수가 되는 경우는 적지만, NSURLUtilities 범주에도 변수에 대한 상수가 있습니다.

[NSCharacterSet URLHostAllowedCharacterSet]
[NSCharacterSet URLUserAllowedCharacterSet]
[NSCharacterSet URLPasswordAllowedCharacterSet]
[NSCharacterSet URLPathAllowedCharacterSet]
[NSCharacterSet URLFragmentAllowedCharacterSet]

[NSCharacterSet URLQueryAllowedCharacterSet]URL의 쿼리 부분에 허용되는 모든 문자를 포함합니다(으로 시작하는 부분).? 리고그전 에.#에는 하이여을포함있)를 포함합니다.? 리고그고.&또는=매개 변수 이름과 값을 구분하는 데 사용되는 문자입니다.영숫자 값을 사용하는 쿼리 매개 변수의 경우 쿼리 문자열을 작성하는 데 사용되는 변수 값에 이러한 문자를 포함할 수 있습니다.이 경우 쿼리 문자열의 부분을 이스케이프해야 하므로 작업이 조금만 더 필요합니다.

NSMutableCharacterSet * URLQueryPartAllowedCharacterSet; // possibly defined in class extension ...

// ... and built in init or on first use
URLQueryPartAllowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[URLQueryPartAllowedCharacterSet removeCharactersInString:@"&+=?"]; // %26, %3D, %3F

// then escape variables in the URL, such as values in the query and any fragment:
NSString * escapedValue = [anUnescapedValue stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet];
NSString * escapedFrag = [anUnescapedFrag stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSString * urlString = [[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext?myparam=%@#%@", escapedValue, escapedFrag];
NSURL * url = [[NSURL alloc] initWithString:urlString];

unescapedValue콜백 또는 리디렉션과 같은 전체 URL일 수도 있습니다.

NSString * escapedCallbackParamValue = [anAlreadyEscapedCallbackURL stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet];
NSURL * callbackURL = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext?callback=%@", escapedCallbackParamValue]];

함: 사용 안 함NSURL initWithScheme:(NSString *)scheme host:(NSString *)host path:(NSString *)path경로에 이스케이프 비율을 더 추가하기 때문에 쿼리 문자열이 있는 URL의 경우.

NSString *encodedString = [myString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

문자열을 인라인으로 대체하지 않고 새 문자열을 반환합니다.그것은 그 방법이 "끈"이라는 단어로 시작한다는 사실에 의해 암시됩니다.현재 NSString을 기반으로 새 NSString 인스턴스를 인스턴스화하는 편리한 방법입니다.

참고--새 문자열은 다음과 같습니다.autorelease'd, 그러니까 당신이 그것을 끝냈을 때 그것에 대해 석방을 요구하지 마세요.

NSString의stringByAddingPercentEscapeUsingEncoding: 원하는 것처럼 보입니다.

편집: 다음은 대신 사용하는 예제입니다.originalString둘 중 하나가 될 수 있습니다.NSString또는CFStringRef.

CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, originalString, NULL, CFSTR("!*'();:@&=+@,/?#[]"), kCFStringEncodingUTF8);

이것은 테스트되지 않았습니다.다음에 대한 메모리 할당 의미를 확실히 이해하려면 설명서 페이지를 살펴봐야 합니다.CFStringRef수신자 부담 교량 등의 개념

또한, 나는 (머리에서) 어떤 캐릭터가 명시되어 있는지 모릅니다.legalURLCharactersToBeEscapedURL에서 불법이기 때문에 인수는 어쨌든 탈출했을 것입니다.안전한 쪽에 서서 탈출할 문자를 직접 지정하는 것이 더 나을 수도 있지만 이를 확인하는 것이 좋습니다.

저는 코어 파운데이션에 대해 더 많은 지식을 가진 사람들이 개선할 수 있도록 이 답변을 커뮤니티 위키로 만들고 있습니다.

RFC3986 표준에 따라 URL 구성 요소를 인코딩하는 데 사용하는 내용은 다음과 같습니다.

// https://tools.ietf.org/html/rfc3986#section-2.2
let rfc3986Reserved = NSCharacterSet(charactersInString: "!*'();:@&=+$,/?#[]")
let encoded = "email+with+plus@example.com".stringByAddingPercentEncodingWithAllowedCharacters(rfc3986Reserved.invertedSet)

출력:email%2Bwith%2Bplus%40example.com

만약 당신이 목표-c 프로그램에서 ASI HttpRequest 라이브러리를 사용하고 있다면, 제가 충분히 추천할 수 없는 것이라면, 당신은 "encode"를 사용할 수 있습니다.ASI FormDataRequest 개체의 URL" 도우미 API입니다.안타깝게도 API는 정적이지 않으므로 프로젝트에서 구현을 사용하여 확장을 생성할 가치가 있습니다.

인코딩을 위해 ASI FormDataRequest.m에서 직접 복사된 코드URL 구현:

- (NSString*)encodeURL:(NSString *)string
{
    NSString *newString = NSMakeCollectable([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding([self stringEncoding])) autorelease]);
    if (newString) {
        return newString;
    }
    return @"";
}

보다시피, 이것은 본질적으로 주변의 포장지입니다.CFURLCreateStringByAddingPercentEscapes제대로 탈출해야 하는 모든 캐릭터를 처리하는 것입니다.

Rob의 답변이 잘 작동하고 깨끗하기 때문에 선호되는 것을 알아차리기 전에 먼저 Dave의 답변을 Swift에 포팅했습니다.관심 있는 사람이 있을 경우를 대비해 여기에 두겠습니다.

public extension String {

    // For performance, I've replaced the char constants with integers, as char constants don't work in Swift.

    var URLEncodedValue: String {
        let output = NSMutableString()
        guard let source = self.cStringUsingEncoding(NSUTF8StringEncoding) else {
            return self
        }
        let sourceLen = source.count

        var i = 0
        while i < sourceLen - 1 {
            let thisChar = source[i]
            if thisChar == 32 {
                output.appendString("+")
            } else if thisChar == 46 || thisChar == 45 || thisChar == 95 || thisChar == 126 ||
                (thisChar >= 97 && thisChar <= 122) ||
                (thisChar >= 65 && thisChar <= 90) ||
                (thisChar >= 48 && thisChar <= 57) {
                    output.appendFormat("%c", thisChar)
            } else {
                output.appendFormat("%%%02X", thisChar)
            }

            i++
        }

        return output as String
    }
}

Swift4에서:

 var str = "someurl/somecontent"

 let percentEncodedString = str.addingPercentEncoding(withAllowedCharacters: .alphanumerics)

언급URL : https://stackoverflow.com/questions/3423545/objective-c-iphone-percent-encode-a-string

반응형