Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.4.8+2

* Add support for offer codes in StoreKit 2.

## 0.4.8+1

* Fixes StoreKit 2 purchase flow to send cancelled/pending/unverified results to `purchaseStream`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, FIAInAppPurchaseAPI {
SetUpFIAInAppPurchaseAPI(messenger, instance)
if #available(iOS 15.0, macOS 12.0, *) {
InAppPurchase2APISetup.setUp(binaryMessenger: messenger, api: instance)
#if os(iOS)
registrar.addSceneDelegate(instance)
#endif
}
}

Expand Down Expand Up @@ -465,3 +468,7 @@ public class InAppPurchasePlugin: NSObject, FlutterPlugin, FIAInAppPurchaseAPI {
)
}
}

#if os(iOS)
extension InAppPurchasePlugin: FlutterSceneLifeCycleDelegate {}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,51 @@ extension InAppPurchasePlugin: InAppPurchase2API {
}
}

func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void) {
#if os(iOS)
if #available(iOS 16.0, *) {
guard let windowScene = self.registrar?.viewController?.view.window?.windowScene else {
let error = PigeonError(
code: "storekit2_missing_key_window_scene",
message: "Failed to fetch key window scene",
details: "registrar.viewController.view.window.windowScene returned nil."
)
completion(.failure(error))
return
}
Task { @MainActor in
do {
try await AppStore.presentOfferCodeRedeemSheet(in: windowScene)
completion(.success(()))
} catch {
completion(.failure(error))
}
}
}
#elseif os(macOS)
if #available(macOS 15.0, *) {
guard let viewController = self.registrar?.viewController else {
let error = PigeonError(
code: "storekit2_missing_view_controller",
message: "Failed to fetch view controller",
details: "registrar.viewController returned nil."
)
completion(.failure(error))
return
}

Task { @MainActor in
do {
try await AppStore.presentOfferCodeRedeemSheet(from: viewController)
completion(.success(()))
} catch {
completion(.failure(error))
}
}
}
#endif
}
Comment on lines +324 to +367
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

If the #available check fails, the completion handler is never called. This will cause the calling Dart code to hang indefinitely. You should add else blocks to handle cases where the API is not available on the current OS version and call the completion handler with an appropriate error.

  func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void) {
    #if os(iOS)
      if #available(iOS 16.0, *) {
        guard let windowScene = self.registrar?.viewController?.view.window?.windowScene else {
          let error = PigeonError(
            code: "storekit2_missing_key_window_scene",
            message: "Failed to fetch key window scene",
            details: "registrar.viewController.view.window.windowScene returned nil."
          )
          completion(.failure(error))
          return
        }
        Task { @MainActor in
          do {
            try await AppStore.presentOfferCodeRedeemSheet(in: windowScene)
            completion(.success(()))
          } catch {
            completion(.failure(error))
          }
        }
      } else {
        let error = PigeonError(
          code: "unavailable",
          message: "presentOfferCodeRedeemSheet is only available on iOS 16.0 and newer.",
          details: nil)
        completion(.failure(error))
      }
    #elseif os(macOS)
      if #available(macOS 15.0, *) {
        guard let viewController = self.registrar?.viewController else {
          let error = PigeonError(
            code: "storekit2_missing_view_controller",
            message: "Failed to fetch view controller",
            details: "registrar.viewController returned nil."
          )
          completion(.failure(error))
          return
        }

        Task { @MainActor in
          do {
            try await AppStore.presentOfferCodeRedeemSheet(from: viewController)
            completion(.success(()))
          } catch {
            completion(.failure(error))
          }
        }
      } else {
        let error = PigeonError(
          code: "unavailable",
          message: "presentOfferCodeRedeemSheet is only available on macOS 15.0 and newer.",
          details: nil)
        completion(.failure(error))
      }
    #endif
  }

Comment on lines +324 to +367
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The completion handler is not called if the OS version requirements are not met (iOS < 16.0 or macOS < 15.0), or if the platform is neither iOS nor macOS. This will cause the Dart Future to hang indefinitely. An error should be returned in these cases to ensure the caller receives a response.

  func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void) {
    #if os(iOS)
      if #available(iOS 16.0, *) {
        guard let windowScene = self.registrar?.viewController?.view.window?.windowScene else {
          let error = PigeonError(
            code: "storekit2_missing_key_window_scene",
            message: "Failed to fetch key window scene",
            details: "registrar.viewController.view.window.windowScene returned nil."
          )
          completion(.failure(error))
          return
        }
        Task { @MainActor in
          do {
            try await AppStore.presentOfferCodeRedeemSheet(in: windowScene)
            completion(.success(()))
          } catch {
            completion(.failure(error))
          }
        }
      } else {
        completion(.failure(PigeonError(
          code: "storekit2_unsupported_version",
          message: "Offer code redemption via StoreKit 2 requires iOS 16.0 or later.",
          details: nil
        )))
      }
    #elseif os(macOS)
      if #available(macOS 15.0, *) {
        guard let viewController = self.registrar?.viewController else {
          let error = PigeonError(
            code: "storekit2_missing_view_controller",
            message: "Failed to fetch view controller",
            details: "registrar.viewController returned nil."
          )
          completion(.failure(error))
          return
        }

        Task { @MainActor in
          do {
            try await AppStore.presentOfferCodeRedeemSheet(from: viewController)
            completion(.success(()))
          } catch {
            completion(.failure(error))
          }
        }
      } else {
        completion(.failure(PigeonError(
          code: "storekit2_unsupported_version",
          message: "Offer code redemption via StoreKit 2 requires macOS 15.0 or later.",
          details: nil
        )))
      }
    #else
      completion(.failure(PigeonError(
        code: "storekit2_unsupported_platform",
        message: "Offer code redemption via StoreKit 2 is not supported on this platform.",
        details: nil
      )))
    #endif
  }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is fine bc users should not be on storekit 2 below ios 15


/// Wrapper method around StoreKit2's sync() method
/// https://developer.apple.com/documentation/storekit/appstore/sync()
/// When called, a system prompt will ask users to enter their authentication details
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v26.1.5), do not edit directly.
// Autogenerated from Pigeon (v26.1.10), do not edit directly.
// See also: https://pub.dev/packages/pigeon

import Foundation
Expand Down Expand Up @@ -759,6 +759,7 @@ protocol InAppPurchase2API {
func restorePurchases(completion: @escaping (Result<Void, Error>) -> Void)
func countryCode(completion: @escaping (Result<String, Error>) -> Void)
func sync(completion: @escaping (Result<Void, Error>) -> Void)
func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void)
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
Expand Down Expand Up @@ -1008,6 +1009,24 @@ class InAppPurchase2APISetup {
} else {
syncChannel.setMessageHandler(nil)
}
let presentOfferCodeRedeemSheetChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.presentOfferCodeRedeemSheet\(channelSuffix)",
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
presentOfferCodeRedeemSheetChannel.setMessageHandler { _, reply in
api.presentOfferCodeRedeemSheet { result in
switch result {
case .success:
reply(wrapResult(nil))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
presentOfferCodeRedeemSheetChannel.setMessageHandler(nil)
}
}
}
/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
6458340B2CE3497379F6B389 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -85,6 +84,8 @@
F2D527192C50627500C137C7 /* PaymentQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PaymentQueueTests.swift; path = ../../shared/RunnerTests/PaymentQueueTests.swift; sourceTree = "<group>"; };
F2D527292C583C4A00C137C7 /* TranslatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TranslatorTests.swift; path = ../../shared/RunnerTests/TranslatorTests.swift; sourceTree = "<group>"; };
F6E5D5F926131C4800C68BED /* Configuration.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Configuration.storekit; sourceTree = "<group>"; };
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -289,7 +290,7 @@
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -526,6 +527,8 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
Expand All @@ -542,8 +545,9 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample9;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The bundle identifier has been changed to include a '9' at the end. This appears to be a local testing change and should be reverted to maintain the correct identifier for the example app.

				PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.in_app_purchaseExample;

PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
Expand All @@ -553,6 +557,8 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
Expand All @@ -569,8 +575,9 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample9;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
Expand All @@ -586,6 +593,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = RunnerTests/Info.plist;
Expand Down Expand Up @@ -616,6 +624,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = RunnerTests/Info.plist;
Expand Down Expand Up @@ -666,7 +675,7 @@
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<MacroExpansion>
Expand Down Expand Up @@ -73,6 +74,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>

@interface AppDelegate : FlutterAppDelegate
@interface AppDelegate : FlutterAppDelegate <FlutterImplicitEngineDelegate>

@end
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ @implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)didInitializeImplicitFlutterEngine:(NSObject<FlutterImplicitEngineBridge> *)engineBridge {
[GeneratedPluginRegistrant registerWithRegistry:engineBridge.pluginRegistry];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand All @@ -22,6 +24,29 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand All @@ -39,9 +64,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class _MyAppState extends State<_MyApp> {
_buildConnectionCheckTile(),
_buildProductList(),
_buildConsumableBox(),
_buildCodeRedemptionButton(),
_buildRestoreButton(),
],
),
Expand Down Expand Up @@ -429,6 +430,30 @@ class _MyAppState extends State<_MyApp> {
);
}

Widget _buildCodeRedemptionButton() {
if (_loading) {
return Container();
}

return Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
),
onPressed: () =>
_iapStoreKitPlatformAddition.presentCodeRedemptionSheet(),
child: const Text('Show code redemption sheet'),
),
],
),
);
}

Widget _buildRestoreButton() {
if (_loading) {
return Container();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 54;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The objectVersion has been downgraded from 60 to 54. This typically occurs when a project is opened in an older version of Xcode. It should be reverted to 60 to maintain consistency with the repository's development environment.

	objectVersion = 60;

objects = {

/* Begin PBXAggregateTarget section */
Expand Down Expand Up @@ -82,8 +82,8 @@
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
39C4797E13DFF5FCF1A87568 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
46EFB01DD1BBB34F886C33A0 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
Expand Down Expand Up @@ -184,8 +184,6 @@
33CEB47122A05771004F2AC0 /* Flutter */ = {
isa = PBXGroup;
children = (
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */,
784666492D4C4C64000A1A5F /* FlutterFramework */,
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ description: Demonstrates how to use the in_app_purchase_storekit plugin.
publish_to: none

environment:
sdk: ^3.9.0
flutter: ">=3.35.0"
sdk: ^3.10.0
flutter: ">=3.38.0"

dependencies:
flutter:
Expand Down
Loading
Loading