iOS의 네트워크 추상화 프레임워크인 Moya에 대해서 정리하겠다.

Moya를 알기 전에는 Alamofire를 이용하여 네트워킹을 구현하였었다. URLSession을 이용하여도 되는데, URLSession은 사용이 복잡하고 가독성이 떨어지기에 Alamofire가 더 좋았었다.

그러나 Alamofire가 아닌 Moya를 더욱 알아야 하는 이유는 유지보수와 unit test가 힘들기 때문이다. Moya는 URLSession을 추상화한 Alamofire를 다시 추상화한 프레임워크로 Network Layer를 템플릿화 하여서 재사용성을 높히고, 개발자가 request, response에만 신경을 쓰도록 해주기에 간편하고 가독성 또한 뛰어나다는 장점이 있다.

우선 Moya를 사용하기 위해서는 CocoaPods나 Swift Package Manager 등을 통해서 install을 해야한다. 그리고 swift 파일에 import를 해주면 준비는 끝이다.

현재 개발중인 앱에서 실제 사용한 코드를 다시 회고해보며 Moya에 대해서 자세히 알아보자.


1: API target enum

import Moya

enum CommunityAPI {
    case totalCommunity
    case detailCommunity(id: String)
}

우선 enum을 선언하여 사용될 target들을 작성해야 한다. (enum은 Enumeration의 약자로 case를 열거할 때 사용하는 열거형 자료형이다.) totalCommunity(전체 커뮤니티 정보)와 detailCommunity(한 커뮤니티의 정보)를 받아오고자 한다. detailCommunity는 id를 파라미터로 받아온다.




2: TargetType 구현

extension CommunityAPI: TargetType {
    var baseURL: URL {
        guard let url = URL(string: "http://localhost:3000/api/community") else {
            fatalError("url error")
        }
        return url
    }
    
    var path: String {
        switch self {
        case .totalCommunity:
            return "/"
        case .detailCommunity(let id):
            return "/\(id)"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .totalCommunity, .detailCommunity(_):
            return .get
        }
    }
    
    var task: Task {
        switch  self {
        case .totalCommunity:
            return .requestPlain
        case .detailCommunity(let id):
            return .requestParameters(parameters: ["id" : id], encoding: URLEncoding.queryString)
        }
    }
    
    var headers: [String : String]? {
        switch self {
        default:
            return ["Content-Type": "application/json"]
        }
    }
}


extension을 통해 여러 property를 구현하여 TargetType 프로토콜을 작성한다.

  • baseURL : 서버의 endpoint 도메인
  • path : 도메인 뒤에 추가 될 경로
  • method : HTTP method (GET, POST 등)
  • task : request에 사용될 parameter
  • headers : HTTP Header 기본적으로 위의 property들은 정의해야 한다.


3: / Request를 보내고 처리

import Foundation
import Moya
import SwiftyJSON

class CommunityNetworkManager {
    static let provider = MoyaProvider<CommunityAPI>()
    
    static func getAllCommunity(completion: @escaping([Community]) -> ()) {
        provider.request(.totalCommunity) { result in
            switch result {
            case .failure(let err):
                print(err.localizedDescription)
                return
            case .success(let res):
                do {
                    let communityData = try JSONDecoder().decode([Community].self, from: res.data)
                    completion(communityData)
                } catch let err {
                    print("-----------------------", err.localizedDescription)
                    return
                }
            }
        }
    }
}

request를 보내고 성공하였다면 JSON의 형태로 받게된다. JSONDecoder를 이용하여 데이터를 파싱하고 최종적으로 화면에 띄워주자.

import Foundation


struct Community: Codable {
    var id: String = ""
    var name: String = ""
//    var offline: Bool = true
    var coach: String = ""
    var location: String = ""
    var description: String = ""
    
    enum CodingKeys: String, CodingKey {
        case id, name, coach, location, description
    }
    
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(String.self, forKey: .id)
        name = try values.decode(String.self, forKey: .name)
//        offline = try values.decode(Bool.self, forKey: .offline)
        coach = try values.decode(String.self, forKey: .coach)
        location = try values.decode(String.self, forKey: .location)
        description = try values.decode(String.self, forKey: .description)
    }
}

(아직 백엔드가 완성되지 않아 주석 처리한 부분이 있음)





참고 : https://velog.io/@dlskawns96/iOS-Moya%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%82%B9-Swift-Http-%ED%86%B5%EC%8B%A0

태그:

카테고리:

업데이트:

댓글남기기