URLComponents.init(url:resolveAgainstBaseURL:)
Tài liệu nói:
Trả về đối tượng thành phần URL được khởi tạo hoặc trả về 0 nếu không thể phân tích cú pháp URL.
Biết:
Tôi cho rằng khi một URL tuân thủ RFC 1808/1738/2732 chứ không phải RFC 3986,Thành phần URL
Việc khởi tạo sẽ thất bại.Đó là loại URL gì? Có ví dụ nào không?
Mẹo duy nhất của tôi cho đến nay có thể liên quan đến các ký tự dành riêng khác nhau?
Vì Swift Foundation là mã nguồn mở nên hãy khám phá nó từ mã nguồn của nó.
Thành phần URL
Trình khởi tạo đang ở apple/swift – URLComponents.swift nhận ra và apple/swift-corelibs-foundation – URLComponents.swiftvà chỉ cần gọi Thành phần NSURL
chương trình khởi tạo.
Thành phần NSURL
Trình khởi tạo đang ở apple/swift-corelibs-foundation – NSURL.swift được thực hiện và chỉ cần gọi _CFURLThành phầnTạoVớiURL
.
_CFURLThành phầnTạoVớiURL
hiện hữu apple/swift-corelibs-foundation – CFURLComponents.c Được thực hiện trong và:
- với
CFURLSao chépURL tuyệt đối
sao chép thất bại
- sử dụng
_CFURLComponentsCreateWithString
Cuộc gọi tạo không thành công:
_CFURIParserParseURIReference
+ thất bại_CFURIParserURLStringIsValid
CFURLSao chépURL tuyệt đối
hiện hữu apple/swift-corelibs-foundation – CFURL.c được thực hiện và chỉ thất bại trong các điều kiện sau:
#if DEPLOYMENT_TARGET_MACOSX ||
if ( base && CFURLIsFileReferenceURL(base) && !CFURLHasDirectoryPath(base) ) {
// 16695827 - Nếu URL cơ sở là URL tham chiếu tệp không kết thúc bằng dấu gạch chéo, chúng tôi phải chuyển đổi nó thành URL đường dẫn tệp trước khi có thể biến nó thành tuyệt đối.
base = CFURLCreateFilePathURL(cấp phát, base, NULL);
nếu ( !base ) {
// không thể chuyển đổi URL tham chiếu tệp thành URL đường dẫn tệp - sẽ thất bại NULL
trả về NULL;
}
}
#endif
CFURLTạoFilePathURL
Sự nhận thức bây giờ là opensource.apple.com/source/CF – CFURL.c , tôi hiểu rằng nó sẽ chỉ thất bại nếu không có sơ đồ hoặc không có đường dẫn, điều này không thể thực hiện được vì trước đây chúng tôi đã sử dụng CFURLIsFileReferenceURL
Đã kiểm tra xem sơ đồ tệp hoặc tệp có tồn tại hay không.
_CFURIParserParseURIReference
hiện hữu apple/swift-corelibs-foundation – CFURLComponents_URIParser.c được triển khai và chỉ thất bại nếu độ dài URL vượt quá 2 GB, điều mà tôi không nghĩ có liên quan gì đến đặc tả RFC.
_CFURIParserURLStringIsValid
Về cơ bản sẽ được gọi cho từng thành phần _CFURIParserValidateComponent
và thất bại với các ký tự không hợp lệ hoặc chuỗi thoát. Đây có lẽ là phần có liên quan nhất.
Bây giờ, sau một số thử nghiệm, chúng tôi biết mình cần một giải pháp (ví dụ:https://
hoặc đơn giản Một://
), thì chúng ta sử dụng các ký tự dành riêng cho ví dụ được đề xuất, ví dụ:
// ĐƯỢC RỒI
hãy url = URL(chuỗi: "a://@@")!
// TAI NẠN
hãy để thành phần = URLComponents (url: url, giải quyếtAgainstBaseURL: true)!
thử Thành phần URL
Trình khởi tạo thay thế cũng sẽ thất bại, vì vậy đừng cố nghĩ rằng nó khác:
// TAI NẠN
hãy để thành phần = URLComponents(chuỗi: url.absoluteString)!
Tóm lại
"Một://@@"
là một ví dụ về NSURL hợp lệ nhưng RFC 3986 không hợp lệ.
Một lưu ý phụ, một số người dùng Swift dường như muốn tương lai thống nhất hỗ trợ cho URL và URLComponents (không có thêm sự khác biệt về RFC)như đã thấy trong URL.swift :
// Future implementation note:
// NSURL (really CFURL, which provides its implementation) has quite a few quirks in its processing of some more esoteric (and some not so esoteric) strings. We would like to move much of this over to the more modern NSURLComponents, but binary compat concerns have made this difficult.
// Hopefully soon, we can replace some of the below delegation to NSURL with delegation to NSURLComponents instead. It cannot be done piecemeal, because otherwise we will get inconsistent results from the API.
我不确定他们打算如何执行此操作,因为这意味着要么 URL(string: "a://@@")
会失败,要么 URLComponents(string : "a://@@")
会成功。
Tôi là một lập trình viên xuất sắc, rất giỏi!