Alamofire
iOS를 개발하며 자주 썼던 라이브러리인 Alamofire에 대해서 내가 사용했던 방식을 TheCatAPI를 이용해 설명하고 예제 프로젝트를 만들려고 한다. Storyboard를 사용할 줄 아는 상태라고 가정하고 글을 썼다.
1. 서버 역할을 해줄 API 를 세팅한다.
이 API 는 말 그대로 고양이 사진을 리스폰스로 준다. (갓갓 api)
먼저 사이트에 들어가 회원가입을 하고 가입한 이메일로 온 API key를 저장한다.
(API key는 간단하게 얘기하자면 특정 API 에 접근 할 수 있는 열쇠를 말한다.)
그럼 api 세팅은 끝났다.
2. Xcode프로젝트를 만들어야 한다.
3. CocoaPods를 설치해준다.
Alamofire를 사용하기 위해선 기존 프로젝트를 cocoapod를 통해 workspace 형식으로 만들어야 한다. 코코아팟 사용법은
https://zeddios.tistory.com/25
자세히 나와있다.
설치를 한 뒤 파란색 프로젝트 말고 흰색의 워크 스페이스로 xcode를 실행한다.
4. Podfile에 Alamofire를 세팅한다.
Podfile을 열어서
pod 'Alamofire', '~> 4.9.1'
라고 적고 저장한 후 닫는다. (Alamofire 4.9.1 버전을 사용한다.) 그리고 해당 프로젝트가 있는 디렉토리의 터미널에서
pod update
를 하면 Alamofire 가 세팅된다.
5. 네트워킹을 담당하는 모듈역할을 할 swift 파일을 만들어 준다.
command + N 을 한 뒤 Swift 파일을 새로 만든다.
6. Network.swift 에서 CATAPI와 통신할 모듈를 코딩한다.
먼저 CatAPI 의 문서를 읽어보자.
다른 기능을 구현하려면 자세히 읽으면 되지만 이번엔 랜덤한 고양이 사진만 필요하기 떄문에 Quickstart 부분만 읽는다.
- 해당 주소를 Load 한다.
- JSON 응답의 첫번째 배열 오브젝트를 참조한다
- 첫번째 오브젝트에 url 형식으로 load 한다.
- 고양이를 즐기면 된다.
쉽다. 코딩을 마무리 하자.
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 더보기]
이런식으로 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]
그치만,,,, 고양이 사진 한장이기 때문에 라이브러리 없이 다운로드해 표시하겠다.
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
}
}
}
}
이렇게 되면 이제 고양이가 표시가 된다.ㅎㅎ
전체 코드는 [여기서 확인]
사실 Network모듈을 따로 만들지 않고 ViewController에 모든 코드를 구현해도 상관은 없다. 하지만 지금과 같은 api 한개가 아닌 수십개의 api 관리와 test 서버, 배포 서버와 연결관리 등등을 고려해 볼때 Network 모듈을 따로 만들어 호출하는 것이 좋다고 생각한다.
'iOS' 카테고리의 다른 글
GCD : Grand Central Dispatch (0) | 2020.06.16 |
---|---|
WWDC Swift Student Challenge 세팅 (0) | 2020.05.06 |
iOS 오픈소스 라이브러리 만들기 101 (1) | 2020.04.18 |
뱅크 샐러드는 어떤 라이브러리를 쓸까?(iOS 유용한 라이브러리) (0) | 2020.04.04 |
재사용 가능한 UIView를 만들어 보자! (1) | 2020.04.03 |
댓글