iOS의 경우 In App Purchase 항목에 Non-Consumable(비소모) 상품이 있을 경우,
필수로 수동 구매복구 기능을 지원해야 한다.
(Google Play와 Universal Windows Applications와 같이 자동 복구를 지원하는 플랫폼에선 IStoreListener의 초기화 시점에 자동으로 복구된다.)
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
extensions.GetExtension<IAppleExtensions> ().RestoreTransactions (result => {
if (result) {
// This does not mean anything was restored,
// merely that the restoration process succeeded.
} else {
// Restoration failed.
}
});
}
iOS에서는 보통 구매복구 Button을 따로 만들고, 위 소스를 호출한다.
그러면 Unity IAP는 구매 내역이 있는 상품에 대해 동일한 구매 로직을 재현한다.
즉, IStoreListener의 ProcessPurchase 메서드가 구매한 비소모성 상품마다 호출되는 것이다.
# IAPController.cs
using UnityEngine;
using UnityEngine.Purchasing;
public class IAPController : MonoBehaviour, IStoreListener
{
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
extensions.GetExtension<IAppleExtensions> ().RestoreTransactions (result => {
if (result) {
// This does not mean anything was restored,
// merely that the restoration process succeeded.
} else {
// Restoration failed.
}
});
}
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
{
}
}
ProcessPurchase 메서드는 말그대로 구매를 처리하는데, PurchaseEventArgs라는 매개변수를 갖고 있다.
PurchaseEventArgs를 살펴보면 다음과 같다.
# PurchaseEventArgs.cs
namespace UnityEngine.Purchasing
{
public class PurchaseEventArgs
{
internal PurchaseEventArgs(Product purchasedProduct)
{
this.purchasedProduct = purchasedProduct;
}
public Product purchasedProduct { get; private set; }
}
}
PurchaseEventArgs는 Product를 갖고 있다.
# Product.cs
namespace UnityEngine.Purchasing
{
public class Product
{
internal Product(ProductDefinition definition, ProductMetadata metadata, string receipt)
{
this.definition = definition;
this.metadata = metadata;
this.receipt = receipt;
}
internal Product(ProductDefinition definition, ProductMetadata metadata)
: this(definition, metadata, (string) null)
{
}
public ProductDefinition definition { get; private set; }
public ProductMetadata metadata { get; internal set; }
public bool availableToPurchase { get; internal set; }
public string transactionID { get; internal set; }
public bool hasReceipt
{
get { return !string.IsNullOrEmpty(this.receipt); }
}
public string receipt { get; internal set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
Product product = obj as Product;
if (product == null)
return false;
return this.definition.Equals((object) product.definition);
}
public override int GetHashCode()
{
return this.definition.GetHashCode();
}
}
}
Product는 각종 상품 정보를 담고 있고, 여기서 갖고 있는 데이터를 ProcessPurchase에서 이용할 수 있다.
# IAPController.cs
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
{
if (e.purchasedProduct.definition.storeSpecificId == SOME_NON_CONSUMABLE_ITEM_ID)
{
// SOME_NON_CONSUMABLE_ITEM_ID에 대한 구매 처리
}
return PurchaseProcessingResult.Complete;
}
상품의 store id를 확인하여 그에 해당하는 메서드를 구현한다.
유의할 점)
ProcessPurchase에서 호출되는 구매 처리 메서드는 독립적이어야 한다.
예를 들어, 상점에서만 유의미한 값을 갖는 변수를 사용하는 등 실제 아이템 구매 시점에서만 제대로 작동할 수 있는 로직이 포함되어 있을 경우 당연히 구매복구가 이루어지지 않는다.
참고) Restoring Transactions - https://docs.unity3d.com/Manual/UnityIAPRestoringTransactions.html
'Unity & C# > iOS & Mac' 카테고리의 다른 글
IAP Sandbox 계정 설정 (0) | 2020.04.28 |
---|