-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[in_app_purchase_storekit] Add storekit 2 support for canMakePayments…
… and products (#7473) This PR contains support for StoreKit2's [canMakePayments](https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments) and [products](https://developer.apple.com/documentation/storekit/product/3851116-products). This also contains basic scaffolding for SK2 support, such as pigeon translators. Part of flutter/flutter#116383
- Loading branch information
Showing
20 changed files
with
2,146 additions
and
7 deletions.
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
...p_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/InAppPurchaseStoreKit2.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension InAppPurchasePlugin: InAppPurchase2API { | ||
// MARK: - Pigeon Functions | ||
|
||
// Wrapper method around StoreKit2's canMakePayments() method | ||
// https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments | ||
func canMakePayments() throws -> Bool { | ||
return AppStore.canMakePayments | ||
} | ||
|
||
// Wrapper method around StoreKit2's products() method | ||
// https://developer.apple.com/documentation/storekit/product/3851116-products | ||
func products( | ||
identifiers: [String], completion: @escaping (Result<[SK2ProductMessage], Error>) -> Void | ||
) { | ||
Task { | ||
do { | ||
let products = try await Product.products(for: identifiers) | ||
let productMessages = products.map { | ||
$0.convertToPigeon | ||
} | ||
completion(.success(productMessages)) | ||
} catch { | ||
completion( | ||
.failure( | ||
PigeonError( | ||
code: "storekit2_products_error", | ||
message: error.localizedDescription, | ||
details: error.localizedDescription))) | ||
} | ||
} | ||
} | ||
} |
169 changes: 169 additions & 0 deletions
169
...app_purchase/in_app_purchase_storekit/darwin/Classes/StoreKit2/StoreKit2Translators.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import Foundation | ||
import StoreKit | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product { | ||
var convertToPigeon: SK2ProductMessage { | ||
|
||
return SK2ProductMessage( | ||
id: id, | ||
displayName: displayName, | ||
description: description, | ||
price: NSDecimalNumber(decimal: price).doubleValue, | ||
displayPrice: displayPrice, | ||
type: type.convertToPigeon, | ||
subscription: subscription?.convertToPigeon, | ||
priceLocale: priceFormatStyle.locale.convertToPigeon | ||
) | ||
} | ||
} | ||
|
||
extension SK2ProductMessage: Equatable { | ||
static func == (lhs: SK2ProductMessage, rhs: SK2ProductMessage) -> Bool { | ||
return lhs.id == rhs.id && lhs.displayName == rhs.displayName | ||
&& lhs.description == rhs.description && lhs.price == rhs.price | ||
&& lhs.displayPrice == rhs.displayPrice && lhs.type == rhs.type | ||
&& lhs.subscription == rhs.subscription && lhs.priceLocale == rhs.priceLocale | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.ProductType { | ||
var convertToPigeon: SK2ProductTypeMessage { | ||
switch self { | ||
case Product.ProductType.autoRenewable: | ||
return SK2ProductTypeMessage.autoRenewable | ||
case Product.ProductType.consumable: | ||
return SK2ProductTypeMessage.consumable | ||
case Product.ProductType.nonConsumable: | ||
return SK2ProductTypeMessage.nonConsumable | ||
case Product.ProductType.nonRenewable: | ||
return SK2ProductTypeMessage.nonRenewable | ||
default: | ||
fatalError("An unknown ProductType was passed in") | ||
} | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionInfo { | ||
var convertToPigeon: SK2SubscriptionInfoMessage { | ||
return SK2SubscriptionInfoMessage( | ||
promotionalOffers: promotionalOffers.map({ $0.convertToPigeon }), | ||
subscriptionGroupID: subscriptionGroupID, | ||
subscriptionPeriod: subscriptionPeriod.convertToPigeon) | ||
} | ||
} | ||
|
||
extension SK2SubscriptionInfoMessage: Equatable { | ||
static func == (lhs: SK2SubscriptionInfoMessage, rhs: SK2SubscriptionInfoMessage) -> Bool { | ||
return lhs.promotionalOffers == rhs.promotionalOffers | ||
&& lhs.subscriptionGroupID == rhs.subscriptionGroupID | ||
&& lhs.subscriptionPeriod == rhs.subscriptionPeriod | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionOffer { | ||
var convertToPigeon: SK2SubscriptionOfferMessage { | ||
return SK2SubscriptionOfferMessage( | ||
/// ID is always `nil` for introductory offers and never `nil` for other offer types. | ||
id: id, | ||
price: NSDecimalNumber(decimal: price).doubleValue, | ||
type: type.convertToPigeon, | ||
period: period.convertToPigeon, | ||
periodCount: Int64(periodCount), | ||
paymentMode: paymentMode.convertToPigeon | ||
) | ||
} | ||
} | ||
|
||
extension SK2SubscriptionOfferMessage: Equatable { | ||
static func == (lhs: SK2SubscriptionOfferMessage, rhs: SK2SubscriptionOfferMessage) -> Bool { | ||
return lhs.id == rhs.id && lhs.price == rhs.price && lhs.type == rhs.type | ||
&& lhs.period == rhs.period && lhs.periodCount == rhs.periodCount | ||
&& lhs.paymentMode == rhs.paymentMode | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionOffer.OfferType { | ||
var convertToPigeon: SK2SubscriptionOfferTypeMessage { | ||
switch self { | ||
case .introductory: | ||
return SK2SubscriptionOfferTypeMessage.introductory | ||
case .promotional: | ||
return SK2SubscriptionOfferTypeMessage.promotional | ||
default: | ||
fatalError("An unknown OfferType was passed in") | ||
} | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionPeriod { | ||
var convertToPigeon: SK2SubscriptionPeriodMessage { | ||
return SK2SubscriptionPeriodMessage( | ||
value: Int64(value), | ||
unit: unit.convertToPigeon) | ||
} | ||
} | ||
|
||
extension SK2SubscriptionPeriodMessage: Equatable { | ||
static func == (lhs: SK2SubscriptionPeriodMessage, rhs: SK2SubscriptionPeriodMessage) -> Bool { | ||
return lhs.value == rhs.value && lhs.unit == rhs.unit | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionPeriod.Unit { | ||
var convertToPigeon: SK2SubscriptionPeriodUnitMessage { | ||
switch self { | ||
case .day: | ||
return SK2SubscriptionPeriodUnitMessage.day | ||
case .week: | ||
return SK2SubscriptionPeriodUnitMessage.week | ||
case .month: | ||
return SK2SubscriptionPeriodUnitMessage.month | ||
case .year: | ||
return SK2SubscriptionPeriodUnitMessage.year | ||
@unknown default: | ||
fatalError("unknown SubscriptionPeriodUnit encountered") | ||
} | ||
} | ||
} | ||
|
||
@available(iOS 15.0, macOS 12.0, *) | ||
extension Product.SubscriptionOffer.PaymentMode { | ||
var convertToPigeon: SK2SubscriptionOfferPaymentModeMessage { | ||
switch self { | ||
case .freeTrial: | ||
return SK2SubscriptionOfferPaymentModeMessage.freeTrial | ||
case .payUpFront: | ||
return SK2SubscriptionOfferPaymentModeMessage.payUpFront | ||
case .payAsYouGo: | ||
return SK2SubscriptionOfferPaymentModeMessage.payAsYouGo | ||
default: | ||
fatalError("Encountered an unknown PaymentMode") | ||
} | ||
} | ||
} | ||
|
||
extension Locale { | ||
var convertToPigeon: SK2PriceLocaleMessage { | ||
return SK2PriceLocaleMessage( | ||
currencyCode: currencyCode ?? "", | ||
currencySymbol: currencySymbol ?? "" | ||
) | ||
} | ||
} | ||
|
||
extension SK2PriceLocaleMessage: Equatable { | ||
static func == (lhs: SK2PriceLocaleMessage, rhs: SK2PriceLocaleMessage) -> Bool { | ||
return lhs.currencyCode == rhs.currencyCode && lhs.currencySymbol == rhs.currencySymbol | ||
} | ||
} |
Oops, something went wrong.