티스토리 뷰

2022.12.26 - [iOS개발/Swift 통신] - Swift ObjectMapper 사용해보기

 

Swift ObjectMapper 사용해보기

일반적으로 통신을 하게 되면 서버에 무언가를 요청하거나 혹은 서버에서 값을 받아오게 되는데 이때 이를 도와주는 도구중 하나인 ObjectMapper 를 이야기해볼까합니다. (저의 경우 Alamofire 와 같

world-of-larooly.tistory.com

위 글과 어느 정도 연관된 내용입니다. 

 

* Alamofire 는 어디에 쓰나요?

- 서버와 데이터를 주고 받을때 쓰는 api 중 하나입니다. 

 

하지만 저희는 지금 서버가 없죠?

그래서 이번에는 임시 사이트에서 데이터 가져오는것만 목표로 할께요.

 

이번 포스트에서는 서버에서 값을 받아오는 기본적인 방법만 알아보겠습니다. 

(파라미터를 보내거나 이미지를 보내는건 따로 올릴 생각입니다.)

 

시작하기 전에 Podfile 에 아래 두개를 추가해주세요 (ObjectMapper 는 필수가 아니지만 저는 사용할거라 추가했습니다.)

pod 'Alamofire'
pod 'ObjectMapper'

* ObjectMapper : 가져온 데이터를 다루기 편한 모양으로 변환하기 위해 사용할 예정입니다. 

import Alamofire
import ObjectMapper

 

그리고 서버를 대신하여 아래 사이트를 사용할겁니다.

(뒤 photos 말고 아래 이미지에 보이는 단어로 바꾸셔도 됩니다.)

https://jsonplaceholder.typicode.com/photos

요 사이트의 힘을 빌릴겁니다.

실제로 제가 넣은 사이트로 들어가보면 

https://jsonplaceholder.typicode.com/photos

이런 식으로 값이 보일 겁니다.

이번 포스팅의 목표는 저 값들을 받아오는 걸 목표로 하겠습니다. 

저는 받아온 값을 가공해 사용할 꺼라 ObjectMapper로 데이터 형식을 하나 만들겠습니다. 

(형식은 만들기 나름입니다!)

import ObjectMapper
class DummyImage : Mappable{
    var id : Int = 0
    var memberid : Int = 0
    var title : String = ""
    var smallImageUrl : String = ""
    var bigImageUrl : String = ""
    
    required init?(map: Map) {
        
    }
    
    func mapping(map: Map) {// 어떤 값을 어떻게 저장할 것인가
        self.id <- map["albumId"]
        self.memberid <- map["id"]
        self.title <- map["title"]
        self.smallImageUrl <- map["thumbnailUrl"]
        self.bigImageUrl <- map["url"]
    }

}

 

근데 사실 생각보다 무지 간단합니다. 

(참고로 responseJSON 이게 Deprecated 되었다고 합니다.)

func loadSamples(){// 가져오기
    let url = "https://jsonplaceholder.typicode.com/photos"
    let alfire = AF.request(url).responseData{response in
    switch response.result {// 결과 값 가져오기 
    case .success(let data):// 통신 성공
        do {// 전환하다 실패하는 경우를 위해 
            let value = try JSONSerialization.jsonObject(with: data , options: .mutableContainers)
            print(value)
            let port = Mapper<DummyImage>().mapArray(JSONObject: value)
            if(port != nil){
                //받아온 값으로 하고싶은걸 하시면 됩니다. 
            }
        }catch {
            print("Failed")
        }
    case .failure(let error): // 통신 실패 
        print(error.localizedDescription)
    }
}

실제로 저부분의 port 값을 브레이크를 찍어보면 아래처럼 값이 들어갔다는걸 알 수 있습니다.

각 항목에 잘 들어갔죠?

 

 

참고로 데이터를 가져오는데 많이 오래 걸리는 경우 아래를 추가해 표현할 수 있습니다.

AF.request(url).responseData{response in 
...
}.downloadProgress{progress in
    print("percent : \(progress.fractionCompleted)")
}

해당 부분 (downloadProgress)은 진행 정도를 알려주는 부분입니다. 

(반대로 uploadProgress 도 존재합니다.)

필요하신 분들은 참고해주세요. 

 

기본 모양은 별로 안 어렵죠? 

 

그럼 만약 특정 URL에 있는게 파일이나 영상이면 어떻게 해야할까요?

기본 구조는 동일합니다.

func downloadVideo(){
    AF.request("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4").downloadProgress(closure : { (progress) in
        print(progress.fractionCompleted)           
    }).responseData{ (response) in
        print(response)
        if let data = response.value {

            self.saveInTmp(data: data)
        }
    }
}

아래는 Temp 에 저장하는 함수입니다. 참고하실분들은 참고해주세요. 

func saveInTmp(data : Data){
        let tmpUrl = FileManager.default.temporaryDirectory
        let videoUrl = tmpUrl.appendingPathComponent("video.mp4")
        do{
            try data.write(to: videoUrl)
        } catch {
            print("fail")
        }
    }

별로 다르지 않죠? 

 

지금은 비교적 단순한 통신이라 간단해 보이지만 

여기에 몇가지 설정이 추가되면 복잡해 보일 수 있습니다.

 

그부분에 대해서는 다음 포스트에 알아보도록 합시다. 

 

일단 기초적인 것부터 천천히 알아가도록 합시다. 

 

그럼 오늘도 파이팅입니다.

댓글