iOS/swift

Swift) 제네릭 (Generics)활용 APICallRequest 함수 간소화

skyiOS 2023. 9. 4. 03:11
반응형
TMDB API 요청을 하다보니 요청 함수가 많아져서 방법을 찾아봤다.

CallRequest API

API요청 함수들을 보면 데이터를 받아와 Codable을 채택한 모델로 변환해서 반환 하고 있다.
요청 데이터 타입에 따라 함수가 계속 늘어난다.
//영화크루 호출
    func callRequestCredit(type: EndPoint, completionHandler: @escaping (MoviePersons) -> () ){
        let url = type.requestURL
        let header: HTTPHeaders = [
              "Authorization": APIKey.TMDBReadKey
            ]
        print(url)
        let parameters: Parameters = ["language": "ko"]
        AF.request(url,method: .get,parameters: parameters,headers: header).validate()
            .responseDecodable(of: MoviePersons.self) { response in
                switch response.result {
                case .success(let value):
                    completionHandler(value)
                case .failure(let error):
                    print(error)
                }
            }
    }
    //영화정보 호출
    func callRequestTrending(type: EndPoint,completionHandler: @escaping ([MovieResult]) -> () ){
        let url = type.requestURL
        let header: HTTPHeaders = [
              "Authorization": APIKey.TMDBReadKey
            ]
        print(url)
        let parameters: Parameters = ["language": "ko"]
        AF.request(url,method: .get,parameters: parameters,headers: header).validate()
            .responseDecodable(of: Movie.self) { response in
                switch response.result {
                case .success(let value):
                    completionHandler(value.results)
                case .failure(let error):
                    print(error)
                }
            }
    }
    // similar 비슷한영화
    func callRequestSimiler(type: EndPoint,completionHandler: @escaping ([SimilerResult]) -> () ){
        let url = type.requestURL
        let header: HTTPHeaders = [
              "Authorization": APIKey.TMDBReadKey
            ]
        print(url)
        let parameters: Parameters = ["language": "ko"]
        AF.request(url,method: .get,parameters: parameters,headers: header).validate()
            .responseDecodable(of: Similer.self) { response in
                switch response.result {
                case .success(let value):
                    completionHandler(value.results)
                case .failure(let error):
                    print(error)
                }
            }
    }
    // Videos 예고편 등등
    func callRequestVideos(type: EndPoint,completionHandler: @escaping ([VideosResult]) -> () ){
        let url = type.requestURL
        let header: HTTPHeaders = [
              "Authorization": APIKey.TMDBReadKey
            ]
        print(url)
        let parameters: Parameters = ["language": "ko"]
        AF.request(url,method: .get,parameters: parameters,headers: header).validate()
            .responseDecodable(of: Videos.self) { response in
                switch response.result {
                case .success(let value):
                    completionHandler(value.results)
                case .failure(let error):
                    print(error)
                }
            }
    }
    
    func callRequestAll(type: EndPoint,completionHandler: @escaping ([MultipleResult]) -> ()){
        let url = type.requestURL
        let header: HTTPHeaders = [
              "Authorization": APIKey.TMDBReadKey
            ]
        print(url)
        let parameters: Parameters = ["language": "ko"]
        AF.request(url,method: .get,parameters: parameters,headers: header).validate()
            .responseDecodable(of: Multiple.self) { response in
                switch response.result {
                case .success(let value):
                    completionHandler(value.results)
                case .failure(let error):
                    print(error)
                }
            }
    }

 

제네릭(Generic)활용

제네릭을 활용해서 하나의 함수로 통일 시켜보았다.
타입파라미터(T)를 Codable을 채택한 타입으로 설정 하고 T 타입으로 디코딩하여 comletionHandler로 전달한다.
func callRequest<T: Codable>(type: EndPoint, completionHandler: @escaping (T) -> ()) {
            let url = type.requestURL
            let header: HTTPHeaders = [
                "Authorization": APIKey.TMDBReadKey
            ]
            let parameters: Parameters = ["language": "ko"]
            
            AF.request(url, method: .get, parameters: parameters, headers: header).validate()
                .responseDecodable(of: T.self) { response in
                    switch response.result {
                    case .success(let value):
                        completionHandler(value)
                    case .failure(let error):
                        print(error)
                    }
                }
        }

데이터 요청

변경전 : 요청하는 데이터 타입마다 함수를 여러개 만들어 필요한 함수를 요청한다.
변경후 : callRequest 하나의 함수에 요청할 타입파라미터의 타입을 지정하여 요청한다.
//        변경전
//        MovieAPIManager.shared.callRequestTrending(type: .trending(page)){ responseMovieList in
//            self.movieList += responseMovieList
//            self.mainView.movieCollectionView.reloadData()
//        }
//        MovieAPIManager.shared.callRequestVideos(type: .videos(id)) { data in
//            print("------------------------------videos",data)
//            self.similerVideosList = []
//            self.similerVideosList = data
//            self.mainView.creditTableView.reloadData()
//        }


// 		변경후
MovieAPIManager.shared.callRequest(type: .trending(page)) { (data: Movie) in
    self.movieList += data.results
    self.mainView.movieCollectionView.reloadData()
}

MovieAPIManager.shared.callRequest(type: .videos(id)) { (data: Videos) in
    self.similerVideosList = []
    self.similerVideosList = data.results
    self.mainView.creditTableView.reloadData()
}
제네릭을 이용하여 비슷한 API요청을 하나의 함수로 만들 수 있다.

 

반응형

 

반응형