URL appendingComponent와 QueryString - Team-HGD/SniffMEET GitHub Wiki
문제
이런 식으로 appendingComponent 메서드를 통해 ?를 넣어주게 되면
absoluteURL = absoluteURL.appendingPathComponent("?" + queryPathString)
예상
실제
https://example.com/user%3Fid=1
그냥 퍼센트 인코딩이라 별 상관없는거 아냐?라고 생각할 수 있지만,
?를 경로로 인식하면서 요청에 실패하게 된다.
해결방법
- 문자열로 직접 만들면 된다!
public var absoluteURL: URL {
var absoluteURLString: String = baseURL.absoluteString + "/"
// 의미없는 / 제거
let pathComponents = path.components(separatedBy: "/")
.compactMap{ $0.isEmpty ? nil : $0 }
let queryPathString: String = query?.map{ "\($0)=\($1)" }.joined(separator: "&") ?? ""
absoluteURLString += pathComponents.joined(separator: "/")
if !queryPathString.isEmpty {
absoluteURLString += "?\(queryPathString)"
}
return URL(string: absoluteURLString) ?? baseURL
}
- URLComponents를 통해 만들기
URLComponents에서 조금 더 안전하게 처리할 수 있다.
public var absoluteURL: URL {
let absoluteURLString: String = baseURL.absoluteString.trimmingCharacters(
in: CharacterSet(charactersIn: "/")
)
var components = URLComponents(string: absoluteURLString)
components?.queryItems = query?.compactMap {
URLQueryItem(name: $0, value: $1)
}
let previousPath = components?.path ?? ""
components?.path = previousPath + "/\(path)"
return components?.url ?? baseURL
}