๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐ŸŽ iOS & Swift

[Alamofire Mapper] URLRequestConvertible ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

Alamofire ์กฐ๊ธˆ ๋” ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•ด๋ณด์ž

 

๋“ค์–ด๊ฐ€๊ธฐ ์ „์—

Alamofire ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด URLRequest๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”

URLRequestConvertible์ด๋ผ๋Š” ํ”„๋กœํ† ์ฝœ์ด ์žˆ๋”๋ผ๊ตฌ์š”?

 

ํ•ญ์ƒ ๊ธฐ๋ณธ์ ์ธ request ๋ฉ”์„œ๋“œ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋˜

์šฐ๋ฆฌ...

์•„๋‹ˆ ๋‚˜ ์ž์‹ ...


์กฐ๊ธˆ ๋” ์„œ๋น„์Šค ์ฝ”๋“œ๋ฅผ ์ž˜ ์ž‘์„ฑํ•ด์„œ ์‚ฌ์šฉํ• ์ˆ˜๋Š” ์—†๋Š”์ง€ ๊ณ ๋ฏผํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์•„์ง ๊ฐˆ ๊ธธ์ด ๋ฉ€์ง€๋งŒ ์กฐ๊ธˆ ๋” ๋ฐฐ์›Œ๋ณด์ž๋ผ๋Š” ์ƒ๊ฐ์œผ๋กœ ์—ด์‹ฌํžˆ ํ•ด๋ด์•ผ์ฃ ~

 

๊ธฐ์กด vs ๊ฐœ์„ 

๊ธฐ์กด ์„œ๋น„์Šค ์ฝ”๋“œ

  • ๊ฐ ์„œ๋น„์Šค๋งˆ๋‹ค ๋งค๋ฒˆ ๋น„์Šทํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ์„ ํ•˜๊ณ  ์žˆ์–ด ํšจ์œจ์„ฑ์—์„œ ์ข‹์ง€ ์•Š์•„ ๋ณด์ž…๋‹ˆ๋‹ค.
  • (์ €๋งŒ ๊ทธ๋Ÿฌ๋Š” ๊ฑธ๊นŒ์š”...ใ…Žใ…Ž ํ†ต์‹  ์ฝ”๋“œ ์ž‘์„ฑํ•˜๋Š” ๊ฑฐ ๋น„์Šทํ•ด์„œ ๋งจ๋‚  ๋ณต๋ถ™ํ•œ๋‹ค์Œ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋ฐ”๊พธ๋Š”... ^^)

์„œ๋น„์Šค ์ฝ”๋“œ ์ž‘์„ฑ๋ถ€
์„œ๋น„์Šค ์ฝ”๋“œ ์‚ฌ์šฉ๋ถ€

 

๊ฐœ์„ ํ•œ ์„œ๋น„์Šค ์ฝ”๋“œ

  • ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋Š” APIRouter์—์„œ ํ•˜๊ณ  ์žˆ๊ณ , APIClient์— ์ž‘์„ฑํ•œ ํ•จ์ˆ˜ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•ด์„œ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋ฅผ ๋ณด๋ฉด, ํ•˜๋‚˜์˜ request๋ฅผ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ endpoint์— ๋Œ€ํ•œ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์Œ

 

์ผ์ •์„ ์กฐํšŒ(GET)ํ•˜๋Š” ํ†ต์‹ 
์—ฌํ–‰์„ ์ถ”๊ฐ€(POST)ํ•˜๋Š” ํ†ต์‹ 

 

์ฝ”๋“œ - Networks/

Networks ํด๋”๋ง ๋ชจ์Šต

 

APIConstants

  1. API ํ†ต์‹ ์— ์‚ฌ์šฉํ•  ๋‹ค์–‘ํ•œ ์ƒ์ˆ˜๋“ค์„ ๋ชจ์•„๋†“์€ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
 import Foundation

 struct APIConstants {
     // MARK: - Start Endpoint
     static var baseURL: URL {
         return URL(string: "http://13.209.82.176:5000")!
     }

     static let token = ""
 }

 enum HTTPHeaderField: String {
     case authentication = "Authorization"
     case contentType = "Content-Type"
     case acceptType = "Accept"
     case acceptEncoding = "Accept-Encoding"
     case xAuthToken = "x-auth-token"
 }

 enum ContentType: String {
     case json = "application/json"
 }

 

APIRouter

  • Endpoint๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  • HTTPMethods, Path, Parameter, Encoding ๋ฐฉ์‹์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
import Foundation

import Alamofire

enum APIRouter: URLRequestConvertible {
    // MARK: - Cases
    case getTravels
    case addTravel(travelName: String, destination: String, startDate: String, endDate: String, imageIndex: Int)
    case getSchedules(groupId: String, date: String)
    
    // MARK: - Methods
    var method: HTTPMethod {
        switch self {
        case .getTravels, .getSchedules:
            return .get
        case .addTravel:
            return .post
        }
    }
    
    // MARK: - Paths
    var path: String {
        switch self {
        case .getTravels, .addTravel:
            return "/travel"
        case .getSchedules(let groupId, let date):
            return "/schedule/daily/\(groupId)/\(date)"
        }
    }
    
    // MARK: - Parameters
    private var parameters: Parameters? {
        switch self {
        case .getTravels, .getSchedules:
            return nil
        case .addTravel(let travelName, let destination, let startDate, let endDate, let imageIndex):
            return [
                "travelName": travelName,
                "destination": destination,
                "startDate": startDate,
                "endDate": endDate,
                "imageIndex": imageIndex
            ]
        }
    }
    
    // MARK: - Encodings
    var encoding: ParameterEncoding {
        switch self {
        case .getTravels:
            return URLEncoding.default
        default:
            return JSONEncoding.default
        }
    }
    
    // MARK: - URL Request
    func asURLRequest() throws -> URLRequest {
        let url = APIConstants.baseURL.appendingPathComponent(path)
        var urlRequest = URLRequest(url: url)
        
        // HTTP Method
        urlRequest.method = method
        
        // Common Headers
        urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
        urlRequest.setValue(APIConstants.token, forHTTPHeaderField: HTTPHeaderField.xAuthToken.rawValue)
        
        // Parameters
        if let parameters = parameters {
            return try encoding.encode(urlRequest, with: parameters)
        }

        return urlRequest
    }
}

 

 

APIClient

  • Service ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  • responseDecodable์„ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
import Foundation

import Alamofire

class APIClient {
    
    typealias onSuccess<T> = ((T) -> Void)
    typealias onFailure = ((_ error: Error) -> Void)
    
    static func request<T>(_ object: T.Type,
                                  router: APIRouter,
                                  success: @escaping onSuccess<T>,
                                  failure: @escaping onFailure) where T: Decodable {
        AF.request(router)
            .validate(statusCode: 200..<500)
            .responseDecodable(of: object) { response in
                switch response.result {
                case .success:
                    guard let decodedData = response.value else { return }
                    success(decodedData)
                case .failure(let err):
                    failure(err)
                }
        }
    }
    
}

 

๋งˆ๋ฌด๋ฆฌ

์‚ฌ์‹ค์ƒ ์œ„์— 3๊ฐœ์˜ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด๋†“๊ณ  ์‚ฌ์šฉํ•˜๋‹ˆ,
๋งค ํ†ต์‹ ๋งˆ๋‹ค ์„œ๋น„์Šค ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ˆ˜๊ณ ๋ฅผ ๋œ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•„๋ณด์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์ข‹๋‹ค๋Š” ์ƒ๊ฐ์€ ํ•˜์ง€ ์•Š๋Š” ๊ฑธ๋กœ ํ•ด์•ผ๊ฒ ์–ด์š”...
์ €๋„ ์ด์ œ ๋ง‰ ์œ„์˜ ๋ฐฉ์‹์„ ์ ์šฉํ•ด๋ณด๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€๋ผ ๋ง‰ ์ถ”์ฒœํ•˜๊ธฐ๋Š” ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™๋„ค์š” ๐Ÿ‘€

 

์ข€ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๋” ๊ณ ๋ฏผํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค :-)

 

์ด๋ฒˆ ๊ธ€์€ ํ•ต์‹ฌ๋งŒ ์ ์–ด๋†”์„œ,,, ๋‚ด์šฉ์„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”...

๋งŒ์•ฝ ๊ทธ๋ ‡๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ์—ฐ๋ฝ์ฃผ์„ธ์š” ..

 

์ฐธ๊ณ ๋งํฌ