티스토리 뷰

반응형

 

안녕하세요 :) Zedd입니다.

iOS15에서 SwiftUI에 이것저것 많이 나왔는데, 그중 반가운게 하나 있더라구요~

SwiftUI에서 네트워크 요청을 해야할 때 요청을 시작하는 부분이..대부분 onAppear였는데요.

var body: some View {
    List {
        ForEach(self.viewModel.names, id: \.self) { name in
            Text(name)
        }
    }
    .onAppear {
        self.viewModel.requestNames() ✅
    }
}

iOS 15에서 task modifier가 나왔습니다! 

 

# task

정의는 

view가 나타날 때(view appears) 수행할 비동기 작업을 추가합니다.


즉 네트워크 요청을 넣기 딱 좋은 위치가 된겁니다!

var body: some View {
    List {
        ForEach(self.viewModel.names, id: \.self) { name in
            Text(name)
        }
    }.task ✅ {
        self.viewModel.requestNames() ✅
    }
}

이렇게 말이죠. (물론 iOS 15부터 사용가능해서 버전 분기 처리가 필요할 수도 ^^...)

 

task가 onAppear에 비해 좋은점은, 이 task가 modifier로 추가된 view의 수명과 일치하는 수명을 가집니다.

1. task에 넣은 (비동기) 작업이 완료됨 -> View가 사라짐 -> 상관없음

2. task에 넣은 (비동기) 작업이 완료되지 않음 -> View가 사라짐 -> ??

2번의 경우 View가 사라졌으니 task에 넣은 작업이 취소되어야겠죠? 그걸 SwiftUI가 대신 해줍니다.

즉, task의 넣은 작업이 완료되기 전에 View가 사라지면 SwiftUI가 task에 있던 작업을 취소해줍니다.

 

task안에 비동기 작업을 넣은 예제를 만들어봅시다!

굳이굳이 async/await을 쓴다면

[ViewModel]

class TestViewModel: ObservableObject {
    
    var urls = [
        "https://zeddios.tistory.com",
        "https://brunch.co.kr/@zedd"
    ]
    
    @Published var htmls: [String] = []
        
    func requestHTMLs() async throws  {
        do {
            for url in self.urls {
                let (data, _) = try await URLSession.shared.data(from: URL(string: url)!)
                let str = String(data: data, encoding: .utf8)!.suffix(50)
                
                DispatchQueue.main.async {
                    self.htmls.append(String(str))
                }
            }
        } catch {
            
        }
    }
}

물론 보통 ViewModel에서 URLSession을 호출하지 않겠지만 ㅎ 일단은 예제니까 이렇게 합니다.

(강제언래핑도 ㅎ)

[View코드]

var body: some View {
    List {
        ForEach(self.viewModel.htmls, id: \.self) { html in
            Text(html)
        }
    }.task {
        try? await self.viewModel.requestHTMLs() ✅
    }
}

 

iOS15에서 새로나온 SwiftUI기능들을 대충만 알고있는데, 한번 훑어보는게 좋겠네요! 

 

반응형