Swift - AWS S3 파일 업로드

민경준·2022년 11월 8일
1

AWS S3 란?

Amazone Web Service 의 Storage 서비스 입니다.

한마디로 대기업 아마존이 운영하는 대용량 저장소 입니다.

https://aws.amazon.com/ko/s3/?nc=sn&loc=1

이곳에 자세한 설명이 있으니 참고하세요 ㅎㅎ

AWS s3 라이브러리 사용을 위해 Pod을 설치한다.

pod 'AWSS3', '~> 2.6.13' # For file transfers
pod 'AWSCognito', '~> 2.6.13' #For data sync

AWS S3에 보내질 저장소에 관한 정보들을 enum 형식으로 작성한다.

컨텐츠 타입은 보내질 파일에 따라서 추가하거나 줄여도 된다.

enum S3Configuration : String
{
	case IDENTITY_POOL_ID = "Your Identity Pool Id"
	case BUCKET_NAME = "Your bucket name"
	case CALLBACK_KEY = "Personality Message"
	case CONTENT_TYPE_IMAGE = "image/jpg"
	case CONTENT_TYPE_VIDEO = "video/mp4"
	case CONTENT_TYPE_TXT = "text/plain"
}

AppDelegate.swift 파일에 AWS S3 와 연결을 위해 아래 코드를 작성한다.

regionType 과 region 은 본인의 저장소에 맞게 선택해주면 된다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
	// AWS S3 
	let credentialProvider = AWSCognitoCredentialsProvider(regionType: .APNortheast2, identityPoolId: S3Configuration.IDENTITY_POOL_ID.rawValue) 
	guard let configuration = AWSServiceConfiguration(region: .APNortheast2, credentialsProvider: credentialProvider) else { 
		print("[ FAILED TO CONNECT AWS S3 ]") 
		return false 
	}
	AWSS3TransferUtility.register(with: configuration, forKey: S3Configuration.CALLBACK_KEY.rawValue) 
	print("[ SUCCESS TO CONNECT AWS S3 ]") 
	return true 
}

파일 업로드를 위한 함수를 하나 작성한다.

imgData는 이미지 업로드를 위해 가져온 것이고, 본인이 다른 데이터를 전송하고 싶다면 다른 타입의 매개변수를 선언 해도 좋다.

func uploadImageFile(imgData: UIImage?, isSuccess: @escaping (String) ->Void, isFailed: @escaping () -> Void) {

}

받아온 이미지를 Data 타입으로 변환시키기 위한 코드를 작성한다.

여기서 부터는 모두 함수 안에 작성하는 코드 들이다.

// 이미지를 Data 타입으로 변환
guard let image = imgData?.jpegData(compressionQuality: 0.9) else {
	print("[ DONT HAVE IMAGE DATA ]")
	isFailed()
	return
}
let data: Data = image

// 파일 이름을 위한 날짜 포맷 설정
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddhhmmssSSS"

전송 될 파일의 이름, 액세스 키, 시크릿 키 값을 설정해준다.

저장소 아래에 폴더로 저장하고 싶다면 파일 이름 앞에 "Folder Name/" 을 붙여주면 된다.

액세스 키와 시크릿 키는 본인 계정 관리에 보안 자격 증명 탭에서 만들 수 있는데

액세스 키는 항상 확인이 가능 하지만, 시크릿 키는 액세스 키를 처음 생성할 때 주는 파일 안에만 들어있다.

let fileName = dateFormatter.string(from: currentDate) + ".jpg"
let accessKey = "Your AccessKey"
let secretKey = "Your SecretKey"

서버 사이드의 암호화 설정과 업로드 할 때 진행률 확인을 위한 코드를 작성한다.

암호화의 종류를 request 헤더에 실어서 보내주는 방식이다.

// 서버 사이드 암호화 설정 : AES256
let expression = AWSS3TransferUtilityUploadExpression()
expression.setValue("AES256", forRequestHeader: "x-amz-server-side-encryption")
expression.progressBlock = {(task, progress) in
	DispatchQueue.main.async(execute: {
		// Do something e.g. Update a progress bar.
		print("[ Upload progress ]: ", progress.fractionCompleted)
	})
}

이미지 업로드가 완료 되었을 때 실행될 코드를 작성 해준다.

// 이미지 업로드 Completion Handler
var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
	DispatchQueue.main.async(execute: {
		// Do something e.g. Alert a user for transfer completion.
		// On failed uploads, error contains the error object.

		// Request 이후 들어오는 Response의 URL값 
		guard let responseURL = task.response?.url else {
			return
		}
		// URL 문자열에서 필요없는 부분을 제거 
		// 문자열을 ? 기준으로 자른뒤 배열로 반환 시키는 함수
		// 배열의 첫 번째 값이 실제 사용하는 URL
		let url = responseURL.absoluteString.components(separatedBy: "?")[0]
		print("[ COMPLETE UPLOAD DATA TO AWS S3 ]")
    isSuccess(url)
	})
}

이미지를 업로드 하는 코드를 작성한다.

let transferUtility = AWSS3TransferUtility.default()
        transferUtility.uploadData(
						// 보내질 Data
						img,
						// 저장소의 버킷 이름
            bucket: S3Configuration.BUCKET_NAME.rawValue,
						// 업로드 할 파일의 이름
            key: fileName,
						// 컨텐츠 타입 (jpg, png, mp4, txt 등...)
            contentType: S3Configuration.CONTENT_TYPE_IMAGE.rawValue,
						// 헤더 값, 프로그래스 바
            expression: expression,
						// Request 요청이 끝나면 실행될 객체
            completionHandler: completionHandler).continueWith {
								// uploadData 코드가 모두 실행되면 실행될 코드
                (task) -> AnyObject? in
                    if let error = task.error {
                       print("Error: \(error.localizedDescription)")
                    }

                    if let _ = task.result {
                       // Do something with uploadTask.
                    }
                return nil;
            }

https://aws-amplify.github.io/aws-sdk-ios/docs/reference/AWSS3/Classes/AWSS3TransferManager.html#/c:objc(cs)AWSS3TransferManager(im)upload:

업로드 및 다운로드에 관한 API 문서 입니다.

profile
iOS Developer 💻

0개의 댓글