728x90
반응형
[IAP 개요]
– 앱내 결제 관련 부분
앱내 결제는 가상의 아이템을 앱내에서 구매할수 있도록 해준다. 일반적으로 이러한 것들은 추가적인 컨텐츠의 형태를 취하여 게임내에서 아이템을 추가적으로 구입하거나 가상의 상품을 구입할수 있게 한다. 구매는 소모성(Consumable, 매번 구매되어야 하는 아이템)과 비소모성(Non-comsumable, 콘텐츠를 구입하는 것처럼 사용자가 한번만 구매하는것), 그리고 정기 구독(subscription)형태로 나뉜다. 정기 구독 형태의 구매는 비갱신형(Non-renewing, 특정 기간동안 활성화 되는 아이템)과 자동 갱신형(Auto-renewing, 사용자가 취소할때까지 일정 간격으로 자동 갱신되는 구독), 그리고 뉴스가판대(Newsstand)기반의 애플리케이션에서 콘텐츠를 무료로 접근할수 있게 하는 무료 구독(Free subscription)형태가 있다. 비소모성(Non-consumable)과 자동 갱신형(Auto-renewable)결제는 사용자의 요청에 따라 사용자의 iOS디바이스에서 복원될수 있도록 구성해야 한다. 사용자에 의해 결제된 아이템은 애플리케이션 내에 내장되거나 서버에 저장되게 할수 있다.
[IAP 관련 샘플 예제]
Step1 – 프로젝트 생성
Single View App으로 프로젝트 생성
Step2 – 스토리보드 구성
샘플을 위해 아래와 같이 3개의 뷰 컨트롤러를 구성할것이다.
첫번째 뷰 컨트롤러에는 2개의 버튼이 위치한다. “구매완료후 활성화” 버튼은 최초 실행시 비활성화 처리가 되어있다.
바로 아래의 “아이템 구매하기” 버튼을 누르면 실제 아이템을 결제하는 화면으로 이동후 구매가 완료되어
첫번째 뷰 컨트롤러로 돌아올 경우 첫번째 버튼이 활성화 되어 두번째 상단의 화면으로 이동가능한 형태이다.
오른쪽 하단의 뷰 컨트롤러가 구매를 담당하는 “PurchaseViewController” 뷰 컨트롤러이다.
구매를 담당하는 새로운 뷰 컨트롤러(PurchaseViewController)를 추가하기 위하여 “Cocoa Touch Class” 선택
PurchaseViewController에는 아래와 같이 위에서부터 순서대로 productTitle, productDescription의 UILable과
purchase라는 UIButton을 추가후 아웃렛으로 연결한다.
Step3 – Apple Developer 사이트 설정
일단 PurchaseViewController 연동이 끝났으면 Apple Developer사이트에 가서 앱에 관련된 설정을 추가한다.
프로젝트로 돌아와 Capabilities에서는 In-App Purchase부분을 활성화시켜준다.
Step4 – iTunes Connect 설정
프로젝트 설정이 끝났으면 이번에는 iTunes Connect사이트로 이동하여 실제 구매할 인앱결제 아이템을 새로 생성한다.
테스트 계정을 등록하기 위하여 “Users and Roles”로 이동
테스트 계정을 추가한다.
Apple Developer 프로그램에 가입하면 동일한 로그인 계정을 사용하는 iTunes Connect 계정이 자동으로 생성된다.
iTunes Connect는 개발자들이 세금과 은행계좌 정보를 입력하고 애플리케이션들에 대한 상세 내용을 입력하며,
애플리케이션들의 판매와 수익 상태를 추적할수 있는 웹 포털이다.
처음 접속하는 사용자는 Contracts, Taxes and Banking 링크를 클릭하여
애플의 약관에 동의하는 작업과 판매 수익에 대한 세금 및 은행 정보를 입력해야 한다.
이 과정이 완료되지 않으면 앱내 결제가 동작하지 않는다.
샌드박스 기능을 이용하여 앱 내 결제를 테스트하려면, 먼저 테스트 사용자 계정을 생성해야 한다.
여기에서 앱내 결제를 테스트할때 디바이스에 입력할 계정 정보를 입력한다.
iTunes Connect에서 Users and Roles 링크를 클릭한 다음,
Sandbox Testers 카테고리를 선택하고 새로운 테스트 사용자를 추가한다.
이때 주의해야 할것은 이미 활성화된 iTunes 계정과 연관된 이메일 주소를 사용할수 없다는 점이다.
Step5 – 앱내결제할 아이템 등록
iTunes Connect 메인으로 다시 이동하여 “My Apps”로 이동
위의 과정중 Apple Developer를 먼저 한것은 아래에서 Bundle ID에서 바로 선택할수 있도록 하기 위하여
코딩 작업 도중 Apple Developer 앱설정을 먼저 한것이다.
애플리케이션 설정이 끝나면 앱내 결제 아이템을 추가해야 한다.
My Apps화면에서 새롭게 생성한 앱을 선택하고 In App Purchases 옵션을 클릭한다.
그 다음에 나오는 화면에서 Create New버튼을 누른다.
여기에선 앱내 결제 타입에 대한 목록에서 적절한 것을 선택하고 아래의 정보를 입력한다.
a) Reference name – iTunes Connect와 sales report에 표시될 아이템의 이름
b) Product ID – 아이템에 대한 고유한 제품 ID, 이것은 보통 판매되는 애플리케이션의 고유한 번들 식별자를 이용한다.
c) Price and Availability – 아이템의 가격과 판매여부
d) In-App Purchase Details – 애플리케이션이 지원하는 각 언어에 대하여 아이템의 Display Name과 Description을 입력(앱 결제때 애플리케이션에 표시된다.)
e) Hosting content with Apple – 콘텐츠가 애플의 서버에서 호스팅 될것인지를 가리킨다.
위의 정보를 입력후 “Waiting for Screenshot”이 표시되면 테스트가 가능하다.
일단 아이템 속성은 소모성으로 선택
Step6 – Step5까지 모든 과정이 끝나면 이제 앱에서 바로 인앱결제를 이용할수 있는 product id를 적용하여 결제를 테스트할수 있다.
실제 최종완성된 2개의 뷰 컨트롤러는 아래와 같다.
(스토리보드 오른쪽 상단의 결제 완료후 이동가능해지는 뷰 컨트롤러는 출력전용으로 스토리보드상에만 있는 ViewController이다.)
스토리보드 최초 화면.swift
//
// ViewController.swift
// inapppurchase
//
import UIKit
// IAP
import StoreKit
class ViewController: UIViewController {
@IBOutlet weak var enableScreen: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// AppDelegate 클래스에 mainViewController를 참조하여 결제가 완료되었을때 버튼을 활성화 시킬수 있도록 한다.
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.mainViewController = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func enableScreenButton(){
enableScreen.enabled = true
}
}
구매를 실질적으로 담당하는 PurchaseViewController.swift
//
// PurchaseViewController.swift
// inapppurchase
import UIKit
// IAP를 위한 Framework
import StoreKit
class PurchaseViewController: UIViewController, SKPaymentTransactionObserver, SKProductsRequestDelegate{
@IBOutlet weak var productTitle: UILabel!
@IBOutlet weak var productDescription: UITextView!
@IBOutlet weak var purchase: UIButton!
@IBAction func purchaseProduct(sender: AnyObject) {
let payment = SKPayment(product: product!)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
var product:SKProduct?
var productID = "iap_sample_free" // iTunesConnect에서 생성한 IAP결제 Free용 제품에 대한 식별자
//var productID = "iap_demo_0.99" // iTunesConnect에서 생성한 IAP결제 Tier1 제품에 대한 식별자
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
/*
제품 정보 수신후 사용자에게 표시할때까지 아이템 구매 버튼은 비활성화되어있어야 한다.
또한 이 클래스를 결제 작업을 위한 트랜잭션 감시자(transaction observer)로 설정해야 한다.
그후에는 결제를 위한 제품 정보를 얻어서 사용자에게 표시하는 메서드를 최초로 호출해야 한다.
*/
purchase.enabled = false // 상품 정보 수신전까지는 구매버튼 비활성화처리
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
getProductInfo()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 상품 정보 요청 함수
func getProductInfo(){
if SKPaymentQueue.canMakePayments() {
// 애플에 상품 정보 요청, 요청이 완료되면 바로 아래 함수인 productsRequest함수가 자동 호출된다.
let request = SKProductsRequest(productIdentifiers: NSSet(object: self.productID) as! Set<String>)
request.delegate = self
request.start()
}else{
productDescription.text = "설정에서 인앱결제를 활성화주세요"
}
}
func productsRequest(request: SKProductsRequest, didReceiveResponse response:SKProductsResponse){
var products = response.products
// 상품 정보가 정상적으로 수신되었을 경우 화면에 상품 정보 갱신 및 구매 버튼 활성화 처리한다.
if products.count != 0 {
product = products[0] as SKProduct
purchase.enabled = true
productTitle.text = product!.localizedTitle
productDescription.text = product!.localizedDescription
}else{
productTitle.text = "애플계정에 등록된 상품정보 확인불가"
}
let productList = response.invalidProductIdentifiers
for productItem in productList{
print("Product not found : \(productItem)")
}
}
// 상품 구매를 위해 결제 요청후 자동으로 호출되는 delegate함수
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions as [SKPaymentTransaction]{
switch transaction.transactionState {
case SKPaymentTransactionState.Purchased:
// 구매가 정상적으로 완료될 경우 후처리 시작
self.unlockFeature()
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
break
case SKPaymentTransactionState.Failed:
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
default: break
}
}
}
// 상품 구매가 완료되었을 경우 앱내 후처리(실제로는 구매번호, 구매일자등을 로컬에 저장해 둔다)
func unlockFeature(){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.mainViewController!.enableScreenButton()
purchase.enabled = false
productTitle.text = "상품 구매 완료되었습니다."
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Step7 – 최종 완성후 결과는 아래와 같다.
ViewController.swift(최초화면) | 구매버튼을 눌러 PurchaseViewController화면으로 이동 |
Sandbox에서 구매여부 확인후 구매작업 시작 | 아이템 구매 완료후 메인화면 버튼 활성화 처리(다음 화면으로 이동가능, 혹은 잠금된 아이템 사용가능 처리) |
아이템 구매 완료후 메인화면 버튼 활성화 처리(다음 화면으로 이동가능, 혹은 잠금된 아이템 사용가능 처리) | 최종 화면으로 이동가능하게 된다.
|
반응형
LIST
'전공 > 실무' 카테고리의 다른 글
Java 암호화 (0) | 2018.04.12 |
---|---|
정규식 및 비교 기타 (0) | 2018.04.12 |
[Linux] CentOS 리눅스 명령어 (0) | 2018.04.12 |
[Nodejs] 난독화, 복호화(암호화) (0) | 2018.04.12 |
[Nodejs] 소켓(socket.io) 연동 (0) | 2018.04.03 |