본문 바로가기
IT·디지털/IT 개발자 팁

[iOS] iPhone에서 올바른 URL 인코딩 방법 (Objective-C & Swift 최신 정리)

by 가을이짱짱 2013. 12. 10.
반응형

[iOS] iPhone에서 URL 인코딩이 제대로 되지 않을 때

예전 iOS 앱 유지보수 중, 로그인 기능에서 비밀번호에 = 문자가 포함되면 정상적으로 서버에 전달되지 않는 문제가 있었습니다. 원인은 URL 인코딩에 사용하던 API가 특수문자를 완전하게 인코딩하지 않았기 때문입니다.

특히 예전 iOS 개발에서 많이 사용하던:


[string stringByAddingPercentEscapesUsingEncoding:]

이 메서드는 다음과 같은 문제를 가지고 있습니다.

  • 이미 deprecated 됨
  • / & = ? + # % 등 중요한 URL 예약 문자 인코딩 불가능
  • RFC 3986 기준을 완전히 만족하지 않음

즉, “진정한 URL 인코딩”이 되지 않아 인증/로그인/REST API 호출에서 문제가 발생할 수 있습니다.


1. (레거시 해결책) CFURLCreateStringByAddingPercentEscapes

Objective-C 시대에 완전한 URL 인코딩을 하기 위해 많이 사용했던 코드입니다.


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

이 방식은 거의 모든 URL 예약 문자를 인코딩할 수 있어 당시 ‘진정한 URL Encoding’으로 불렸습니다.

하지만 지금은 deprecated이며, 더 이상 추천되지 않습니다.


2. 2025년 기준 공식적인 URL 인코딩 방법 (Objective-C 최신)

2-1. stringByAddingPercentEncodingWithAllowedCharacters:

지금은 반드시 아래 메서드를 사용해야 합니다.


NSString *raw = @"test=password=123&key=value";

NSString *encoded = [raw stringByAddingPercentEncodingWithAllowedCharacters:
                     [NSCharacterSet URLQueryAllowedCharacterSet]];

// 필요 시 추가 필터링(예약문자 제거)
NSCharacterSet *allowed = [[NSCharacterSet URLQueryAllowedCharacterSet]
                            mutableCopy];
[(NSMutableCharacterSet *)allowed removeCharactersInString:@"=&+?#"];

NSString *finalEncoded = [raw stringByAddingPercentEncodingWithAllowedCharacters:allowed];

iOS 공식 표준이며, RFC 3986 규칙을 준수하도록 커스터마이징할 수 있습니다.


3. Swift에서의 최신 URL 인코딩 방식 (2025)

3-1. Query 파라미터 인코딩


let raw = "password=abc=123&key=value"

var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "=&+?#")

let encoded = raw.addingPercentEncoding(withAllowedCharacters: allowed)

3-2. URLComponents를 통한 완전 자동 인코딩 (가장 추천)


var components = URLComponents(string: "https://example.com/login")!
components.queryItems = [
    URLQueryItem(name: "id", value: "tester"),
    URLQueryItem(name: "password", value: "ab=c&123")
]

let url = components.url   // 자동 RFC 3986 인코딩 적용

직접 인코딩할 필요 없이 가장 안전하고 권장되는 방식입니다.


4. 어떤 문자가 반드시 인코딩되어야 하나?

RFC3986 기준, 반드시 인코딩해야 하는 URL 예약 문자:


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

특히 로그인/인증에서는 =& 문자가 서버 파싱을 망가뜨리므로 반드시 URL 인코딩이 필요합니다.


5. 정리

  • stringByAddingPercentEscapesUsingEncoding → deprecated / 사용 금지
  • CFURLCreateStringByAddingPercentEscapes → 레거시 방식
  • stringByAddingPercentEncodingWithAllowedCharacters → 최신 표준
  • URLComponents를 통한 자동 인코딩이 가장 안전한 방식

비밀번호, 토큰, 인증키처럼 민감한 문자열을 URL로 전송할 때는 정확한 URL 인코딩이 필수입니다. 예전 API는 제대로 인코딩되지 않으므로 반드시 최신 방식으로 전환해야 합니다.

반응형