diff --git a/src/Plugin.InAppBilling/InAppBilling.apple.cs b/src/Plugin.InAppBilling/InAppBilling.apple.cs
index d4b36eb..e09718b 100644
--- a/src/Plugin.InAppBilling/InAppBilling.apple.cs
+++ b/src/Plugin.InAppBilling/InAppBilling.apple.cs
@@ -5,7 +5,6 @@
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
-using UIKit;
namespace Plugin.InAppBilling
{
@@ -13,9 +12,29 @@ namespace Plugin.InAppBilling
/// Implementation for InAppBilling
///
[Preserve(AllMembers = true)]
- public class InAppBillingImplementation : BaseInAppBilling
+ public class InAppBillingImplementation : BaseInAppBilling, ISKProductsRequestDelegate
{
- static bool IsiOS112 => UIDevice.CurrentDevice.CheckSystemVersion(11, 2);
+#if __IOS__ || __TVOS__
+ static bool HasIntroductoryPrice => UIKit.UIDevice.CurrentDevice.CheckSystemVersion(11, 2);
+#else
+ static bool initIntro, hasIntro;
+ static bool HasIntroductoryPrice
+ {
+ get
+ {
+ if (initIntro)
+ return hasIntro;
+
+ initIntro = true;
+
+
+ using var info = new NSProcessInfo();
+ hasIntro = info.IsOperatingSystemAtLeastVersion(new NSOperatingSystemVersion(10,13,2));
+ return hasIntro;
+
+ }
+ }
+#endif
///
/// Gets or sets a callback for out of band purchases to complete.
@@ -38,13 +57,15 @@ public InAppBillingImplementation()
///
public override bool InTestingMode { get; set; }
- ///
- /// Get product information of a specific product
- ///
- /// Sku or Id of the product(s)
- /// Type of product offering
- ///
- public async override Task> GetProductInfoAsync(ItemType itemType, params string[] productIds)
+ public IntPtr Handle => throw new NotImplementedException();
+
+ ///
+ /// Get product information of a specific product
+ ///
+ /// Sku or Id of the product(s)
+ /// Type of product offering
+ ///
+ public async override Task> GetProductInfoAsync(ItemType itemType, params string[] productIds)
{
var products = await GetProductAsync(productIds);
@@ -56,8 +77,8 @@ public async override Task> GetProductInfoAsync
ProductId = p.ProductIdentifier,
Description = p.LocalizedDescription,
CurrencyCode = p.PriceLocale?.CurrencyCode ?? string.Empty,
- LocalizedIntroductoryPrice = IsiOS112 ? (p.IntroductoryPrice?.LocalizedPrice() ?? string.Empty) : string.Empty,
- MicrosIntroductoryPrice = IsiOS112 ? (long)((p.IntroductoryPrice?.Price?.DoubleValue ?? 0) * 1000000d) : 0
+ LocalizedIntroductoryPrice = HasIntroductoryPrice ? (p.IntroductoryPrice?.LocalizedPrice() ?? string.Empty) : string.Empty,
+ MicrosIntroductoryPrice = HasIntroductoryPrice ? (long)((p.IntroductoryPrice?.Price?.DoubleValue ?? 0) * 1000000d) : 0
});
}
@@ -175,7 +196,9 @@ public async override Task PurchaseAsync(string productId,
Id = p.TransactionIdentifier,
ProductId = p.Payment?.ProductIdentifier ?? string.Empty,
State = p.GetPurchaseState(),
+#if __IOS__ || __TVOS__
PurchaseToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None) ?? string.Empty
+#endif
};
if (verifyPurchase == null)
@@ -203,7 +226,9 @@ Task ValidateReceipt(IInAppBillingVerifyPurchase verifyPurchase, string pr
}
- Task PurchaseAsync(string productId)
+ TaskCompletionSource productTCS;
+
+ async Task PurchaseAsync(string productId)
{
var tcsTransaction = new TaskCompletionSource();
@@ -257,13 +282,35 @@ Task PurchaseAsync(string productId)
paymentObserver.TransactionCompleted += handler;
+#if __IOS__ || __TVOS__
+
var payment = SKPayment.CreateFrom(productId);
+#else
+ productTCS?.TrySetCanceled();
+ productTCS = new TaskCompletionSource();
+ var productIdentifiers = NSSet.MakeNSObjectSet(new NSString[] { new NSString(productId) });
+ var productsRequest = new SKProductsRequest(productIdentifiers);
+ productsRequest.Delegate = this; // for SKProductsRequestDelegate.ReceivedResponse
+ productsRequest.Start();
+ var product = await productTCS.Task;
+ if (product == null)
+ throw new InAppBillingPurchaseException(PurchaseError.InvalidProduct);
+
+ var payment = SKPayment.CreateFrom(product);
+ //var payment = SKPayment.CreateFrom((SKProduct)SKProduct.FromObject(new NSString(productId)));
+#endif
SKPaymentQueue.DefaultQueue.AddPayment(payment);
- return tcsTransaction.Task;
+ return await tcsTransaction.Task;
}
+ public void ReceivedResponse(SKProductsRequest request, SKProductsResponse response)
+ {
+ productTCS?.TrySetResult(response?.Products?.FirstOrDefault());
+ }
+
+
///
/// Consume a purchase with a purchase token.
///
@@ -341,6 +388,7 @@ public override void Dispose(bool disposing)
base.Dispose(disposing);
}
+
}
@@ -471,11 +519,15 @@ public static InAppBillingPurchase ToIABPurchase(this SKPaymentTransaction trans
if (p == null)
return null;
+#if __IOS__ || __TVOS__
var finalToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
if (string.IsNullOrEmpty(finalToken))
finalToken = transaction.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
- return new InAppBillingPurchase
+#else
+ var finalToken = string.Empty;
+#endif
+ return new InAppBillingPurchase
{
TransactionDateUtc = NSDateToDateTimeUtc(transaction.TransactionDate),
Id = p.TransactionIdentifier,
diff --git a/src/Plugin.InAppBilling/Plugin.InAppBilling.csproj b/src/Plugin.InAppBilling/Plugin.InAppBilling.csproj
index b9471e2..cd4c861 100644
--- a/src/Plugin.InAppBilling/Plugin.InAppBilling.csproj
+++ b/src/Plugin.InAppBilling/Plugin.InAppBilling.csproj
@@ -1,6 +1,6 @@
- netstandard2.0;MonoAndroid10.0;Xamarin.iOS10;Xamarin.TVOS10
+ netstandard2.0;MonoAndroid10.0;Xamarin.iOS10;Xamarin.TVOS10;Xamarin.Mac20
$(TargetFrameworks);uap10.0.16299;
Plugin.InAppBilling
Plugin.InAppBilling
@@ -61,6 +61,7 @@
+
@@ -77,7 +78,7 @@
-
+
@@ -90,4 +91,8 @@
+
+
+
+
\ No newline at end of file