-
Notifications
You must be signed in to change notification settings - Fork 0
Purchasing integration (iOS)
유니티는 사용자가 Unity IAP를 구현하지 않고도 최적화된 수익화 기능을 활용할 수 있도록 지원합니다. 다음의 기초적인 단계들을 따라 자체적인 인앱 구매 솔루션을 유지하면서 동시에 Unity Ads 3.0+으로 IAP Promo를 생성하고 개인화 플레이스먼트를 활용해 보세요.
- 프로젝트에 Unity Ads SDK 3.0+을 설치합니다.
- Developer Dashboard에서 수동으로 제품 카탈로그를 구성합니다.
- 대시보드에서 IAP Promo를 구성합니다.
-
USRVUnityPurchasingAPI를 사용하여 게임 코드에서 구매 어댑터를 구현합니다. - 구매 어댑터 내에서 게임 로직 및 구매 이벤트를 구현합니다.
- 구매 어댑터와 수익화(Monetization) SDK를 초기화합니다.
다음은 iOS를 사용하는 Objective-C 개발자를 위한 지침입니다.
여기에서 Unity Ads 프레임워크를 다운로드할 수 있습니다. USRVUnityPurchasing API는 SDK 3.0 이상 버전이 필요합니다.
- 프레임워크를 드래그 앤 드롭으로 Unity Project 폴더에 옮기고 복사하십시오.
- ViewController 헤더(.h)에서, Unity Ads를 임포트하고 Unity Ads 델리게이트를 설정하십시오.
#import <UIKit/UIKit.h>
#import <UnityAds/UnityMonetization.h>
@interface ViewController: UIViewController<UnityMonetizationDelegate, UMONShowAdDelegate>
@end아직 UDN 계정이 없다면 여기에서 계정을 생성하세요. 이미 계정이 있으시다면 아래 과정을 따라 Unity 프로젝트를 생성하실 수 있습니다.
- Developer Dashboard에 로그인하고 Operate 탭으로 이동합니다.
- 왼쪽 내비게이션에서 Projects(프로젝트)를 선택합니다.
- 오른쪽 상단에 있는 NEW PROJECT 버튼을 클릭합니다.
프로젝트를 선택하여 프로젝트의 게임 ID를 찾은 다음, 내비게이션에서 Monetization > Platforms를 선택합니다. Apple App Store Game ID를 복사합니다. 이는 게임에서 Unity Ads 서비스를 활성화하는 데 필요합니다.
Monetization 구매 델리게이션을 구현하기 전에 Operate 탭(Developer Dashboard)으로 이동한 다음 제품 카탈로그 완성을 위한 수동 구성 지침을 따르십시오.
Operate 탭(Developer Dashboard)에서, IAP Promo 구성 지침을 따르십시오.
게임 스크립트에서 <UnityAds/USRVUnityPurchasingDelegate.h> 델리게이트를 포함한 뒤에 USRVUnityPurchasingDelegate 델리게이트를 관리하는 USRVUnityPurchasing 클래스를 구현할 수 있습니다. 두 가지 함수인 loadProducts 및 purchaseProduct를 사용하여 구매 어댑터에서 사용할 게임 로직을 정의할 수 있습니다. 이들 메서드는 USRVUnityPurchasing를 사용하는 클래스가 필요합니다. SDK가 제품 거래를 관리할 때 필요에 맞게 호출하려면 이를 구현해야 합니다.
#import <UnityAds/USRVUnityPurchasingDelegate.h>
@interface MyPurchasing <USRVUnityPurchasingDelegate>
@end
// Placeholder for loadProducts function
// Placeholder for purchaseProduct functionProduct Catalog 가져오기
SDK는 loadProducts를 호출하여 이용할 수 있는 제품 목록을 가져오고, UnityPurchasingLoadProductsCompletionHandler 함수를 사용하여 UPURProduct 오브젝트를 Monetization.Product 오브젝트로 변환합니다. 각 제품마다 최소 productID, localizedPriceString, productType, isoCurrencyCode 및 localizedTitle 문자열이 필요합니다.
구매 처리
사용자가 프로모션 에셋의 구매하기 버튼을 클릭하면 SDK는 purchaseProduct를 호출합니다. 구매 성공 또는 실패 핸들링은 인앱 구매 구현 방식에 따라 달라집니다.
거래가 성공하면 UPURTransactionDetails 오브젝트를 사용하여 UnityPurchasingTransactionCompletionHandler 함수를 호출합니다.
거래가 실패하면 UPURTransactionError 오브젝트를 사용하여 UnityPurchasingTransactionErrorHandler 함수를 호출합니다.
마지막으로 [USRVUnityPurchasing setDelegate: [[MyPurchasing alloc] init]]을 사용하여 델리게이트를 설정합니다.
USRVUnityPurchasingDelegate 구현 예제
#import <UnityAds/USRVUnityPurchasingDelegate.h>
@interface MyPurchasing <USRVUnityPurchasingDelegate>
@end
@implementation MyPurchasing
-(void) loadProducts: (UnityPurchasingLoadProductsCompletionHandler) completionHandler {
completionHandler (@[[UPURProduct build: ^(UPURProductBuilder *builder) {
builder.productId = @"100BronzeCoins";
builder.localizedTitle = @"100 Bronze Coins";
builder.localizedPriceString = @"$1.99";
builder.localizedPrice = [NSDecimalNumber decimalNumberWithString: @"1.99"];
builder.isoCurrencyCode = @"USD";
builder.localizedDescription = @"Awesome Bronze Coins available for a low price!";
builder.productType = @"Consumable";
}]]);
}
-(void) purchaseProduct: (NSString *) productId completionHandler: (UnityPurchasingTransactionCompletionHandler) completionHandler errorHandler: (UnityPurchasingTransactionErrorHandler) errorHandler userInfo: (nullable NSDictionary *) extras {
thirdPartyPurchasing.purchase (productId); // Generic developer purchasing function
// If purchase succeeds:
completionHandler ([UPURTransactionDetails build: ^(UPURTransactionDetailsBuilder *builder) {
builder.productId = productId;
builder.transactionId = thirdPartyPurchasing.transactionId;
builder.currency = @"USD";
builder.price = [NSDecimalNumber decimalNumberWithString: @"1.99"];
builder.receipt = @"{\n\"data\": \"{\\\"Store\\\":\\\"fake\\\",\\\"TransactionID\\\":\\\"ce7bb1ca-bd34-4ffb-bdee-83d2784336d8\\\",\\\"Payload\\\":\\\"{ \\\\\\\"this\\\\\\\": \\\\\\\"is a fake receipt\\\\\\\" }\\\"}\"\n}";
}]);
// If purchase fails:
errorHandler (kUPURTransactionErrorNetworkError, nil);
}
@end구매 어댑터를 구현했다면 setDelegate 메서드를 사용하여 레퍼런스를 제공해야 합니다. 마지막으로, 해당 플랫폼에서 프로젝트의 게임 ID를 이용하여 SDK를 초기화해야 합니다. ID는 Developer Dashboard의 Operate 탭에서 프로젝트를 선택한 다음, 왼쪽 내비게이션에서 Monetization > Platforms를 선택하여 찾을 수 있습니다.
오류를 방지하려면 게임 런타임 수명주기에서 최대한 이른 시점에 이 호출을 구현하는 것이 좋습니다. 예를 들면 다음과 같습니다.
#import "ViewController.h"
@implementation ViewController
- (void) viewDidLoad {
[super viewDidLoad];
[USRVUnityPurchasing setDelegate: [[MyPurchasing alloc] init]];
[UnityMonetization initialize: @"1234567" delegate: self testMode: true];
}
@end구매 델리게이트를 관리하는 정적인 클래스이며 SDK가 커스텀 IAP 구현으로부터 정보를 가져올 때 필요로 하는 델리게이트입니다.
@interface USRVUnityPurchasing: NSObject
+(void) setDelegate: (id<USRVUnityPurchasingDelegate>) delegate;
+(nullable id<USRVUnityPurchasingDelegate>) getDelegate;
@end개발자가 구현하여 SDK에 다시 전달하는 델리게이트입니다.
typedef void (^UnityPurchasingLoadProductsCompletionHandler) (NSArray<UPURProduct*>*);
typedef void (^UnityPurchasingTransactionCompletionHandler) (UPURTransactionDetails*);
typedef void (^UnityPurchasingTransactionErrorHandler) (UPURTransactionError, NSException*);
@protocol USRVUnityPurchasingDelegate
-(void) loadProducts: (UnityPurchasingLoadProductsCompletionHandler) completionHandler;
-(void) purchaseProduct: (NSString *) productId
completionHandler: (UnityPurchasingTransactionCompletionHandler) completionHandler
errorHandler: (UnityPurchasingTransactionErrorHandler) errorHandler
userInfo: (nullable NSDictionary *) extras;
@endSDK는 이를 호출하여 이용할 수 있는 제품의 목록을 가져옵니다. 제품을 등록하기 위해 UPURProduct 오브젝트를 받는 UnityPurchasingProductsCompletionHandler 함수를 사용합니다. 예를 들면 다음과 같습니다.
-(void) loadProducts: (UnityPurchasingLoadProductsCompletionHandler) completionHandler {
completionHandler (@[[UPURProduct build:^(UPURProductBuilder *builder){
builder.productId = @"100BronzeCoins";
builder.localizedTitle = @"100 Bronze Coins";
builder.localizedPriceString = @"$1.99";
builder.localizedPrice = [NSDecimalNumber decimalNumberWithString:@"1.99"];
builder.isoCurrencyCode = @"USD";
builder.localizedDescription = @"Awesome Bronze Coins available for a low price!";
builder.productType = @"Consumable";
}]]);
}UPURProduct
SDK가 수익화를 최적화하는 데 사용하는 오브젝트로 전환된 IAP 제품입니다.
다음 필드를 @interface UPURProductBuilder: NSObject builder에 설정한 다음, +(instancetype) build: (void (^) (UPURProductBuilder *)) buildBlock을 호출하여 최종 오브젝트를 구축합니다.
| 속성 | 설명 |
|---|---|
@property (strong, nonatomic, readonly) NSString *productId |
제품의 내부 레퍼런스 ID입니다. |
@property (strong, nonatomic, readonly) NSString *localizedTitle |
소비자가 스토어 UI에서 보는 제품 이름입니다. |
@property (nonatomic, readonly) NSDecimalNumber *localizedPrice |
소비자가 스토어 UI에서 보는 가격 문자열이며 화폐 기호가 포함됩니다. |
@property (strong, nonatomic, readonly) NSString *localizedPriceString |
제품 가격의 내부 시스템 값입니다. |
@property (strong, nonatomic, readonly) NSString *isoCurrencyCode |
제품의 현지 화폐의 ISO 코드입니다. |
@property (strong, nonatomic, readonly) NSString *localizedDescription | 소비자가 스토어 UI에서 보는 제품 설명입니다.
@property (strong, nonatomic, readonly) NSString *productType | Unity는 “Consumable(소모품)”과 “Non-Consumable(비소모품)”, 그리고 “Subscription(구독)” 제품 유형을 지원합니다.
제품 속성에 대한 자세한 내용은 제품 정의 참고 문서를 참조하세요.
사용자가 프로모션 에셋의 구매하기 버튼을 클릭하면 SDK는 이 함수를 호출합니다. Unity는 구매된 제품의 ID를 인앱 구매 시스템에 전달합니다. 이 함수는 UnityPurchasingTransactionCompletionHandler 및 UnityPurchasingTransactionErrorHandler 함수를 사용하여 구현된 내용에 따라 구매 성공 또는 실패를 핸들링합니다.
성공적으로 완료되는 거래를 핸들링하는 커스텀 게임 로직입니다. 아래 예제에서는 거래가 성공하면 UnityPurchasingTransactionCompletionHandler를 호출하고 UPURTransactionDetails 오브젝트를 빌드합니다.
실패한 거래를 핸들링하는 커스텀 게임 로직입니다. 이 함수는 TransactionDetails 오브젝트를 받습니다. 아래 예제에서 거래가 실패하면 UnityPurchasingTransactionErrorHandler를 호출하고 UPURTransactionError 열거형을 반환합니다.
purchaseProduct 구현 예제
-(void) purchaseProduct: (NSString *) productId completionHandler: (UnityPurchasingTransactionCompletionHandler) completionHandler errorHandler: (UnityPurchasingTransactionErrorHandler) errorHandler userInfo: (nullable NSDictionary *) extras {
thirdPartyPurchasing.purchase (productId); // Generic developer purchasing function
// If purchase succeeds:
completionHandler ([UPURTransactionDetails build: ^(UPURTransactionDetailsBuilder *builder) {
builder.productId = productId;
builder.transactionId = thirdPartyPurchasing.transactionId;
builder.currency = @"USD";
builder.price = [NSDecimalNumber decimalNumberWithString: @"1.99"];
builder.receipt = @"{\n\"data\": \"{\\\"Store\\\":\\\"fake\\\",\\\"TransactionID\\\":\\\"ce7bb1ca-bd34-4ffb-bdee-83d2784336d8\\\",\\\"Payload\\\":\\\"{ \\\\\\\"this\\\\\\\": \\\\\\\"is a fake receipt\\\\\\\" }\\\"}\"\n}";
}]);
// If purchase fails:
errorHandler (kUPURTransactionErrorNetworkError, nil);
}
@endUPURTransactionDetails
SDK가 수익화를 최적화하는 데 사용하는 오브젝트로 전환된 IAP 거래 영수기록입니다.
| 속성 | 설명 |
|---|---|
@property (strong, nonatomic, readonly) NSString *productId |
제품의 내부 레퍼런스 ID입니다. |
@property (strong, nonatomic, readonly) NSString *transactionId |
거래에 대한 내부 레퍼런스 ID입니다. |
@property (strong, nonatomic, readonly) NSString *receipt |
거래의 세부 내용을 다루는 appStoreReceiptURL의 JSON 필드입니다. Store, TransactionID 및 Payload를 포함하는 JSON 오브젝트로 영수기록을 인코딩합니다. |
@property (strong, nonatomic, readonly) NSDecimalNumber *price |
제품 가격의 내부 시스템 값입니다. |
@property (strong, nonatomic, readonly) NSString *currency |
제품의 현지 화폐의 ISO 코드입니다. |
자세한 내용은 인앱 구매 영수기록 필드 참고 문서를 참조하세요.
UPURStore
거래가 발생한 스토어를 나타내는 열거형입니다.
typedef NS_ENUM (NSInteger, UPURStore) {
kUPURStoreNotSpecified,
kUPURStoreGooglePlay,
kUPURStoreAmazonAppStore,
kUPURStoreCloudMoolah,
kUPURStoreSamsungApps,
kUPURStoreXiaomiMiPay,
kUPURStoreMacAppStore,
kUPURStoreAppleAppStore,
kUPURStoreWinRT,
kUPURStoreTizenStore,
kUPURStoreFacebookStore
};
NSString *NSStringFromUPURAppStore(UPURStore);UnityPurchasingTransactionError
거래 실패 사유를 나타내는 열거형입니다.
typedef NS_ENUM (NSInteger, UPURTransactionError) {
kUPURTransactionErrorNotSupported,
kUPURTransactionErrorItemUnavailable,
kUPURTransactionErrorUserCancelled,
kUPURTransactionErrorNetworkError,
kUPURTransactionErrorServerError,
kUPURTransactionErrorUnknownError
};
NSString *NSStringFromUPURTransactionError (UPURTransactionError);SDK는 수익화 최적화를 지원하기 위해 비Unity 개발자에게 Unity Analytics API를 제공합니다. 다음 분석 이벤트를 구현하여 다시 SDK로 보내면 게임의 경제를 심층적으로 분석하는 데 도움이 될 수 있습니다. SDK가 플레이어의 동작에 대해서 더 많은 정보를 파악할수록 수익화 전략을 더 효과적으로 관리할 수 있습니다.
@interface UnityAnalytics: NSObject플레이어가 게임 내에서 아이템을 구매할 때 이 이벤트를 호출합니다.
+ (void) onItemAcquired: (NSString *) transactionId itemId: (NSString *) itemId transactionContext: (NSString *) transactionContext level: (NSString *) level itemType: (NSString *) itemType amount: (float) amount balance: (float) balance acquisitionType: (UnityAnalyticsAcquisitionType) acquisitionType;플레이어가 게임 내에서 아이템을 소모할 때 이 이벤트를 호출합니다.
+ (void) onItemSpent: (NSString *) transactionId itemId: (NSString *) itemId transactionContext: (NSString *) transactionContext level: (NSString *) level itemType: (NSString *) itemType amount: (float) amount balance: (float) balance acquisitionType: (UnityAnalyticsAcquisitionType) acquisitionType;| 파라미터 | 유형 | 설명 |
|---|---|---|
transactionContext |
NSString |
거래를 위한 게임 내 컨텍스트의 설명입니다(예: 전리품 상자). |
amount |
NSFloat |
획득한 리소스의 수량입니다. |
itemId |
NSString |
획득한 리소스에 대한 내부 레퍼런스 ID입니다. |
balance |
NSFloat |
플레이어가 획득한 리소스의 새로운(거래 후) 수량입니다. |
itemType |
NSString |
획득한 리소스의 범주입니다(예: “Premium currency”). |
level |
NSString |
플레이어가 리소스를 획득한 레벨/지역의 이름 또는 ID입니다(예: 1레벨 스토어). |
transactionId |
NSString |
거래에 대한 내부 레퍼런스 ID입니다. 원하는 바에 따라 이러한 식별자를 활용하여 다수의 이벤트를 하나의 거래로 그룹화할 수 있습니다. |
acquisitionType |
UnityAnalyticsAcquisitionType |
게임 내 화폐(Soft) 또는 프리미엄 화폐(Premium)를 나타냅니다. |
이 이벤트는 SDK가 Promo를 표시할 최적의 시점을 인지하도록 교육하고 지원합니다. 다음 예제를 한 번 살펴보도록 하겠습니다.
플레이어가 300 Gold Coins를 구매하고 250 Gold Coins를 소비한 경우에 금화의 보유액이 감소했으므로, 데이터 모델은 Gold Coins를 더 획득할 수 있는 Promo를 표시하기에 적합한 시점이라고 판단할 수 있습니다.
[UnityAnalytics onItemAcquired: @"ABCD" itemId: @"300goldCoins" transactionContext: @"3rd level store" level: @"3" itemType: @"in-game-currency" amount: 300.0F balance: 300.0F acquisitionType: kUnityAnalyticsAcquisitionTypePremium];
[UnityAnalytics onItemSpent: @"ABCD" itemId: @"250goldCoins" transactionContext: @"4th level store" level: @"4" itemType: @"in-game-item" amount: 250.0F balance: 50.0F acquisitionType: kUnityAnalyticsAcquisitionTypePremium];플레이어가 100마리의 Cows를 팔아서 400마리의 Pigs를 받았다면 데이터 모델은 줄어든 Cows를 보충할 수 있는 Promo를 표시하기에 적합한 시점이라고 판단할 수 있습니다.
[UnityAnalytics onItemAcquired: @"ABCD" itemId: @"400pigs" transactionContext: @"Newbie Bazaar" level: @"newbieBazaar" itemType: @"in-game-currency" amount: 400.0F balance: 400.0F acquisitionType: kUnityAnalyticsAcquisitionTypeSoft];
[UnityAnalytics onItemSpent: @"ABCD" itemId: @"100cows" transactionContext: @"Newbie Bazaar" level: @"newbieBazaar" itemType: @"in-game-item" amount: 100.0F balance: 0.0F acquisitionType: kUnityAnalyticsAcquisitionTypeSoft];UnityAnalyticsAcquisitionType
열거형 자료로 아이템이 kUnityAnalyticsAcquisitionTypeSoft(게임 내 화폐)인지 아니면 kUnityAnalyticsAcquisitionTypePremium(현실 세계 화폐)인지를 나타냅니다.
typedef NS_ENUM (NSInteger, UnityAnalyticsAcquisitionType) {
kUnityAnalyticsAcquisitionTypeUnset,
kUnityAnalyticsAcquisitionTypeSoft,
kUnityAnalyticsAcquisitionTypePremium
};
NSString *NSStringFromUnityAnalyticsAcquisitionType (UnityAnalyticsAcquisitionType);플레이어가 게임 내에서 레벨을 통과하지 못했을 때 이 함수를 호출합니다. 데이터 모델은 이를 사용하여 플레이어가 다음 번 플레이할 때 레벨을 통과하는 데 도움이 될 수 있는 제품의 Promo를 표시할 수 있습니다.
+ (void) onLevelFail: (int) levelIndex;플레이어가 게임 내에서 레벨을 완료했을 때 이 함수를 호출합니다. onLevelFail과 함께 사용 시, 사용자가 어느 레벨에서 고전하는지 그리고 각 레벨에서 효과적으로 제공할 수 있는 Promo가 무엇인지를 데이터 모델이 간파할 수 있습니다.
+ (void) onLevelUp: (int) theNewLevelIndex;