fix: 修复 IAP 启动报错 BUG, 修复 取值为空的 BUG

deeplink
胡宇飞 2024-04-08 22:59:23 +08:00
parent 19c9cb831b
commit d76f6de15e
3 changed files with 78 additions and 50 deletions

View File

@ -10,6 +10,7 @@ namespace Guru
public class IAPModel
{
public static readonly float SaveInterval = 3;
public static readonly int MaxReceiptCount = 30;
public static readonly string PlatformAndroid = "android";
public static readonly string PlatformIOS = "ios";
@ -20,8 +21,6 @@ namespace Guru
public List<GoogleOrderData> googleOrders;
public List<AppleOrderData> appleOrders;
/// <summary>
/// 是否还有未上报的 Google Order
/// </summary>
@ -33,11 +32,12 @@ namespace Guru
public bool HasUnreportedAppleOrder => (appleOrders?.Count ?? 0) > 0;
#region Initialize
public IAPModel()
{
androidTokens = new List<string>(20);
iosReceipts = new List<string>(20);
androidTokens = new List<string>(MaxReceiptCount);
iosReceipts = new List<string>(MaxReceiptCount);
googleOrders = new List<GoogleOrderData>(20);
appleOrders = new List<AppleOrderData>(20);
}
@ -72,35 +72,45 @@ namespace Guru
PlayerPrefs.SetString(nameof(IAPModel), json);
}
#endregion
#region Receipt
#region Google Token
/// <summary>
/// 添加 Google 的收据数据
/// </summary>
/// <param name="token"></param>
public void AddToken(string token)
{
if (androidTokens == null) androidTokens = new List<string>(20);
if (androidTokens == null) androidTokens = new List<string>(MaxReceiptCount);
if(string.IsNullOrEmpty(token)) return;
if(androidTokens.Count >= MaxReceiptCount) androidTokens.RemoveAt(0);
androidTokens.Add(token);
Save();
}
/// <summary>
/// 添加收据
/// </summary>
/// <param name="receipt"></param>
/// <param name="platform"></param>
public void AddReceipt(string receipt)
{
if (iosReceipts == null) iosReceipts = new List<string>(20);
if(string.IsNullOrEmpty(receipt)) return;
iosReceipts.Add(receipt);
Save();
}
public bool IsTokenExists(string token)
{
if (androidTokens == null) return false;
return androidTokens.Contains(token);
}
#endregion
#region iOS Receipt
/// <summary>
/// 添加收据
/// </summary>
/// <param name="receipt"></param>
public void AddReceipt(string receipt)
{
if (iosReceipts == null) iosReceipts = new List<string>(MaxReceiptCount);
if(string.IsNullOrEmpty(receipt)) return;
if(iosReceipts.Count >= MaxReceiptCount) iosReceipts.RemoveAt(0);
iosReceipts.Add(receipt);
Save();
}
public bool IsReceiptExist(string receipt)
{
@ -110,7 +120,7 @@ namespace Guru
#endregion
#region Orders
#region Google Orders
public void AddGoogleOrder(GoogleOrderData order)
{
@ -153,6 +163,10 @@ namespace Guru
Save();
}
#endregion
#region Apple Orders
public void AddAppleOrder(AppleOrderData order)
{
if (HasAppleOrder(order)) return;

View File

@ -195,7 +195,7 @@ namespace Guru
// 建立本地的商品信息列表
if (string.IsNullOrEmpty(item.Category)) item.Category = DefaultCategory;
_products[item.ProductId] = new ProductInfo() { Setting = item };
_products[item.ProductId] = new ProductInfo(item);
}
}
// 调用插件初始化
@ -864,17 +864,25 @@ namespace Guru
#if UNITY_ANDROID
if (_model.HasUnreportedGoogleOrder)
{
foreach (var o in _model.googleOrders)
int i = 0;
while (_model.googleOrders.Count > 0
&& i < _model.googleOrders.Count)
{
var o = _model.googleOrders[i];
ReportGoogleOrder(o);
i++;
}
}
#elif UNITY_IOS
if (_model.HasUnreportedAppleOrder)
{
foreach (var o in _model.appleOrders)
int i = 0;
while (_model.appleOrders.Count > 0
&& i < _model.appleOrders.Count)
{
var o = _model.appleOrders[i];
ReportAppleOrder(o);
i++;
}
}
#endif
@ -927,6 +935,7 @@ namespace Guru
private void ReportNextOrder(RequestBase request)
{
if(_orderRequests == null) _orderRequests = new Queue<RequestBase>(20);
_orderRequests.Enqueue(request);
if(isOrderSending) return;
@ -943,11 +952,12 @@ namespace Guru
{
if (_orderRequests != null && _orderRequests.Count > 0)
{
// 如果上报队列不为空, 则尝试上报
isOrderSending = true;
var request = _orderRequests.Dequeue();
if (request == null)
{
// 跳过空请求
OnSendNextOrder();
return;
}
@ -959,51 +969,50 @@ namespace Guru
{
if (_model.IsTokenExists(go.token))
{
OnSendNextOrder();
OnSendNextOrder(); // 跳过上报过的 Google 订单
return;
}
_model.AddGoogleOrder(go.orderData); // 尝试缓存 order
_model.AddGoogleOrder(go.orderData); // 缓存当前 orderData 等待上报后再消除
}
if( ao != null)
else if( ao != null)
{
if (_model.IsReceiptExist(ao.receipt))
{
OnSendNextOrder();
OnSendNextOrder(); // 跳过上报过的 Apple 订单
return;
}
_model.AddAppleOrder(ao.orderData); // 尝试缓存 order
_model.AddAppleOrder(ao.orderData); // 缓存当前 orderData 等待上报后再消除
}
request.SetTimeOut(OrderRequestTimeout)
.SetRetryTimes(OrderRequestRetryTimes)
.SetSuccessCallBack(() =>
{
//---------------- Success ------------------------
if (go != null)
{
_model.AddToken(go.token);
_model.RemoveGoogleOrder(go.orderData);
_model.AddToken(go.token); // 记录当前的 Google 订单
_model.RemoveGoogleOrder(go.orderData); // 成功后清除缓存 orderData
}
else if (ao != null)
{
_model.AddReceipt(ao.receipt);
_model.RemoveAppleOrder(ao.orderData);
_model.AddReceipt(ao.receipt); // 记录当前的 Apple 订单
_model.RemoveAppleOrder(ao.orderData); // 成功后清除缓存 orderData
}
OnSendNextOrder();
OnSendNextOrder(); // NEXT Order
})
.SetFailCallBack(() =>
{
//---------------- Fail ------------------------
if (go != null)
{
ReportGoogleOrderLost(go.orderData);
ReportGoogleOrderLost(go.orderData); // 上报 Google 订单缺失打点
}
else if (ao != null)
{
ReportAppleOrderLost(ao.orderData);
ReportAppleOrderLost(ao.orderData); // 上报 Apple 订单缺失打点
}
OnSendNextOrder();
OnSendNextOrder(); // NEXT Order
})
.Send();
}

View File

@ -64,19 +64,24 @@ namespace Guru
public partial class ProductInfo
{
private Product _product;
public ProductSetting Setting;
private ProductSetting _setting;
public ProductSetting Setting => _setting;
public Product Product => _product;
public ProductInfo(ProductSetting setting)
{
_setting = setting;
}
public void SetProduct(Product product) => _product = product;
public string Name => Setting.ProductName;
public string Id => Product.definition.id;
public double Price => (double?)Product?.metadata?.localizedPrice ?? Setting.Price;
public string CurrencyCode => Product?.metadata?.isoCurrencyCode ?? "$";
public string Category => Setting.Category;
public string Type => Setting.Type == ProductType.Subscription ? "subscription" : "product";
public bool IsFree => Setting.IsFree;
public string LocalizedPriceString => Product?.metadata.localizedPriceString ?? $"{CurrencyCode}{Setting.Price}";
public string Name => _setting.ProductName;
public string Id => _product?.definition?.id ?? _setting.ProductId;
public double Price => (double?)_product?.metadata?.localizedPrice ?? _setting.Price;
public string CurrencyCode => _product?.metadata?.isoCurrencyCode ?? "$";
public string Category => _setting.Category;
public string Type => _setting.Type == ProductType.Subscription ? "subscription" : "product";
public bool IsFree => _setting.IsFree;
public string LocalizedPriceString => _product?.metadata?.localizedPriceString ?? $"{CurrencyCode}{_setting.Price}";
}
}