Skip to content

Commit ea8232e

Browse files
authored
Merge branch 'main' into docs-cross-file-mimetype
2 parents d7e2aec + ede9842 commit ea8232e

20 files changed

Lines changed: 339 additions & 214 deletions

File tree

packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.4.9
2+
3+
* Add support for offer codes in StoreKit 2.
4+
* Updates minimum supported SDK version to Flutter 3.38.
5+
16
## 0.4.8+1
27

38
* Fixes StoreKit 2 purchase flow to send cancelled/pending/unverified results to `purchaseStream`.

packages/in_app_purchase/in_app_purchase_storekit/darwin/in_app_purchase_storekit/Sources/in_app_purchase_storekit/StoreKit2/InAppPurchasePlugin+StoreKit2.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,67 @@ extension InAppPurchasePlugin: InAppPurchase2API {
321321
}
322322
}
323323

324+
func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void) {
325+
#if os(iOS)
326+
if #available(iOS 16.0, *) {
327+
guard let windowScene = self.registrar?.viewController?.view.window?.windowScene else {
328+
let error = PigeonError(
329+
code: "storekit2_missing_key_window_scene",
330+
message: "Failed to fetch key window scene",
331+
details: "registrar.viewController.view.window.windowScene returned nil."
332+
)
333+
completion(.failure(error))
334+
return
335+
}
336+
Task { @MainActor in
337+
do {
338+
try await AppStore.presentOfferCodeRedeemSheet(in: windowScene)
339+
completion(.success(()))
340+
} catch {
341+
completion(.failure(error))
342+
}
343+
}
344+
} else {
345+
completion(
346+
.failure(
347+
PigeonError(
348+
code: "storekit2_unsupported_platform_version",
349+
message: "Offer code redemption requires iOS 16+",
350+
details: nil
351+
)))
352+
}
353+
#elseif os(macOS)
354+
if #available(macOS 15.0, *) {
355+
guard let viewController = self.registrar?.viewController else {
356+
let error = PigeonError(
357+
code: "storekit2_missing_view_controller",
358+
message: "Failed to fetch view controller",
359+
details: "registrar.viewController returned nil."
360+
)
361+
completion(.failure(error))
362+
return
363+
}
364+
365+
Task { @MainActor in
366+
do {
367+
try await AppStore.presentOfferCodeRedeemSheet(from: viewController)
368+
completion(.success(()))
369+
} catch {
370+
completion(.failure(error))
371+
}
372+
}
373+
} else {
374+
completion(
375+
.failure(
376+
PigeonError(
377+
code: "storekit2_unsupported_platform_version",
378+
message: "Offer code redemption requires macOS 15+",
379+
details: nil
380+
)))
381+
}
382+
#endif
383+
}
384+
324385
/// Wrapper method around StoreKit2's sync() method
325386
/// https://developer.apple.com/documentation/storekit/appstore/sync()
326387
/// When called, a system prompt will ask users to enter their authentication details

packages/in_app_purchase/in_app_purchase_storekit/darwin/in_app_purchase_storekit/Sources/in_app_purchase_storekit/StoreKit2/StoreKit2Messages.g.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v26.1.5), do not edit directly.
4+
// Autogenerated from Pigeon (v26.1.10), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66

77
import Foundation
@@ -759,6 +759,7 @@ protocol InAppPurchase2API {
759759
func restorePurchases(completion: @escaping (Result<Void, Error>) -> Void)
760760
func countryCode(completion: @escaping (Result<String, Error>) -> Void)
761761
func sync(completion: @escaping (Result<Void, Error>) -> Void)
762+
func presentOfferCodeRedeemSheet(completion: @escaping (Result<Void, Error>) -> Void)
762763
}
763764

764765
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@@ -1008,6 +1009,24 @@ class InAppPurchase2APISetup {
10081009
} else {
10091010
syncChannel.setMessageHandler(nil)
10101011
}
1012+
let presentOfferCodeRedeemSheetChannel = FlutterBasicMessageChannel(
1013+
name:
1014+
"dev.flutter.pigeon.in_app_purchase_storekit.InAppPurchase2API.presentOfferCodeRedeemSheet\(channelSuffix)",
1015+
binaryMessenger: binaryMessenger, codec: codec)
1016+
if let api = api {
1017+
presentOfferCodeRedeemSheetChannel.setMessageHandler { _, reply in
1018+
api.presentOfferCodeRedeemSheet { result in
1019+
switch result {
1020+
case .success:
1021+
reply(wrapResult(nil))
1022+
case .failure(let error):
1023+
reply(wrapError(error))
1024+
}
1025+
}
1026+
}
1027+
} else {
1028+
presentOfferCodeRedeemSheetChannel.setMessageHandler(nil)
1029+
}
10111030
}
10121031
}
10131032
/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.

packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
5757
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
5858
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
59-
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
60-
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
59+
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>"; };
6160
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
6261
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
6362
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@@ -85,6 +84,8 @@
8584
F2D527192C50627500C137C7 /* PaymentQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PaymentQueueTests.swift; path = ../../shared/RunnerTests/PaymentQueueTests.swift; sourceTree = "<group>"; };
8685
F2D527292C583C4A00C137C7 /* TranslatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TranslatorTests.swift; path = ../../shared/RunnerTests/TranslatorTests.swift; sourceTree = "<group>"; };
8786
F6E5D5F926131C4800C68BED /* Configuration.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Configuration.storekit; sourceTree = "<group>"; };
87+
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
88+
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
8889
/* End PBXFileReference section */
8990

9091
/* Begin PBXFrameworksBuildPhase section */
@@ -289,7 +290,7 @@
289290
);
290291
mainGroup = 97C146E51CF9000F007C117D;
291292
packageReferences = (
292-
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
293+
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
293294
);
294295
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
295296
projectDirPath = "";
@@ -526,6 +527,8 @@
526527
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
527528
buildSettings = {
528529
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
530+
CODE_SIGN_IDENTITY = "Apple Development";
531+
CODE_SIGN_STYLE = Automatic;
529532
CURRENT_PROJECT_VERSION = 1;
530533
DEVELOPMENT_TEAM = "";
531534
ENABLE_BITCODE = NO;
@@ -544,6 +547,7 @@
544547
);
545548
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample;
546549
PRODUCT_NAME = "$(TARGET_NAME)";
550+
PROVISIONING_PROFILE_SPECIFIER = "";
547551
VERSIONING_SYSTEM = "apple-generic";
548552
};
549553
name = Debug;
@@ -553,6 +557,8 @@
553557
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
554558
buildSettings = {
555559
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
560+
CODE_SIGN_IDENTITY = "Apple Development";
561+
CODE_SIGN_STYLE = Automatic;
556562
CURRENT_PROJECT_VERSION = 1;
557563
DEVELOPMENT_TEAM = "";
558564
ENABLE_BITCODE = NO;
@@ -571,6 +577,7 @@
571577
);
572578
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample;
573579
PRODUCT_NAME = "$(TARGET_NAME)";
580+
PROVISIONING_PROFILE_SPECIFIER = "";
574581
VERSIONING_SYSTEM = "apple-generic";
575582
};
576583
name = Release;
@@ -586,6 +593,7 @@
586593
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
587594
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
588595
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
596+
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
589597
CODE_SIGN_STYLE = Automatic;
590598
DEVELOPMENT_TEAM = "";
591599
INFOPLIST_FILE = RunnerTests/Info.plist;
@@ -616,6 +624,7 @@
616624
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
617625
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
618626
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
627+
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
619628
CODE_SIGN_STYLE = Automatic;
620629
DEVELOPMENT_TEAM = "";
621630
INFOPLIST_FILE = RunnerTests/Info.plist;
@@ -666,7 +675,7 @@
666675
/* End XCConfigurationList section */
667676

668677
/* Begin XCLocalSwiftPackageReference section */
669-
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
678+
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
670679
isa = XCLocalSwiftPackageReference;
671680
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
672681
};

packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
buildConfiguration = "Debug"
4545
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
4646
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
47+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
4748
shouldUseLaunchSchemeArgsEnv = "YES"
4849
codeCoverageEnabled = "YES">
4950
<MacroExpansion>
@@ -73,6 +74,7 @@
7374
buildConfiguration = "Debug"
7475
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
7576
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
77+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
7678
launchStyle = "0"
7779
useCustomWorkingDirectory = "NO"
7880
ignoresPersistentStateOnLaunch = "NO"

packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner/AppDelegate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
#import <Flutter/Flutter.h>
66
#import <UIKit/UIKit.h>
77

8-
@interface AppDelegate : FlutterAppDelegate
8+
@interface AppDelegate : FlutterAppDelegate <FlutterImplicitEngineDelegate>
99

1010
@end

packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner/AppDelegate.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ @implementation AppDelegate
99

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

16+
- (void)didInitializeImplicitFlutterEngine:(NSObject<FlutterImplicitEngineBridge> *)engineBridge {
17+
[GeneratedPluginRegistrant registerWithRegistry:engineBridge.pluginRegistry];
18+
}
19+
1720
@end

packages/in_app_purchase/in_app_purchase_storekit/example/ios/Runner/Info.plist

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>CADisableMinimumFrameDurationOnPhone</key>
6+
<true/>
57
<key>CFBundleDevelopmentRegion</key>
68
<string>en</string>
79
<key>CFBundleExecutable</key>
@@ -22,6 +24,29 @@
2224
<string>1</string>
2325
<key>LSRequiresIPhoneOS</key>
2426
<true/>
27+
<key>UIApplicationSceneManifest</key>
28+
<dict>
29+
<key>UIApplicationSupportsMultipleScenes</key>
30+
<false/>
31+
<key>UISceneConfigurations</key>
32+
<dict>
33+
<key>UIWindowSceneSessionRoleApplication</key>
34+
<array>
35+
<dict>
36+
<key>UISceneClassName</key>
37+
<string>UIWindowScene</string>
38+
<key>UISceneConfigurationName</key>
39+
<string>flutter</string>
40+
<key>UISceneDelegateClassName</key>
41+
<string>FlutterSceneDelegate</string>
42+
<key>UISceneStoryboardFile</key>
43+
<string>Main</string>
44+
</dict>
45+
</array>
46+
</dict>
47+
</dict>
48+
<key>UIApplicationSupportsIndirectInputEvents</key>
49+
<true/>
2550
<key>UILaunchStoryboardName</key>
2651
<string>LaunchScreen</string>
2752
<key>UIMainStoryboardFile</key>
@@ -39,9 +64,5 @@
3964
<string>UIInterfaceOrientationLandscapeLeft</string>
4065
<string>UIInterfaceOrientationLandscapeRight</string>
4166
</array>
42-
<key>CADisableMinimumFrameDurationOnPhone</key>
43-
<true/>
44-
<key>UIApplicationSupportsIndirectInputEvents</key>
45-
<true/>
4667
</dict>
4768
</plist>

packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class _MyAppState extends State<_MyApp> {
148148
_buildConnectionCheckTile(),
149149
_buildProductList(),
150150
_buildConsumableBox(),
151+
_buildCodeRedemptionButton(),
151152
_buildRestoreButton(),
152153
],
153154
),
@@ -429,6 +430,30 @@ class _MyAppState extends State<_MyApp> {
429430
);
430431
}
431432

433+
Widget _buildCodeRedemptionButton() {
434+
if (_loading) {
435+
return Container();
436+
}
437+
438+
return Padding(
439+
padding: const EdgeInsets.all(4.0),
440+
child: Row(
441+
mainAxisAlignment: MainAxisAlignment.end,
442+
children: <Widget>[
443+
TextButton(
444+
style: TextButton.styleFrom(
445+
backgroundColor: Theme.of(context).colorScheme.primary,
446+
foregroundColor: Colors.white,
447+
),
448+
onPressed: () =>
449+
_iapStoreKitPlatformAddition.presentCodeRedemptionSheet(),
450+
child: const Text('Show code redemption sheet'),
451+
),
452+
],
453+
),
454+
);
455+
}
456+
432457
Widget _buildRestoreButton() {
433458
if (_loading) {
434459
return Container();

packages/in_app_purchase/in_app_purchase_storekit/example/macos/Runner.xcodeproj/project.pbxproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@
8282
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
8383
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
8484
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
85-
784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = ephemeral/Packages/.packages/FlutterFramework; sourceTree = "<group>"; };
86-
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = in_app_purchase_storekit; path = ../../../darwin/in_app_purchase_storekit; sourceTree = "<group>"; };
85+
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>"; };
86+
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>"; };
8787
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
8888
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
8989
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
@@ -184,8 +184,6 @@
184184
33CEB47122A05771004F2AC0 /* Flutter */ = {
185185
isa = PBXGroup;
186186
children = (
187-
78DABEA22ED26510000E7860 /* in_app_purchase_storekit */,
188-
784666492D4C4C64000A1A5F /* FlutterFramework */,
189187
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
190188
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
191189
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,

0 commit comments

Comments
 (0)