Completion Handler
- 비동기 작업이 완료되었을 때 실행되는 코드 블록 (callback)
- 주로 비동기 작업의 결과나 상태를 전달하고 처리하는 용도로 사용
- 비동기 작업이 완료되면 그 결과를 즉시 처리
- 일반적으로 함수의 매개변수로 전달되며, 작업이 완료된 후에 호출
- 이때 작업의 성공 여부나 결과 등을 전달 가능
- 일반적으로 'Result' 타입이나 옵셔널, 매개변수 목록을 이용하여 결과 전달
비동기적으로 데이터를 가져오는 함수 예시
func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
let url = URL(string: "https://example.com/data")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
} else if let data = data {
completion(.success(data))
} else {
// 데이터가 없는 경우에 대한 처리
}
}.resume()
}
- 'fetchData(completion:)' 함수 : 비동기적으로 데이터 가져오고 작업이 완료되면 Completion Handler를 호출하여 결과 전달
- Completion Hander는 'Result<Data, Error>' 타입을 받음
- 작업의 성공시 'Result.success(data)' 전달
- 작업 실패시 'Result.failure(data)' 전달
- 작업이 완료되면 Result<Data, Error> 타입의 결과와 성공 여부 전달
- @escaping : 클로저가 함수의 범위를 벗어나서 실행될 수 있음을 알림. 작업이 완료 후 completion Handler가 호출될 때 클로저가 함수 외부에서 실행되기 때문에 @escaping 키워드 사용
- 외부에서 실행되는 클로저는 아래 ViewDidLoad()에서 실행 중인 'fetchData { result in ...}' 부분을 뜻함
- '(Result<Data, Error>) -> Void' : 클로저 타입
- Result<Data, Error> 타입으로 입력을 받고 반환 값이 없는 Void 형태를 가지는 함수. 성공 또는 실패의 결과를 나타내는 열거형
fetchData(completion:) 함수 호출
override func viewDidLoad() {
super.viewDidLoad()
fetchData { result in
switch result {
case .success(let data):
// 데이터를 가져오는 작업이 성공한 경우
self.handleSuccess(data: data)
case .failure(let error):
// 데이터를 가져오는 작업이 실패한 경우
self.handleError(error: error)
}
}
}
- fetchData를 실행하고 비동기 작업이 완료되면 { result in ... } 클로저를 실행하는 구문
- fetchData(completion:) 함수를 호출하면 비동기 작업이 시작
- 작업이 완료되면 completion handler 호출
- completion handler의 매개변수 'result' 는 Result<Data, Error> 타입으로 작업의 성공 여부와 결과 전달
- 비동기 작업의 결과에 따라 result를 분기하여 처리
- 성공하면 handleSuccess() 메서드를 호출하여 data를 처리, 실패하면 handleError() 메서드 호출하여 에러 처리
전체 코드
import UIKit
class CompletionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
fetchData { result in
switch result {
case .success(let data):
// 데이터를 가져오는 작업이 성공한 경우
self.handleSuccess(data: data)
case .failure(let error):
// 데이터를 가져오는 작업이 실패한 경우
self.handleError(error: error)
}
}
}
func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
let url = URL(string: "https://example.com/data")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
} else if let data = data {
completion(.success(data))
} else {
// 데이터가 없는 경우에 대한 처리
}
}.resume()
}
func handleSuccess(data: Data) {
// 데이터를 성공적으로 처리하는 로직
}
func handleError(error: Error) {
// 에러를 처리하는 로직
}
}
참고)
https://lxxyeon.tistory.com/202
'Swift' 카테고리의 다른 글
Swift - UIKit, SnapKit 비교 (0) | 2023.07.23 |
---|---|
Swift - PickerView (0) | 2023.07.19 |
Swift - 비동기처리(async / await) (0) | 2023.07.14 |
Swift - sort, sorted 함수 비교 (0) | 2023.07.13 |
Swift - 고차함수 (compactMap, flatMap) (0) | 2023.07.12 |