Skip to content

Commit

Permalink
[in_app_purchase] Update iOS Pigeon for non-nullable generics (#7820)
Browse files Browse the repository at this point in the history
Updates the Pigeon definition to uses non-nullable generics now that it's possible. Leaves a few nullable value types in maps where that corresponds to the public API of the collections passed in, so reflects an API decision rather than a Pigeon limitation.

While updating this, also fixes the fact that the Obj-C Pigeon generation wasn't configured to use a prefix, which created the possibility of collision with Apple code due to using an Apple-reserved prefix on all the Pigeon-generated code.

Part of flutter/flutter#155891
  • Loading branch information
stuartmorgan authored Oct 18, 2024
1 parent 3b7ee86 commit dafd753
Show file tree
Hide file tree
Showing 25 changed files with 1,095 additions and 967 deletions.
10 changes: 7 additions & 3 deletions packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
## 0.3.18+3

* Updates Pigeon for non-nullable collection type support.

## 0.3.18+2

* Adds support for StoreKit2's `purchase` and `transactions`

## 0.3.18+1

* Adds support for StoreKit2's `canMakePayments` and `products`
* Adds support for StoreKit2's `canMakePayments` and `products`

## 0.3.18

Expand Down Expand Up @@ -53,7 +57,7 @@

## 0.3.12

* Converts `refreshReceipt()`, `startObservingPaymentQueue()`, `stopObservingPaymentQueue()`,
* Converts `refreshReceipt()`, `startObservingPaymentQueue()`, `stopObservingPaymentQueue()`,
`registerPaymentQueueDelegate()`, `removePaymentQueueDelegate()`, `showPriceConsentIfNeeded()` to pigeon.

## 0.3.11
Expand All @@ -80,7 +84,7 @@

## 0.3.7

* Adds `Future<SKStorefrontWrapper?> storefront()` in SKPaymentQueueWrapper class.
* Adds `Future<SKStorefrontWrapper?> storefront()` in SKPaymentQueueWrapper class.

## 0.3.6+7

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,33 +57,33 @@ NS_ASSUME_NONNULL_BEGIN
withError:(NSString *_Nullable *_Nullable)error
API_AVAILABLE(ios(12.2));

+ (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon:
+ (nullable FIASKPaymentTransactionMessage *)convertTransactionToPigeon:
(nullable SKPaymentTransaction *)transaction;

+ (nullable SKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront
+ (nullable FIASKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront
API_AVAILABLE(ios(13.0));

+ (nullable SKPaymentDiscountMessage *)convertPaymentDiscountToPigeon:
+ (nullable FIASKPaymentDiscountMessage *)convertPaymentDiscountToPigeon:
(nullable SKPaymentDiscount *)discount API_AVAILABLE(ios(12.2));

+ (nullable SKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment
+ (nullable FIASKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment
API_AVAILABLE(ios(12.2));

+ (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error;
+ (nullable FIASKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error;

+ (nullable SKProductsResponseMessage *)convertProductsResponseToPigeon:
+ (nullable FIASKProductsResponseMessage *)convertProductsResponseToPigeon:
(nullable SKProductsResponse *)payment;

+ (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product
+ (nullable FIASKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product
API_AVAILABLE(ios(12.2));

+ (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon:
+ (nullable FIASKProductDiscountMessage *)convertProductDiscountToPigeon:
(nullable SKProductDiscount *)productDiscount API_AVAILABLE(ios(12.2));

+ (nullable SKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale
+ (nullable FIASKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale
API_AVAILABLE(ios(12.2));

+ (nullable SKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon:
+ (nullable FIASKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon:
(nullable SKProductSubscriptionPeriod *)period API_AVAILABLE(ios(12.2));
@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,12 @@ + (SKPaymentDiscount *)getSKPaymentDiscountFromMap:(NSDictionary *)map
return discount;
}

+ (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon:
+ (nullable FIASKPaymentTransactionMessage *)convertTransactionToPigeon:
(nullable SKPaymentTransaction *)transaction API_AVAILABLE(ios(12.2)) {
if (!transaction) {
return nil;
}
SKPaymentTransactionMessage *msg = [SKPaymentTransactionMessage
return [FIASKPaymentTransactionMessage
makeWithPayment:[self convertPaymentToPigeon:transaction.payment]
transactionState:[self convertTransactionStateToPigeon:transaction.transactionState]
originalTransaction:transaction.originalTransaction
Expand All @@ -306,10 +306,9 @@ + (nullable SKPaymentTransactionMessage *)convertTransactionToPigeon:
timeIntervalSince1970]]
transactionIdentifier:transaction.transactionIdentifier
error:[self convertSKErrorToPigeon:transaction.error]];
return msg;
}

+ (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error {
+ (nullable FIASKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error {
if (!error) {
return nil;
}
Expand All @@ -320,127 +319,117 @@ + (nullable SKErrorMessage *)convertSKErrorToPigeon:(nullable NSError *)error {
userInfo[key] = [FIAObjectTranslator encodeNSErrorUserInfo:value];
}

SKErrorMessage *msg = [SKErrorMessage makeWithCode:error.code
domain:error.domain
userInfo:userInfo];
return msg;
return [FIASKErrorMessage makeWithCode:error.code domain:error.domain userInfo:userInfo];
}

+ (SKPaymentTransactionStateMessage)convertTransactionStateToPigeon:
+ (FIASKPaymentTransactionStateMessage)convertTransactionStateToPigeon:
(SKPaymentTransactionState)state {
switch (state) {
case SKPaymentTransactionStatePurchasing:
return SKPaymentTransactionStateMessagePurchasing;
return FIASKPaymentTransactionStateMessagePurchasing;
case SKPaymentTransactionStatePurchased:
return SKPaymentTransactionStateMessagePurchased;
return FIASKPaymentTransactionStateMessagePurchased;
case SKPaymentTransactionStateFailed:
return SKPaymentTransactionStateMessageFailed;
return FIASKPaymentTransactionStateMessageFailed;
case SKPaymentTransactionStateRestored:
return SKPaymentTransactionStateMessageRestored;
return FIASKPaymentTransactionStateMessageRestored;
case SKPaymentTransactionStateDeferred:
return SKPaymentTransactionStateMessageDeferred;
return FIASKPaymentTransactionStateMessageDeferred;
}
}

+ (nullable SKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment
+ (nullable FIASKPaymentMessage *)convertPaymentToPigeon:(nullable SKPayment *)payment
API_AVAILABLE(ios(12.2)) {
if (!payment) {
return nil;
}
SKPaymentMessage *msg = [SKPaymentMessage
return [FIASKPaymentMessage
makeWithProductIdentifier:payment.productIdentifier
applicationUsername:payment.applicationUsername
requestData:[[NSString alloc] initWithData:payment.requestData
encoding:NSUTF8StringEncoding]
quantity:payment.quantity
simulatesAskToBuyInSandbox:payment.simulatesAskToBuyInSandbox
paymentDiscount:[self convertPaymentDiscountToPigeon:payment.paymentDiscount]];
return msg;
}

+ (nullable SKPaymentDiscountMessage *)convertPaymentDiscountToPigeon:
+ (nullable FIASKPaymentDiscountMessage *)convertPaymentDiscountToPigeon:
(nullable SKPaymentDiscount *)discount API_AVAILABLE(ios(12.2)) {
if (!discount) {
return nil;
}
SKPaymentDiscountMessage *msg =
[SKPaymentDiscountMessage makeWithIdentifier:discount.identifier
keyIdentifier:discount.keyIdentifier
nonce:[discount.nonce UUIDString]
signature:discount.signature
timestamp:[discount.timestamp intValue]];

return msg;
return [FIASKPaymentDiscountMessage makeWithIdentifier:discount.identifier
keyIdentifier:discount.keyIdentifier
nonce:[discount.nonce UUIDString]
signature:discount.signature
timestamp:[discount.timestamp intValue]];
}

+ (nullable SKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront
+ (nullable FIASKStorefrontMessage *)convertStorefrontToPigeon:(nullable SKStorefront *)storefront
API_AVAILABLE(ios(13.0)) {
if (!storefront) {
return nil;
}
SKStorefrontMessage *msg = [SKStorefrontMessage makeWithCountryCode:storefront.countryCode
identifier:storefront.identifier];
return msg;
return [FIASKStorefrontMessage makeWithCountryCode:storefront.countryCode
identifier:storefront.identifier];
}

+ (nullable SKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon:
+ (nullable FIASKProductSubscriptionPeriodMessage *)convertSKProductSubscriptionPeriodToPigeon:
(nullable SKProductSubscriptionPeriod *)period API_AVAILABLE(ios(12.2)) {
if (!period) {
return nil;
}

SKSubscriptionPeriodUnitMessage unit;
FIASKSubscriptionPeriodUnitMessage unit;
switch (period.unit) {
case SKProductPeriodUnitDay:
unit = SKSubscriptionPeriodUnitMessageDay;
unit = FIASKSubscriptionPeriodUnitMessageDay;
break;
case SKProductPeriodUnitWeek:
unit = SKSubscriptionPeriodUnitMessageWeek;
unit = FIASKSubscriptionPeriodUnitMessageWeek;
break;
case SKProductPeriodUnitMonth:
unit = SKSubscriptionPeriodUnitMessageMonth;
unit = FIASKSubscriptionPeriodUnitMessageMonth;
break;
case SKProductPeriodUnitYear:
unit = SKSubscriptionPeriodUnitMessageYear;
unit = FIASKSubscriptionPeriodUnitMessageYear;
break;
}

SKProductSubscriptionPeriodMessage *msg =
[SKProductSubscriptionPeriodMessage makeWithNumberOfUnits:period.numberOfUnits unit:unit];

return msg;
return [FIASKProductSubscriptionPeriodMessage makeWithNumberOfUnits:period.numberOfUnits
unit:unit];
}

+ (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon:
+ (nullable FIASKProductDiscountMessage *)convertProductDiscountToPigeon:
(nullable SKProductDiscount *)productDiscount API_AVAILABLE(ios(12.2)) {
if (!productDiscount) {
return nil;
}

SKProductDiscountPaymentModeMessage paymentMode;
FIASKProductDiscountPaymentModeMessage paymentMode;
switch (productDiscount.paymentMode) {
case SKProductDiscountPaymentModeFreeTrial:
paymentMode = SKProductDiscountPaymentModeMessageFreeTrial;
paymentMode = FIASKProductDiscountPaymentModeMessageFreeTrial;
break;
case SKProductDiscountPaymentModePayAsYouGo:
paymentMode = SKProductDiscountPaymentModeMessagePayAsYouGo;
paymentMode = FIASKProductDiscountPaymentModeMessagePayAsYouGo;
break;
case SKProductDiscountPaymentModePayUpFront:
paymentMode = SKProductDiscountPaymentModeMessagePayUpFront;
paymentMode = FIASKProductDiscountPaymentModeMessagePayUpFront;
break;
}

SKProductDiscountTypeMessage type;
FIASKProductDiscountTypeMessage type;
switch (productDiscount.type) {
case SKProductDiscountTypeIntroductory:
type = SKProductDiscountTypeMessageIntroductory;
type = FIASKProductDiscountTypeMessageIntroductory;
break;
case SKProductDiscountTypeSubscription:
type = SKProductDiscountTypeMessageSubscription;
type = FIASKProductDiscountTypeMessageSubscription;
break;
}

SKProductDiscountMessage *msg = [SKProductDiscountMessage
return [FIASKProductDiscountMessage
makeWithPrice:productDiscount.price.description
priceLocale:[self convertNSLocaleToPigeon:productDiscount.priceLocale]
numberOfPeriods:productDiscount.numberOfPeriods
Expand All @@ -449,37 +438,33 @@ + (nullable SKProductDiscountMessage *)convertProductDiscountToPigeon:
.subscriptionPeriod]
identifier:productDiscount.identifier
type:type];

return msg;
}

+ (nullable SKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale
+ (nullable FIASKPriceLocaleMessage *)convertNSLocaleToPigeon:(nullable NSLocale *)locale
API_AVAILABLE(ios(12.2)) {
if (!locale) {
return nil;
}
SKPriceLocaleMessage *msg = [SKPriceLocaleMessage makeWithCurrencySymbol:locale.currencySymbol
currencyCode:locale.currencyCode
countryCode:locale.countryCode];

return msg;
return [FIASKPriceLocaleMessage makeWithCurrencySymbol:locale.currencySymbol
currencyCode:locale.currencyCode
countryCode:locale.countryCode];
}

+ (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product
+ (nullable FIASKProductMessage *)convertProductToPigeon:(nullable SKProduct *)product
API_AVAILABLE(ios(12.2)) {
if (!product) {
return nil;
}

NSArray<SKProductDiscount *> *skProductDiscounts = product.discounts;
NSMutableArray<SKProductDiscountMessage *> *pigeonProductDiscounts =
NSMutableArray<FIASKProductDiscountMessage *> *pigeonProductDiscounts =
[NSMutableArray arrayWithCapacity:skProductDiscounts.count];

for (SKProductDiscount *productDiscount in skProductDiscounts) {
[pigeonProductDiscounts addObject:[self convertProductDiscountToPigeon:productDiscount]];
};

SKProductMessage *msg = [SKProductMessage
return [FIASKProductMessage
makeWithProductIdentifier:product.productIdentifier
localizedTitle:product.localizedTitle
localizedDescription:product.localizedDescription
Expand All @@ -490,27 +475,24 @@ + (nullable SKProductMessage *)convertProductToPigeon:(nullable SKProduct *)prod
[self convertSKProductSubscriptionPeriodToPigeon:product.subscriptionPeriod]
introductoryPrice:[self convertProductDiscountToPigeon:product.introductoryPrice]
discounts:pigeonProductDiscounts];

return msg;
}

+ (nullable SKProductsResponseMessage *)convertProductsResponseToPigeon:
+ (nullable FIASKProductsResponseMessage *)convertProductsResponseToPigeon:
(nullable SKProductsResponse *)productsResponse API_AVAILABLE(ios(12.2)) {
if (!productsResponse) {
return nil;
}
NSArray<SKProduct *> *skProducts = productsResponse.products;
NSMutableArray<SKProductMessage *> *pigeonProducts =
NSMutableArray<FIASKProductMessage *> *pigeonProducts =
[NSMutableArray arrayWithCapacity:skProducts.count];

for (SKProduct *product in skProducts) {
[pigeonProducts addObject:[self convertProductToPigeon:product]];
};

SKProductsResponseMessage *msg = [SKProductsResponseMessage
return [FIASKProductsResponseMessage
makeWithProducts:pigeonProducts
invalidProductIdentifiers:productsResponse.invalidProductIdentifiers ?: @[]];
return msg;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import StoreKit
import FlutterMacOS
#endif

public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI {
public class InAppPurchasePlugin: NSObject, FlutterPlugin, FIAInAppPurchaseAPI {
private let receiptManager: FIAPReceiptManager
private var productsCache: NSMutableDictionary = [:]
private var paymentQueueDelegateCallbackChannel: FlutterMethodChannel?
Expand Down Expand Up @@ -55,7 +55,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI {
let instance = InAppPurchasePlugin(registrar: registrar)
registrar.addMethodCallDelegate(instance, channel: channel)
registrar.addApplicationDelegate(instance)
SetUpInAppPurchaseAPI(messenger, instance)
SetUpFIAInAppPurchaseAPI(messenger, instance)
if #available(iOS 15.0, macOS 12.0, *) {
InAppPurchase2APISetup.setUp(binaryMessenger: messenger, api: instance)
}
Expand Down Expand Up @@ -120,7 +120,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI {
}

public func transactionsWithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError?>)
-> [SKPaymentTransactionMessage]?
-> [FIASKPaymentTransactionMessage]?
{
return getPaymentQueueHandler()
.getUnfinishedTransactions()
Expand All @@ -130,7 +130,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI {
}

public func storefrontWithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError?>)
-> SKStorefrontMessage?
-> FIASKStorefrontMessage?
{
if #available(iOS 13.0, *), let storefront = getPaymentQueueHandler().storefront {
return FIAObjectTranslator.convertStorefront(toPigeon: storefront)
Expand All @@ -140,7 +140,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI {

public func startProductRequestProductIdentifiers(
_ productIdentifiers: [String],
completion: @escaping (SKProductsResponseMessage?, FlutterError?) -> Void
completion: @escaping (FIASKProductsResponseMessage?, FlutterError?) -> Void
) {
let request = getProductRequest(withIdentifiers: Set(productIdentifiers))
let handler = handlerFactory(request)
Expand Down
Loading

0 comments on commit dafd753

Please sign in to comment.