드디어 시작하는 SandboxProject
깃허브 세팅이 끝났으니 진짜 코딩을 해보려 한다.
이전에 여기서 언급한 적이 있는 간단한 코드를 짜보고,
새로운 디자인패턴, 새로운 라이브러리 등을 적용해보며 리팩토링 해 나가는 경험을 쌓아보려한다.
뭐 대충 이런 식으로 이미지, 텍스트 등을 담은 HTTP API를 받아와서 띄워주는 간단한 프로젝트를 만들어볼 예정이다.
내가 취준하는 당시 보통의 회사들에서 받은 과제전형들이었고,
2년차 3년차 채용공고로 올라갈 수록 제한사항들이 늘어나는 식이었고, 큰 틀은 변하지 않았다.
- 받은 이미지 캐싱 처리하기
- 일부로 던져주는 깨진 데이터에 대해 에러 처리하기
(이건 솔직히 내가 일일히 Json 찍어보지 않았으면 이런 함정이 숨어있단 걸 몰랐을 것이다) - 내려온 이미지, 텍스트 데이터를 활용해서 게시판 리스트 형식의 테이블 뷰 만들기
- 가장 하단까지 스크롤 했을 때 새로 fetch해서 데이터 불러오기
- 랜덤으로 받은 json에 담긴 미디어가 이미지인지 영상인지 확인하고 분기처리하기
- 구조체 안에 담긴 미디어가 배열 형식으로 내려와서 미디어가 하나일 경우 기본으로 세로 스크롤, 여러개일 경우 가로 스크롤 추가하기
- 특정 디자인 패턴 적용하기, 특정 라이브러리 사용하기, 써드파티 라이브러리 사용하지 않기 등등...
뭐 이런 제약사항들이 더 많았지만 대충 이런 형식이었다.
더 자세하게 적기엔 과제들로 특정 될 수 있을 것 같아 자세하게 적지도 못하겠다.
어찌됫든 이번에는 회사에서 내주었던 이러한 채용 과제들을 기억을 더듬어 가며 다시 만들어보려한다.
그리고 기존에 MVC 패턴에 퍼스트파티 라이브러리로만 만들었던 내 과제들을
MVVM 패턴을 적용시켜본다던가, RxSwift나 Alamofire 같은 써드파티 라이브러리를 적용시켜본다던가 하며 한번 공부해 보려 한다.
서두가 너무 길었다. 본론으로 들어가보겠다.
Model 생성
내가 받아올 HTTP API는 picsum에서 받아올 예정이다.
그냥 랜덤한 더미 이미지와 텍스트를 제공해주는 사이트이다. 쿼리에 따라 다양한 조건도 추가할 수 있고,
뭐 다양한 기능을 제공하지만 난 그냥 평범하게 이미지랑 텍스트 데이터만 받아오겠다.
이미지 데이터는 이렇다고 친절히 설명까지 해준다.
그럼 받아올 JSON 형태의 구조체부터 한번 만들어보도록 하자.
JSON 타입 변환 사이트는 기존에 많은데 보통 나는 quicktype 여기를 많이 활용한다.
JSON 타입의 텍스트를 복사해서 여기에 붙여넣으면,
이렇게 이쁘게 Swift에서 활용할 수 있는 구조체 모델로 변환 시켜 준다.
코드는 이런 식이 된다.
struct ImageData: Codable {
let id: String
let author: String
let width: Int
let height: Int
let url: String
let downloadURL: String
enum CodingKeys: String, CodingKey {
case id, author, width, height, url
case downloadURL = "download_url"
}
}
Codable
먼저, 채택한 Codable에 대해 알아보자.
Codable은 Decodable 프로토콜과 Encodable 프로토콜을 결합한 타입 별칭(Type Alias)이다.
자신을 외부 표현으로 변환하거나 외부 표현을 변환할 수 있는 형식이라고 설명이 되어있다.
보통 여기서 말하는 외부 표현은 JSON 타입으로 변환을 가장 많이 사용하게되는데,
Decoding을 하든지 Encoding을 하든지 하는 구조체, 열거형, 클래스에서 채택을 하여 활용하면 된다.
우리는 데이터를 받아오기만 할 것이기 때문에 Decoding만 한다고 생각하면 된다.
(그렇기에 사실 이 프로젝트에서는 Decodable 프로토콜만을 채택해도 상관은 없다)
구조체 안의 CodingKey 프로토콜을 채택한 열거형은
카멜 케이스를 사용하는 Swift의 변수명명법에 맞춰 스네이크 케이스로 표기된 Json을 코드 내에서는 카멜 케이스에 맞춰 명명하겠다는 의미이다.
JSON은 보통 String 타입이기에 String 타입을 상속하여 Raw Value 타입을 String 타입으로 선택한 것도 볼 수 있다.
JsonDecoder로 JSON 파싱하기
JSON을 받을 구조체 모델도 생성했으니 이제 Json을 파싱할 수 있게 코드를 짜 주겠다.
아까도 말했지만 우린 데이터를 받기만 할 것이니 Encoder말고 Decoder만 사용해 주겠다.
JSON 객체에서 데이터 유형의 인스턴스를 디코딩하는 객체라고 설명이 되어있다.
활용법은 어렵지 않다. JSON 타입의 문자열을 구조체로 바꿔주기 위한 코드는 이런 식으로 하면 된다.
func parseJSON(_ jsonData: Data) -> ImageData? {
let imageData = try? JSONDecoder().decode(ImageData.self, from: jsonData)
return imageData
}
JSONDecoder 클래스의 decode 메서드를 활용하면 쉽게 디코딩이 가능하다.
나는 나중에 코드 정리를 수월하게 하기 위해 DataManager라는 클래스를 따로 생성해서 그 안에 parseJSON 함수를 정의해줬다.
그리고 지금은 ImageData 타입을 리턴하지만,
나중에는 여러 데이터를 받아 담을 예정이기 때문에 ImageData타입을 원소로 받는 배열을 리턴하게 코드를 수정할 예정이다.
더미데이터를 넣고 디코딩이 잘 되는지 확인해보자.
ViewController에서 print를 찍어보면 잘 나오는 모습을 볼 수 있다.
내가 만든 parseJSON 함수는 옵셔널 타입의 구조체를 리턴하기 때문에 테스트를 위해 강제 언래핑을 해줬지만,
실제로는 네트워크 에러로 데이터가 들어오지 않을 수도 있으니 nil값에 대한 예외처리를 꼭 해주어야한다.
그건 차차 정리해 나가도록 하자.
이렇게 하면 HTTP API를 통해 JSON 데이터를 받아올 모델 생성은 끝이난다.
다음 포스팅은 URLSession을 활용하여 API를 받아오는 작업을 포스팅할 예정이다.
이 포스트의 프로젝트는 여기서 확인할 수 있습니다.
https://github.com/hminkim/iOSSandbox
오늘 작업 내용은 여기서 확인할 수 있습니다.
https://github.com/hminkim/iOSSandbox/pull/6
'ToyProject' 카테고리의 다른 글
[Project] Swift에서 URLSession을 통해 API를 받아오는 법 (0) | 2023.11.11 |
---|---|
[Project] GitHub Issue / PR 템플릿 등록하는 법 (0) | 2023.10.26 |
[Project] Xcode로 GitHub 연동 및 Repository 세팅 (0) | 2023.10.26 |