AWS Amplify + API Gateway + Lambda + iOS App

daymore 앱 프리미엄을 구독방식으로 변경하기 위해 인앱결제 영수증을 서버에서 검증하는 방식으로 변경하기로 함, 여러가지를 고민하다가 AWS Lambda를 사용하기로 결정! 약간의 삽질을 동반한 설정 경험을 정리함.

EC2에 올려서 운영하는것보다는 서버관리가 없어서 편하고 월 100만건 호출까지 무료로 사용가능해서 Lambda를 사용하기로 함, cold start 문제가 있기는 하지만 어짜피 앱에서 백그라운드로 돌려서 결과 확인하는 방식이라서 별 상관없을 것 같음

서버
AWS Lambda(Golang) + API Gateway

  • Golang
    “github.com/apex/gateway”
    “github.com/gin-gonic/gin”
    “github.com/awa/go-iap/appstore”

    빌드, GOOS=linux GOARCH=amd64 go build -o main
    압축, zip main.zip main
  • Amplify Cli
    AWS 콘솔에서 직접 만들지 않고 Amplify Cli를 이용함
    Amplify Cli를 이용하여 S3, Api, Lambda를 생성함

    https://docs.amplify.aws/lib/project-setup/prereq/q/platform/ios#option-1-watch-the-video-guide
    – amplify configure (IAM 유저 생성)

    https://docs.amplify.aws/lib/project-setup/create-application/q/platform/ios#n2-install-amplify-libraries
    – amplify init (AWS Amplify에 프로젝트 생성)

    https://docs.amplify.aws/lib/storage/getting-started/q/platform/ios
    – amplify add storage (S3 생성, 버킷 생성), (auth and guest users 선택, 모든 권한)
    – amplify push

    https://docs.amplify.aws/lib/restapi/getting-started/q/platform/ios
    – amplify add api (API, Lambda 생성), (Restrict API access 에서 No), (auth and guest users 선택, 모든 권한)
    – amplify push
  • AWS Lambda console
    – 생성된 함수 moreiap 로 이동
    – “코드 소스”에서 로컬에서 만들어 놓은 main.zip 파일 업로드
    – “런타임 설정”에서 핸들러를 main으로 변경
  • AWS API Gateway console
    – 여기서 설정해 줄건 없지만 내부 테스트 할 수 있음
  • iOS 프로젝트
    https://docs.amplify.aws/lib/project-setup/create-application/q/platform/ios#n1-create-a-new-project
    – 프로젝트에 amplifyconfiguration.json, awsconfiguration.json 파일 추가
    – 아래와 같이 테스트, 리턴값 확인
    func appleReceipt() {
        func loadReceipt() -> Data? {
            guard let url = Bundle.main.appStoreReceiptURL else {
                return nil
            }
            
            do {
                let data = try Data(contentsOf: url)
                return data
            } catch {
                print("Error loading receipt data: \(error.localizedDescription)")
                return nil
            }
        }
        
        guard let data = loadReceipt() else { return }
        
        let message = ["receipt-data":data.base64EncodedString()]
        guard let jsonData = try? JSONSerialization.data(withJSONObject: message, options: []) else { return }
        let request = RESTRequest(path: "/apple/receipt", body: jsonData)
        Amplify.API.post(request: request) { result in
            switch result {
            case .success(let data):
                let json = try? JSONSerialization.jsonObject(with: data, options: [])
                print(json)
            case .failure(let apiError):
                print("Failed", apiError)
            }
        }
    }

정리 끝!
삽질 1) amplify 이용시 api를 추가하고 storage를 추가하면 오류가 생김, 그래서 storage 먼저 추가하고 api 추가함, 인증때문인거 같음
삽질 2) api를 추가할 때 restrict api access를 yes 로 했는데 앱에서 호출 에러(403에러) 발생하여 정책을 찾아서 수정하려다 실패하고 amplify update api 로 restrict api access를 no로 변경하고 다시 amplify push, 앱에서 호출 성공!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다