고양이 이미지를 랜덤으로 감상하고, 내가 찍은 사진을 업로드하고, 좋아하는 이미지를 즐겨찾는 iOS 앱
이 버전은 Alamofire + Router 패턴을 활용하여
보다 구조적이고 확장성 있는 네트워크 구조를 목표로 제작되었습니다.
MyCat은 랜덤 고양이 사진을 감상하고,
직접 사진을 업로드하거나 즐겨찾기할 수 있는 iOS 반려동물 이미지 앱입니다.
이 버전은 Alamofire 라이브러리와 Router 패턴을 활용하여 API 통신을 구현하는 것을 목표로 했습니다.
더욱 효율적이고 유지보수 가능한 네트워크 구조에 중점을 두었습니다.
- 1인 개인 프로젝트
- 기획, UI/UX 설계, API 연동, 로컬 저장 등 전 과정을 단독으로 개발
Swift
UIKit
Alamofire
– 네트워크 통신 (Router 기반 구조)Toast
– 사용자 피드백 메시지PHPickerViewController
– 이미지 업로드 기능
- 본 프로젝트는 The Cat API를 사용하여 고양이 이미지를 제공합니다.
- API 문서: https://docs.thecatapi.com/
- 랜덤 고양이 이미지 API 호출 및 표시
- 앨범에서 고양이 사진 선택하여 업로드
- 고양이 사진 즐겨찾기 등록/해제 및 로컬 저장소 반영
import Foundation
import Alamofire
enum CatRouter: URLRequestConvertible {
case fetch(limit: Int)
case upload
case fetchUploaded(limit: Int)
case delete(imageID: String)
private var baseURL: URL {
return URL(string: endPoint)! // endPoint는 상수 또는 환경 파일에서 관리
}
private var catApiKey: String? {
return Bundle.main.object(forInfoDictionaryKey: "CAT_API") as? String
}
var method: HTTPMethod {
switch self {
case .fetch, .fetchUploaded:
return .get
case .upload:
return .post
case .delete:
return .delete
}
}
var path: String {
switch self {
case .fetch:
return "v1/images/search"
case .upload:
return "v1/images/upload"
case .fetchUploaded:
return "v1/images/"
case .delete(let imageID):
return "v1/images/\(imageID)"
}
}
var headers: HTTPHeaders {
switch self {
case .upload:
let boundary = UUID().uuidString
return [
"x-api-key": catApiKey ?? "",
"Content-Type": "multipart/form-data; boundary=\(boundary)"
]
default:
return [
"Content-Type": "application/json",
"x-api-key": catApiKey ?? ""
]
}
}
var parameters: Parameters {
switch self {
case .fetch(let limit), .fetchUploaded(let limit):
return ["limit": limit]
default:
return [:]
}
}
func asURLRequest() throws -> URLRequest {
let url = baseURL.appendingPathComponent(path)
var request = URLRequest(url: url)
request.method = method
request.headers = headers
switch self {
case .fetch, .fetchUploaded:
return try URLEncoding.default.encode(request, with: parameters)
default:
retur