본문 바로가기
iOS

TheCatAPI를 이용한 Alamofire 예제

by HaningYa 2020. 3. 30.
728x90

 

Alamofire/Alamofire

Elegant HTTP Networking in Swift. Contribute to Alamofire/Alamofire development by creating an account on GitHub.

github.com

Alamofire

iOS를 개발하며 자주 썼던 라이브러리인 Alamofire에 대해서 내가 사용했던 방식을 TheCatAPI를 이용해 설명하고 예제 프로젝트를 만들려고 한다. Storyboard를 사용할 줄 아는 상태라고 가정하고 글을 썼다.

 

1. 서버 역할을 해줄 API 를 세팅한다.

https://thecatapi.com/

 

TheCatAPI - Cats as a Service, Everyday is Caturday.

A public service API all about Cats, free to use when making your fancy new App, Website or Service.

TheCatAPI.com

이 API 는 말 그대로 고양이 사진을 리스폰스로 준다. (갓갓 api)

 

먼저 사이트에 들어가 회원가입을 하고 가입한 이메일로 온 API key를 저장한다.

(API key는 간단하게 얘기하자면 특정 API 에 접근 할 수 있는 열쇠를 말한다.) 

 

그럼 api 세팅은 끝났다.

2. Xcode프로젝트를 만들어야 한다.

single view app 을 선택한다. 

 

프로젝트이름도 마음대로 설정해 준다. 

3. CocoaPods를 설치해준다.

Alamofire를 사용하기 위해선 기존 프로젝트를 cocoapod를 통해 workspace 형식으로 만들어야 한다.  코코아팟 사용법은

https://zeddios.tistory.com/25

 

왕 초보를 위한 CocoaPods(코코아팟) 사용법 (Xcode와 연동)

안녕하세요! 오늘은 CocoaPod사용법에 대해 알려드릴려고해요 :) 저는 CocoaPod 처음에 시작할 때 뭐가 뭔지 몰라서 정말 하나도 몰라서 진짜 어려운거구나...라고 생각했었어요. 하지만 한번 배워 놓으면 정말 쉽..

zeddios.tistory.com

자세히 나와있다.

 

설치를 한 뒤 파란색 프로젝트 말고 흰색의 워크 스페이스로 xcode를 실행한다.

 

4. Podfile에 Alamofire를 세팅한다.

Podfile을 열어서

pod 'Alamofire', '~> 4.9.1'

 

라고 적고 저장한 후 닫는다. (Alamofire 4.9.1 버전을 사용한다.) 그리고 해당 프로젝트가 있는 디렉토리의 터미널에서 

pod update

를 하면 Alamofire 가 세팅된다. 

 

 

세팅이 완료된 후의 Terminal

5. 네트워킹을 담당하는 모듈역할을 할 swift 파일을 만들어 준다.

command + N 을 한 뒤 Swift 파일을 새로 만든다.

6. Network.swift 에서 CATAPI와 통신할 모듈를 코딩한다.

먼저 CatAPI 의 문서를 읽어보자. 

https://docs.thecatapi.com/

 

Home

TheCatApi // Developer Experience Get your API Key from - https://TheCatAPI.com Here you'll find the API reference & Code examples for: 1\. Searc...

docs.thecatapi.com

다른 기능을 구현하려면 자세히 읽으면 되지만 이번엔 랜덤한 고양이 사진만 필요하기 떄문에 Quickstart 부분만 읽는다.

  1. 해당 주소를 Load 한다.
  2. JSON 응답의 첫번째 배열 오브젝트를 참조한다
  3. 첫번째 오브젝트에 url 형식으로 load 한다. 
  4. 고양이를 즐기면 된다.

쉽다. 코딩을 마무리 하자. 

import Foundation
import Alamofire

class Network {
    let apiKey = "각자 발행된 API 키를 넣으면 됩니다."
    
    static let shared = Network()
    
    class var baseURL : String {
        return "https://api.thecatapi.com"
    }
    
    static var sessionManager: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = [:]
        configuration.httpAdditionalHeaders?["Accept"] = "application/json"
        return Alamofire.SessionManager(configuration: configuration)
    }()
    

    func getRandomCatPicture(parameters : Parameters, completion : @escaping(_ result : Data) -> (Void)){
        let url = "/v1/images/search"
        let parameters : Parameters = parameters
        Network.sessionManager.request(Network.baseURL + url, method: .get, parameters:  parameters).responseJSON { (response) in
            switch response.result{
            case .success(_):
                completion(response.data!)
                break
            case .failure(let error):
                print(error)
                print(response.data!)
                break
            }
        }
    }
}

 

 

 

7. Storyboard와 ViewController를 세팅한다. 

단순히 이미지를 표시하기 때문에 고양이 사진을 표시할 UIImageView 하나와

고양이가 마음에 안들경우 바꿀 수 있는 버튼을 추가한다. (constraint를 0으로 했는데 이상한 standard 여백이 들어가질 않는다 드디어 버그가 고쳐졌다)

8. ViewController에 CatAPI를 사용할 네트워크부분을 코딩한다.

먼저 api 의 리스폰스가 어떤 형태로 오는지 확인해야 디코딩을 할 수가 있다.

POSTMAN을 써보겠다.[POSTMAN 더보기]

 

Postman 개요 / 설치 / 사용법 / 활용 방법 : TOAST Meetup

Postman

meetup.toast.com

이런식으로 JSON Array형식으로 오는데 api 문서에서 왔듯이 url 이라는 키의 value 값에 고양이의 이미지 url 정보가 담겨있는걸 알 수 있다. 간단하게 struct 로 받아서 decode 하겠다. (breeds는 생략)

struct CatResponse : Decodable {
     let id : String?
     let url : String?
     let width : Int?
     let height : Int?
 }

여기서 중요한 점은 CatResponse로 파싱할 때 받는 JSON 은 Object가 아닌 Array 형식이라는 점이다. 

그래서 deocode 부분에서 [CatResponse] 라고 Array안에 넣어줘야한다. 
일단 간단하게 리스폰스에서 고양이 사진의 url만 print 하는 코드를 작성해봤다.

func getRandomCatPicture(){
        let parameters: Parameters = [
            "x-api-key" : Network.apiKey
        ]
        Network.shared.getRandomCatPicture(parameters: parameters, completion: { (data) -> (Void) in
            do {
                let res = try JSONDecoder().decode([CatResponse].self, from : data)
                print("cat picture url : \(res[0].url ?? "no url")")
            }catch {
                print(error)
            }
        })
    }
    

결과

https://cdn2.thecatapi.com/images/bit.jpg

성공이다. 이제 이 이미지 url 을 가지고 만들어 두었던 UIImageVIew에 표시하는 일만 남았다.

 

9. 이미지 url 로 고양이 사진 표시하기

url을 통한 이미지 표시는 라이브러리를 이용했었다. 왜냐하면 여러장의 이미지를 비동기적으로 들고와야 스크롤시 버벅이지도 않고 부드럽게 loading이 가능하기 때문이다. [자주 사용하는 libarary]

 

SDWebImage/SDWebImage

Asynchronous image downloader with cache support as a UIImageView category - SDWebImage/SDWebImage

github.com

그치만,,,, 고양이 사진 한장이기 때문에 라이브러리 없이 다운로드해 표시하겠다.

 func loadCatImage(_ url : String?){
        let downloadQueue = DispatchQueue(__label: url,attr: nil)
        downloadQueue.async(){
            let data = NSData(contentsOf: NSURL(string: url!)! as URL)
            var image: UIImage?
            if (data != nil){
                image = UIImage(data: data! as Data)
            }
            DispatchQueue.main.async {
                self.imgViewCat.image = image
            }
        }
    }
    

이제 이 고양이 url 요청과 url을 통한 이미지 다운로드 메소드를 연결하면 고양이를 가질 수 있다!

//
//  ViewController.swift
//  RandomCatPicture
//
//  Created by 김태형 on 2020/03/30.
//  Copyright © 2020 김태형. All rights reserved.
//

import UIKit
import Alamofire

struct CatResponse : Decodable {
    let id : String?
    let url : String?
    let width : Int?
    let height : Int?
}

class ViewController: UIViewController {
    
    @IBOutlet weak var imgViewCat: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func actionChangeCat(_ sender: Any) {
        getRandomCatPicture()
    }
    func getRandomCatPicture(){
        let parameters: Parameters = [
            "x-api-key" : Network.apiKey
        ]
        Network.shared.getRandomCatPicture(parameters: parameters, completion: { (data) -> (Void) in
            do {
                let res = try JSONDecoder().decode([CatResponse].self, from : data)
                print("cat picture url : \(res[0].url ?? "no url")")
                self.loadCatImage(res[0].url)
            }catch {
                print(error)
            }
        })
    }
    func loadCatImage(_ url : String?){
        let downloadQueue = DispatchQueue(__label: url,attr: nil)
        downloadQueue.async(){
            let data = NSData(contentsOf: NSURL(string: url!)! as URL)
            var image: UIImage?
            if (data != nil){
                image = UIImage(data: data! as Data)
            }
            DispatchQueue.main.async {
                self.imgViewCat.image = image
            }
        }
    }
    
}


이렇게 되면 이제 고양이가 표시가 된다.ㅎㅎ

고양이는 늘짜릿해 새로워!

전체 코드는 [여기서 확인]

 

KimTaeHyeong17/RandomCatWithAlamofire

Contribute to KimTaeHyeong17/RandomCatWithAlamofire development by creating an account on GitHub.

github.com

사실 Network모듈을 따로 만들지 않고 ViewController에 모든 코드를 구현해도 상관은 없다. 하지만 지금과 같은 api 한개가 아닌 수십개의 api 관리와 test 서버, 배포 서버와 연결관리 등등을 고려해 볼때 Network 모듈을 따로 만들어 호출하는 것이 좋다고 생각한다.

728x90

댓글