透過 URLComponents 將 http 的網址改成 https

使用 URLSession 抓取資料時,為了安全性的考量,Apple 限制我們只能抓取 https 的資料,因此以下 http 連結的圖片將無法抓取。

struct ContentView: View {
var body: some View {

Button(action: {
if let url = URL(string: "http://i.annihil.us/u/prod/marvel/i/mg/c/e0/535fecbbb9784/standard_xlarge.jpg") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data,
let image = UIImage(data: data) {
print(image)
}
}.resume()
}
}, label: {
Text("抓圖")
})
}
}

點選 button 抓取失敗時 Xcode 將印出以下錯誤訊息。

2021-03-02 15:37:41.390698+0800 Demo[1763:112402] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
2021-03-02 15:37:41.390872+0800 Demo[1763:112402] Cannot start load of Task <7F5EAF82-F0A4-4EFF-A8C2-285DFA7C3C9C>.<1> since it does not conform to ATS policy
2021-03-02 15:37:41.395450+0800 Demo[1763:113203] Task <7F5EAF82-F0A4-4EFF-A8C2-285DFA7C3C9C>.<1> finished with error [-1022] Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLStringKey=http://i.annihil.us/u/prod/marvel/i/mg/c/e0/535fecbbb9784/standard_xlarge.jpg, NSErrorFailingURLKey=http://i.annihil.us/u/prod/marvel/i/mg/c/e0/535fecbbb9784/standard_xlarge.jpg, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <7F5EAF82-F0A4-4EFF-A8C2-285DFA7C3C9C>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <7F5EAF82-F0A4-4EFF-A8C2-285DFA7C3C9C>.<1>, NSUnderlyingError=0x6000012dced0 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}}

有些 http 的網址其實可以換成 https,因此剛剛的圖片網址我們可以透過 URLComponents 狸貓換太子,將 http 改成 https 再抓取。(ps: 不過也別高興得太早,並非每個 http 的網址都能轉換成 https。)

透過 URLComponents 將 http 的網址改成 https 的範例如下:

var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)
urlComponents?.scheme = "https"
print(urlComponents!.url!)

參考連結

Develop in Swift Data Collection‪s‬ Lession 2.6 Working with the Web: Concurrency

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com