SwiftUI
이 글은 alamofire와 같은 외부라이브러리를 사용하지 않는 아주 기초적인 방법입니다!
mockapi.io에서 샘플을 만들면 아래와 같은 데이터를 생성해 줍니다.
https://62bbeeb36b1401736cecefcf.mockapi.io/user
데이터는 다음과 같이 구성했습니다.
struct User: Codable, Identifiable {
var createdAt: String
var name: String
var avatar: String
var id: String
}
json데이터를 가져오기 위해 메인으로 작성되는 class는 이 전 글과 동일합니다.
class network {
func getJSON(completion : @escaping ([User]) -> Void ) {
guard let url = URL(string: "https://62bbeeb36b1401736cecefcf.mockapi.io/user") else {
print("url error")
return
}
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let realData = data else {
print("data error")
return
}
do{
let allUser = try JSONDecoder().decode([User].self, from: realData)
completion(allUser)
}catch{
print("error: \(error)")
}
}.resume()
}
}
이미지url을 통해 이미지를 가지고 와서 저장하는 imageLoader라고 하는 class를 구현한다.
ObservableObject는 말그대로 관찰가능한 Object이다.
@Published로 선언한 프로퍼티의 값이 변경되면 해당 프로퍼티가 있는 클래스를 관찰하고 있는 곳의 View가 이를 감지하여 View를 렌더링 한다.
network.swift
class imageLoader: ObservableObject {
@Published var image: UIImage?
var urlString: String
init(urlString: String){
self.urlString = urlString
self.loadImageURL()
}
func loadImageURL(){
guard let url = URL(string: urlString) else {
return
}
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let realData = data else {
return
}
guard let realImage = UIImage(data: realData) else {
return
}
self.image = realImage
}.resume()
}
}
@Published를 관찰하기 위해서는 @ObservedObject를 사용해야 한다.
imageLoader의 image 프로퍼티를 관찰하고 있다가 값이 변경되면 View를 다시 렌더링한다.
struct URLImage: View{
@ObservedObject var loader: imageLoader
init(urlString: String){
self.loader = imageLoader(urlString: urlString)
}
var body: some View{
Image(uiImage: loader.image ?? UIImage())
.resizable()
}
}
💡 이미지 렌더링 순서
1. URLImage을 초기화 할 때 urlString에 이미지 링크를 보낸다.
2. 받은 urlString을 imageLoader객체에 보낸다.
3. 받은 urlString을 통해 imageLoader에서 통신을하고, 데이터를 받아오면 image에 넣어준다.
4. image는 @published이기 때문에 통신이 끝나고 값이 변경되면 뷰를 렌더링한다.
ContentView.swift
@State private var allUser = [User]()
var body: some View {
ScrollView {
LazyVGrid(columns: [GridItem(.flexible())], content: {
ForEach(allUser){ user in
HStack(){
URLImage(urlString: user.avatar)
.frame(width: 100, height: 100)
Text(user.name)
.foregroundColor(.black)
Spacer()
}
}
}).onAppear {
network().getJSON { allUser in
self.allUser = allUser
print("onAppear: \(allUser)")
}
}
}
}
결과
코드 전체보기
https://github.com/sladuf/SwiftUI_practice/tree/main/practice_imageAPI
'📱 iOS > SwiftUI' 카테고리의 다른 글
디바이스 화면고정 portrait only (0) | 2022.07.25 |
---|---|
[SwiftUI] Grid속성 (0) | 2022.07.05 |
URLSession을 통해JSON 가져오기 (1) (0) | 2022.06.28 |
Auto Layout 1 [Why?] (0) | 2022.05.31 |
[SwiftUI] 데이터 바인딩 (1/5) @State (0) | 2021.10.11 |