Điều này làm việc cho tôi trong Swift 5 . Trường hợp sử dụng đang lấy một URL từ bảng ghi tạm hoặc tương tự có thể đã thoát các ký tự nhưng cũng chứa các ký tự Unicode có thể gây ra URLComponents
hoặc URL(string:)
thất bại.
Đầu tiên, tạo một bộ ký tự bao gồm tất cả các ký tự hợp pháp URL:
extension CharacterSet {
/// Characters valid in at least one part of a URL.
///
/// These characters are not allowed in ALL parts of a URL; each part has different requirements. This set is useful for checking for Unicode characters that need to be percent encoded before performing a validity check on individual URL components.
static var urlAllowedCharacters: CharacterSet {
// Start by including hash, which isn't in any set
var characters = CharacterSet(charactersIn: "#")
// All URL-legal characters
characters.formUnion(.urlUserAllowed)
characters.formUnion(.urlPasswordAllowed)
characters.formUnion(.urlHostAllowed)
characters.formUnion(.urlPathAllowed)
characters.formUnion(.urlQueryAllowed)
characters.formUnion(.urlFragmentAllowed)
return characters
}
}
Tiếp theo, mở rộng String
bằng một phương pháp để mã hóa URL:
extension String {
/// Converts a string to a percent-encoded URL, including Unicode characters.
///
/// - Returns: An encoded URL if all steps succeed, otherwise nil.
func encodedUrl() -> URL? {
// Remove preexisting encoding,
guard let decodedString = self.removingPercentEncoding,
// encode any Unicode characters so URLComponents doesn't choke,
let unicodeEncodedString = decodedString.addingPercentEncoding(withAllowedCharacters: .urlAllowedCharacters),
// break into components to use proper encoding for each part,
let components = URLComponents(string: unicodeEncodedString),
// and reencode, to revert decoding while encoding missed characters.
let percentEncodedUrl = components.url else {
// Encoding failed
return nil
}
return percentEncodedUrl
}
}
Mà có thể được kiểm tra như:
let urlText = "https://www.example.com/폴더/search?q=123&foo=bar&multi=eggs+and+ham&hangul=한글&spaced=lovely%20spam&illegal=<>#top"
let url = encodedUrl(from: urlText)
Giá trị url
ở cuối:https://www.example.com/%ED%8F%B4%EB%8D%94/search?q=123&foo=bar&multi=eggs+and+ham&hangul=%ED%95%9C%EA%B8%80&spaced=lovely%20spam&illegal=%3C%3E#top
Lưu ý rằng cả hai %20
và +
khoảng cách đều được giữ nguyên, các ký tự Unicode được mã hóa, %20
trong bản gốc urlText
không được mã hóa kép và phần neo (đoạn hoặc #
) vẫn còn.
Chỉnh sửa: Bây giờ kiểm tra tính hợp lệ của từng thành phần.