Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added 10 million doc comments 😭
  • Loading branch information
LouiseHsu committed Aug 27, 2024
commit 37a57c123aff4ce39c2d3a951f3aac2236aa2a80
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ extension InAppPurchasePlugin: InAppPurchase2API {
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

products.map { $0.convertToPigeon() }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

completion(.success(productMessages))
} catch {
throw PigeonError(
code: "storekit2_products_error",
message: error.localizedDescription,
details: error.localizedDescription
)
completion(
.failure(
PigeonError(
code: "storekit2_products_error",
message: error.localizedDescription,
details: error.localizedDescription)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@
"_storefront" : "USA",
"_storeKitErrors" : [
{
"current" : null,
"current" : {
"index" : 2,
"type" : "generic"
},
"enabled" : false,
"name" : "Load Products"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,34 @@ final class InAppPurchase2PluginTests: XCTestCase {
case .success(let productMessages):
fetchedProductMsg = productMessages
expectation.fulfill()
case .failure(let error):
// Handle the error
print("Failed to fetch products: \(error.localizedDescription)")
case .failure(_):
XCTFail("Products should be successfully fetched")
}
}
await fulfillment(of: [expectation], timeout: 5)

XCTAssert(fetchedProductMsg?.count == 0)
}

@available(iOS 17.0, *)
func testGetProductsWithStoreKitError() async throws {
try await session.setSimulatedError(
.generic(.networkError(URLError(.badURL))), forAPI: .loadProducts)

let expectation = self.expectation(description: "products request should fail")

plugin.products(identifiers: ["subscription_silver"]) { result in
switch result {
case .success(_):
XCTFail("This `products` call should not succeed")
case .failure(let error):
expectation.fulfill()
XCTAssert(error.localizedDescription.contains("This operation couldn't be completed."))
}
}
await fulfillment(of: [expectation], timeout: 5)

// Reset test session
try await session.setSimulatedError(nil, forAPI: .loadProducts)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const String kPurchaseErrorCode = 'purchase_error';
/// Indicates store front is Apple AppStore.
const String kIAPSource = 'app_store';

const bool useStoreKit2 = true;
/// Experimental flag for StoreKit2.
bool _useStoreKit2 = true;

/// An [InAppPurchasePlatform] that wraps StoreKit.
///
Expand Down Expand Up @@ -69,7 +70,7 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {

@override
Future<bool> isAvailable() {
if (useStoreKit2) {
if (_useStoreKit2) {
return AppStore().canMakePayments();
}
return SKPaymentQueueWrapper.canMakePayments();
Expand Down Expand Up @@ -127,7 +128,7 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {
@override
Future<ProductDetailsResponse> queryProductDetails(
Set<String> identifiers) async {
if (useStoreKit2) {
if (_useStoreKit2) {
List<SK2Product> products = <SK2Product>[];
Set<String> invalidProductIdentifiers;
PlatformException? exception;
Expand Down Expand Up @@ -206,6 +207,11 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {
/// Use countryCode instead.
@Deprecated('Use countryCode')
Future<String?> getCountryCode() => countryCode();

/// Turns on StoreKit2. You cannot disable this after it is enabled.
void enableStoreKit2() {
_useStoreKit2 = true;
}
}

enum _TransactionRestoreState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import '../../store_kit_2_wrappers.dart';
InAppPurchase2API _hostApi = InAppPurchase2API();

/// Wrapper for StoreKit2's AppStore
/// (https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments)
/// (https://developer.apple.com/documentation/storekit/appstore)
final class AppStore {
/// Dart wrapper for StoreKit2's canMakePayments()
/// Returns a bool that indicates whether the person can make purchases.
/// (https://developer.apple.com/documentation/storekit/appstore/3822277-canmakepayments)
Future<bool> canMakePayments() {
return _hostApi.canMakePayments();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
// found in the LICENSE file.

import 'package:flutter/services.dart';
import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart';
import '../../store_kit_2_wrappers.dart';

InAppPurchase2API _hostApi = InAppPurchase2API();

/// A wrapper around StoreKit2's ProductType
/// https://developer.apple.com/documentation/storekit/product/producttype
/// The types of in-app purchases.
enum SK2ProductType {
Expand Down Expand Up @@ -55,7 +55,16 @@ extension on SK2ProductType {
}
}

enum SK2SubscriptionOfferType { introductory, promotional }
/// A wrapper around StoreKit2's SubscriptionOfferType
/// https://developer.apple.com/documentation/appstoreserverapi/offertype/
/// The subscription offer types.
enum SK2SubscriptionOfferType {
/// An introductory offer.
introductory,

/// A A promotional offer.
promotional
}

extension on SK2SubscriptionOfferTypeMessage {
SK2SubscriptionOfferType convertFromPigeon() {
Expand All @@ -68,20 +77,36 @@ extension on SK2SubscriptionOfferTypeMessage {
}
}

/// A wrapper around StoreKit2's SubscriptionOffer
/// https://developer.apple.com/documentation/storekit/product/subscriptionoffer
/// Information about a subscription offer on a product.
class SK2SubscriptionOffer {
const SK2SubscriptionOffer({
/// Creates a new [SK2SubscriptionOffer]
SK2SubscriptionOffer({
this.id,
required this.price,
required this.type,
required this.period,
required this.periodCount,
required this.paymentMode,
});

/// The subscription offer identifier.
final String? id;

/// The decimal representation of the discounted price of the subscription offer.
final double price;

/// The type of subscription offer, either introductory or promotional.
final SK2SubscriptionOfferType type;

/// The subscription period for the subscription offer.
final SK2SubscriptionPeriod period;

/// The number of periods that the subscription offer renews for.
final int periodCount;

/// The payment modes for subscription offers that apply to a transaction.
final SK2SubscriptionOfferPaymentMode paymentMode;
}

Expand All @@ -97,10 +122,12 @@ extension on SK2SubscriptionOfferMessage {
}
}

/// A wrapper around StoreKit2's SubscriptionInfo
/// https://developer.apple.com/documentation/storekit/product/subscriptioninfo
/// Information about an auto-renewable subscription, such as its status, period, subscription group, and subscription offer details.
/// Information about an auto-renewable subscription,
/// such as its status, period, subscription group, and subscription offer details.
class SK2SubscriptionInfo {
/// Constructor
/// Creates a new instance of [SK2SubscriptionInfo]
const SK2SubscriptionInfo({
required this.subscriptionGroupID,
required this.promotionalOffers,
Expand All @@ -122,7 +149,8 @@ extension on SK2SubscriptionInfoMessage {
return SK2SubscriptionInfo(
subscriptionGroupID: subscriptionGroupID,
// Note that promotionalOffers should NOT be nullable, but is only declared
// so because of pigeon weirdness. There should be NO NULLS.
// so because of pigeon cannot handle non null lists.
// There should be NO NULLS.
promotionalOffers: promotionalOffers
.whereType<SK2SubscriptionOfferMessage>()
.map((SK2SubscriptionOfferMessage offer) =>
Expand All @@ -132,9 +160,11 @@ extension on SK2SubscriptionInfoMessage {
}
}

/// https://developer.apple.com/documentation/storekit/product/subscriptionperiod?changes=latest_minor
/// A wrapper around StoreKit2's SubscriptionPeriod
/// https://developer.apple.com/documentation/storekit/product/subscriptionperiod
/// Values that represent the duration of time between subscription renewals.
class SK2SubscriptionPeriod {
/// Creates a new instance of [SK2SubscriptionPeriod]
const SK2SubscriptionPeriod({required this.value, required this.unit});

/// The number of units that the period represents.
Expand All @@ -150,6 +180,7 @@ extension on SK2SubscriptionPeriodMessage {
}
}

/// A wrapper around StoreKit2's SubscriptionPeriodUnit
/// https://developer.apple.com/documentation/storekit/product/subscriptionperiod/3749576-unit
/// The increment of time for the subscription period.
enum SK2SubscriptionPeriodUnit {
Expand Down Expand Up @@ -181,7 +212,7 @@ extension on SK2SubscriptionPeriodUnitMessage {
}
}

/// https://developer.apple.com/documentation/storekit/product/subscriptionoffer/paymentmode
/// A wrapper around StoreKit2's [PaymentMode](https://developer.apple.com/documentation/storekit/product/subscriptionoffer/paymentmode)
/// The payment modes for subscription offers that apply to a transaction.
enum SK2SubscriptionOfferPaymentMode {
/// A payment mode of a product discount that applies over a single billing period or multiple billing periods.
Expand All @@ -207,11 +238,19 @@ extension on SK2SubscriptionOfferPaymentModeMessage {
}
}

/// A wrapper around StoreKit2's [Locale](https://developer.apple.com/documentation/foundation/locale)
/// The payment modes for subscription offers that apply to a transaction.
class SK2PriceLocale {
/// Creates a new instance of [SK2PriceLocale]
SK2PriceLocale({required this.currencyCode, required this.currencySymbol});

/// The currency code this format style uses.
final String currencyCode;

/// The currency symbol this format style uses.
final String currencySymbol;

/// Convert this instance of [SK2PriceLocale] to [SK2PriceLocaleMessage]
SK2PriceLocaleMessage convertToPigeon() {
return SK2PriceLocaleMessage(
currencyCode: currencyCode, currencySymbol: currencySymbol);
Expand All @@ -225,8 +264,7 @@ extension on SK2PriceLocaleMessage {
}
}

/// Dart wrapper around StoreKit2's [Product](https://developer.apple.com/documentation/storekit/product).
///
/// A wrapper around StoreKit2's [Product](https://developer.apple.com/documentation/storekit/product).
/// The Product type represents the in-app purchases that you configure in
/// App Store Connect and make available for purchase within your app.
class SK2Product {
Expand Down Expand Up @@ -286,6 +324,7 @@ class SK2Product {
.toList();
}

/// Converts this instance of [SK2Product] to it's pigeon representation [SK2ProductMessage]
SK2ProductMessage convertToPigeon() {
return SK2ProductMessage(
id: id,
Expand All @@ -298,7 +337,6 @@ class SK2Product {
}
}

// let me test what i wanted you to type
extension on SK2ProductMessage {
SK2Product convertFromPigeon() {
return SK2Product(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,9 @@ class FakeStoreKit2Platform implements TestInAppPurchase2Api {
for (final String validID in validProductIDs) {
final SK2Product product = SK2Product(
id: validID,
displayName: "test_product",
displayPrice: "0.99",
description: "description",
displayName: 'test_product',
displayPrice: '0.99',
description: 'description',
price: 0.99,
type: SK2ProductType.consumable,
priceLocale:
Expand All @@ -318,7 +318,7 @@ class FakeStoreKit2Platform implements TestInAppPurchase2Api {
}
}
final List<SK2ProductMessage?> result = <SK2ProductMessage?>[];
for (SK2Product p in products) {
for (final SK2Product p in products) {
result.add(p.convertToPigeon());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void main() {
late InAppPurchaseStoreKitPlatform iapStoreKitPlatform;

setUpAll(() {
TestInAppPurchase2Api.setup(fakeStoreKit2Platform);
TestInAppPurchase2Api.setUp(fakeStoreKit2Platform);
});

setUp(() {
Expand Down