[MVVM] 1. Model , Service 구현 (Alamofire) - 1

miori·2022년 6월 15일
0

ios-MVVM

목록 보기
2/6
post-thumbnail

mvvm 부시기 🫡

API 소개

사용할 API 는 "네이버의 검색 API 중 쇼핑 검색결과를 출력해주는 REST API" 이다. 네이버 API 링크 에 자세한 소개가 나와있다.

Model

postman을 활용해, 응답결과를 확인해보았다.
응답 json 은 다음과 같다.

{
    "lastBuildDate": "Wed, 15 Jun 2022 15:18:06 +0900",
    "total": 14182,
    "start": 1,
    "display": 1,
    "items": [
        {
            "title": "마이나믹 <b>무릎보호대</b> 헬스 등산 스쿼트 테이핑 아대 <b>크로스핏</b> 니슬리브",
            "link": "https://search.shopping.naver.com/gate.nhn?id=29274544625",
            "image": "https://shopping-phinf.pstatic.net/main_2927454/29274544625.20220217164716.jpg",
            "lprice": "49000",
            "hprice": "",
            "mallName": "네이버",
            "productId": "29274544625",
            "productType": "1",
            "brand": "마이나믹",
            "maker": "",
            "category1": "스포츠/레저",
            "category2": "보호용품",
            "category3": "무릎보호대",
            "category4": ""
        }
    ]
}

이를 토대로 응답을 받을수 있는 모델을 만들어주었다.

struct ShoppingResponse : Decodable {
    let total : Int
    let items : [ShoppingItems]
}

struct ShoppingItems : Decodable {
    let title : String
    let link : String
    let image : String
    let lprice : String
    let brand : String
}

extension ShoppingResponse {
    static let EMPTY = ShoppingResponse(total: 0, items: [])
}

json의 구조를 보면 key-value형식이고 items는 key-value를 가진 배열형식이다.

따라서 우선 ShoppingItems 라는 구조체를 선언해주고, 그안에는 items의 배열내 key-value쌍을 넣어주었다.
그다음, ShoppingResponse 라는 구조체를 선언해주고, 전체 검색결과수를 나타내는 total key값과 위에서 선언한 ShoppingItems를 배열로 갖는 items key를 선언해주었다.

사용할 키값들만 받아왔고, 이때 total 값은 추후에 무한스크롤을 구현할 때 필요한 요소이기때문에 받아왔다.

Service - Alamofire

  • Alamofire는 http 프로토콜을 사용하는 통신 라이브러리이다

구현 내용

- fetch

private let api = ShoppingAPI()

var searchedData : ShoppingResponse = ShoppingResponse.EMPTY
var addedData : ShoppingResponse = ShoppingResponse.EMPTY
var startNum : Int = 1

func getItmes(_ query : String , onCompleted : @escaping (ShoppingResponse) -> Void) {
    
    startNum = 1
    guard let url = api.searchItems(query: query, start: startNum).url else { return }
            
    AF.request(url, method: .get, parameters: nil, encoding: JSONEncoding(), headers: ShoppingAPIHeader.HEADERS)
        .validate()
        .responseDecodable(of: ShoppingResponse.self) { response in
            switch response.result {
            case .success(let response):
                self.searchedData = response
                onCompleted(self.searchedData)
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
}

함수 파라미터부터 정리를 해보겠다.

  • query : 검색어를 입력 받을 파라미터

그리고, escaping closure(탈출클로저)를 활용하여, 함수가 종료후에 호출이 필요한 작업을 선언하였다.
비동기 작업으로 함수가 종료되고 그 이후에 호출이 필요한 클로저가 있다면, escaping closure(탈출클로저)를 사용하면 된다.

startNum = 1 이 코드는 추후에 무한스크롤을 구현할때 초기화를 위해 선언한 값이다. 무한스크롤 부분에서 자세히 설명해보도록 하겠다.

이제, 통신하는 부분을 보면 클라이언트인 내가 서버한테 원하는 데이터를 요청해야하므로, GET 방식을 사용하였다.

responseDecodable를 통해 구현했던 응답 모델로 디코딩이 가능하다.

switch 구문을 통해 성공을 했을때, onCompleted 를 호출해주었다.

물론 실패의 경우도 성공처럼 onCompleted 를 통해 에러를 전달해줘야하지만, 간단한 MVVM 연습이기에 생략하였다.


다음번에, 이어서, 무한스크롤 구현 부분에 대해 정리해보겠다.

profile
iS를 공부하는 miori 입니다.

0개의 댓글