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

View File

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

View File

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