티스토리 뷰

iOS

[iOS] Alamofire 순서대로 API 실행하기

Kim_Baechu 2021. 2. 23. 12:10

1. DispatchGroup과 DispatchQueue 만들기

let dispatchGroup = DispatchGroup()
let queue = DispatchQueue(label: "queue", qos: .default, attributes: .concurrent)

dispatchGroup은 한 단위로 모니터하는 작업 그룹입니다.

dispatchQueue는 실행 작업을 계획합니다.

 

2. 첫 번째 실행되는 API

func getReviewList() {
    showIndicator()
    NetworkService.getData(type: .getReviews, headers: nil, parameters: nil) { [weak self] (result: Result<Reviews,APIError>) in
        switch result {
        case .success(let model):
            self?.reviews = model
                self?.getProduct(review: model)
            print("#1")
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
}

이 함수를 통해서 리뷰목록을 불러오도록 하겠습니다.

이 모델에는 리뷰가 배열로 담겨있습니다.

// MARK: - Reviews
struct Reviews: Codable {
    let isSuccess: Bool
    let code: Int
    let message: String
    let result: [Review]
}

// MARK: - Review
struct Review: Codable {
    let reviewID, productID, userNo: Int
    let userName: String
    let profileImageURL: String
    let star: Double
    let content: String
    let picture: [Picture]
    let createDate: String

    enum CodingKeys: String, CodingKey {
        case reviewID = "reviewId"
        case productID = "productId"
        case userNo, userName, profileImageURL, star, content, picture, createDate
    }
}

// MARK: - Picture
struct Picture: Codable {
    let pictureID: Int
    let pictureURL: String
    let status: String

    enum CodingKeys: String, CodingKey {
        case pictureID = "pictureId"
        case pictureURL, status
    }
}

 

2. 두 번째 실행되는 API

func getProduct(review: Reviews) {
    review.result.enumerated().forEach { (index, model) in
        dispatchGroup.enter()
        let id = String(model.productID)
        NetworkService.getData(type: .getProduct(id), headers: nil, parameters: nil) { [weak self] (result: Result<Product,APIError>) in
            switch result {
            case .success(let model):
                self?.products[index] = model.result
                print("#2", index)
            case .failure(let error):
                print(error.localizedDescription)
            }
            self?.dispatchGroup.leave()
        }
    }
    
    dispatchGroup.notify(queue: queue) {
        DispatchQueue.main.async {
            self.reviewTableView.reloadData()
            self.dismissIndicator()
            print("#3")
        }
    }
}

리뷰에는 productID가 있는데 이 ID를 상품정보를 받아오는 API에서 사용합니다.

그래서 리뷰를 불러오고 -> 상품정보를 불러와야합니다.

 

모든 작업이 끝나면 .notify 를 이용해서 다음 동작을 처리 할 수 있습니다.

여기서는 테이블 뷰를 리로드하고 인디케이터를 사라지게 했습니다.

 

alamofire를 어떻게 사용하냐에 따라서 식은 달라질 수 있지만

dispatchGroup.enter()와 dispatchGroup.leave()만 정확한 위치에 넣어주시면 원하는 결과를 얻으실 수 있습니다.

 

3. 실행 결과

댓글
공지사항