[swift] Swift Moya에서 AWS S3 연동하기

AWS S3는 클라우드 기반의 객체 스토리지 서비스로 데이터를 저장하고 검색하는 데 사용됩니다. 이번 포스팅에서는 Swift Moya 라이브러리를 사용하여 iOS 애플리케이션에서 AWS S3와의 연동 방법을 알아보겠습니다.

1. AWS SDK 설치하기

AWS SDK를 사용하여 S3와의 통신을 처리할 수 있습니다. Cocoapods를 사용하여 아래와 같이 AWS SDK를 설치합니다.

pod 'AWSS3', '~> 2.0'

2. AWS S3 설정하기

AWS 콘솔에서 S3 버킷을 생성하고 엑세스 키와 시크릿 키를 발급받아야 합니다. 발급받은 키를 사용하여 AWS S3를 사용할 수 있습니다.

3. Moya와의 통신 설정하기

Moya는 iOS에서 네트워크 요청을 쉽게 구현하기 위한 라이브러리입니다. Moya를 사용하여 AWS S3와의 통신을 처리합니다. 먼저 Moya를 설정하고 AWS S3와의 API 요청을 정의해야 합니다.

import Moya

enum AWSS3Service {
    case uploadImage(imageData: Data, fileName: String)
    case downloadImage(fileName: String)
}

extension AWSS3Service: TargetType {
    var baseURL: URL {
        return URL(string: "https://s3.amazonaws.com")!
    }
    
    var path: String {
        switch self {
        case .uploadImage(_, let fileName), .downloadImage(let fileName):
            return "/bucket-name/\(fileName)"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .uploadImage:
            return .put
        case .downloadImage:
            return .get
        }
    }
    
    var task: Task {
        switch self {
        case .uploadImage(let imageData, _):
            return .uploadMultipart([MultipartFormData(provider: .data(imageData), name: "file")])
        case .downloadImage:
            return .downloadDestination(DefaultDownloadDestination)
        }
    }
    
    var headers: [String: String]? {
        return nil
    }
}

let provider = MoyaProvider<AWSS3Service>()

4. 이미지 업로드 및 다운로드 기능 구현하기

이제 이미지 업로드 및 다운로드 기능을 구현해보겠습니다.

func uploadImage(imageData: Data, fileName: String, completion: @escaping (Result<String, Error>) -> Void) {
    provider.request(.uploadImage(imageData: imageData, fileName: fileName)) { result in
        switch result {
        case let .success(response):
            do {
                let json = try JSONSerialization.jsonObject(with: response.data, options: [])
                if let s3Url = json["url"] as? String {
                    completion(.success(s3Url))
                } else {
                    completion(.failure(NSError(domain: "Invalid response", code: -1, userInfo: nil)))
                }
            } catch {
                completion(.failure(error))
            }
        case let .failure(error):
            completion(.failure(error))
        }
    }
}

func downloadImage(fileName: String, completion: @escaping (Result<Data, Error>) -> Void) {
    provider.request(.downloadImage(fileName: fileName)) { result in
        switch result {
        case let .success(response):
            completion(.success(response.data))
        case let .failure(error):
            completion(.failure(error))
        }
    }
}

5. 사용 예시

이제 구현한 이미지 업로드 및 다운로드 기능을 사용해보겠습니다.

// 이미지 업로드
let imageData = UIImageJPEGRepresentation(image, 0.8)!
let fileName = "image.jpg"
uploadImage(imageData: imageData, fileName: fileName) { result in
    switch result {
    case let .success(s3Url):
        print("Uploaded image URL: \(s3Url)")
    case let .failure(error):
        print("Failed to upload image: \(error)")
    }
}

// 이미지 다운로드
// fileName은 업로드할 때 사용한 파일 이름과 동일해야 합니다.
let downloadFileName = "image.jpg"
downloadImage(fileName: downloadFileName) { result in
    switch result {
    case let .success(imageData):
        let image = UIImage(data: imageData)
        // 다운로드한 이미지를 사용하거나 처리합니다.
    case let .failure(error):
        print("Failed to download image: \(error)")
    }
}

이제 AWS S3와의 연동을 위해 Swift Moya를 사용하는 방법에 대해 알아보았습니다. 이를 활용하여 iOS 애플리케이션에서 AWS S3와의 이미지 업로드 및 다운로드 기능을 구현할 수 있습니다.