[SwiftUI] Remote Image 讀取方式

戴萌
8 min readMay 1, 2022
Photo by abillion on Unsplash

製作應用型App 最常遇到的就是必須從 URL 讀取圖片,雖然可以使用URLSession 去處理,但是實在是太麻煩了,所以一般都會使用第三方程式,此在外iOS15之後,Apple 官方也推出了一個新的Image 元件是專門來讀取Remote Image 的,這篇文章會介紹 一直在使用的 SDWebImage 與官方推出的AsyncImage

SDWebImage

相信 iOS Developer 應該是無人不知,無人不曉,說到好用的Remote image third party,SDWebImage 確定是名單上的第一名,從 Objc 時代到用SwiftUI 都很好用,且也推出了很多 Coder,幾乎可以支援到所有圖片類型,是相當好用的一個套件。

使用方式在Github 上與網路上都有介紹,這裡就不細談,簡單來說就是載入所需要的 SDWebImage 套件,放到專案裡,它有支援各種第三方套件的管理程式, CocoaPods、Carthage及 Apple 的 Swift Package Manager,只要依照說明就可以很方便的載入專案裡

由於iOS 也從Objc演變到 Swift , UIKit演變到 SwiftUI,因此要載入那個SDWebImage套件就看你App使用的是什麼

Objc / Swift + UIKit

使用的套件是 SDWebImage ,其使用方式是 import SDWebImage 後呼叫sd_setImage

.Objective-C

#import <SDWebImage/SDWebImage.h>
...
[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

.Swift

import SDWebImageimageView.sd_setImage(with: URL(string: "http://www.domain.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))

SwiftUI

使用的套件是 SDWebImageSwiftUI

使用方式是import SDWebImageSwiftUI 之後呼叫 WebImage

WebImage(url: URL(string: "http://www.domain.com/path/to/image.jpg")

當然它也有很多 Modifier 可以使用,可以直接看Github 的使用說明

剛剛有說到它也出了一些Coder ,主要是為了支援原本SDWebImage 沒有支搜的圖片類型,像最近常遇到的就是 SVG 的圖檔,SVG 是向量圖的一種,在使用圖片的時候最怕的就是圖片變形,因為手機的解析度各有不同就算是iPhone 也已經出很多不同解析度的手機,更別說Android 手機了,只要圖片比例沒有處理好,就很容易變形,向量圖就不會有這種問題,但是一般Size 都會大一點。

SVG 這個圖檔,目前iOS的 Image 已經有支援,雖然不知道是那一版開始支援的,不過若SVG 的圖檔是直接放在專案裡的話,可以直接使用Image元件來讀取圖檔

那若是必須要使用URL讀取SVG 圖檔的話,SDWebImage 就有提供SVG 的Coder 就叫 SDWebImageSVGCoder

使用方式也很簡單,當然要載入 SDWebImageSVGCoder import SDWebImageSVGCoder,然後到再 AppDelegatedidFinishLaunchingWithOptions 裡寫上

let SVGCoder = SDImageSVGCoder.shared
SDImageCodersManager.shared.addCoder(SVGCoder)

若是使用SwiftUI的話也可以在Struct App 的init 中去呼叫 SDImageCodersManager.shared.addCoder(SVGCoder) ,可以參考下列文章

Objc/Swift 一樣是呼叫sd_setImage,SwiftUI 就是 WebImage

最後來說說 iOS 15之後推出的 AsyncImage

原本需要使用URLSession 才可以讀取 Remote Image 且建置十分麻煩,所以SDWebImage 才會這麼多人愛用,但是到了iOS15就有新的選擇了,就是AsyncImage !!

使用方式也是非常簡單只要呼叫 AsyncImage 就可以輕輕鬆鬆讀取到Remote Image

AsyncImage(url: URL(string: "https://example.com/icon.png"))
.frame(width: 200, height: 200)

而且,它還提供了placeholder 的部分,可以像官方寫的使用ProgressView

AsyncImage(url: URL(string: "https://example.com/icon.png")) { image in
image.resizable()
} placeholder: {
ProgressView()
}
.frame(width: 50, height: 50)

那在圖片讀到之前它都會顯示ProgressView ,若想要寫那個不知道為什麼很多App 愛用的 Shimmer 效果也是可以的

AsyncImage(url: URL(string:"https://example.com/icon.png")) 
{ image in
image
.resizable()
} placeholder: {
Color.gray
.shimmering()
}
.frame(maxWidth: .infinity, maxHeight: 350)

至於要怎麼寫出Shimmer 效果,這個Google 一下就查得到了,在這裡就不特別說明

雖然官方在SwiftUI 上已經有推出很好用的AsyncImage 不過可惜的是它並不支援SVG 圖檔,現在應該只有支援 PNG/JPG 圖檔,相信未來它應該也會支援更多的圖片格式

不過大多數的情況下Remote Image應該都是 PNG/JPG的圖檔,SVG 到是比較少見,若有特別需求的話,其實可以使用SDWebImage ,但是 SDWebImage 並無法為SVG 圖上色,若是存放在專案裡的SVG 圖可以用Image 元件進行上色,這就要好好和Designer溝通啦~

最後~祝大家 Coding 愉快~

--

--