Skip to content

[in_app_purchase_storekit] Add show manage subscriptions path - #12454

Open
Hari-07 wants to merge 1 commit into
flutter:mainfrom
Hari-07:storekit2-manage-subscriptions
Open

[in_app_purchase_storekit] Add show manage subscriptions path#12454
Hari-07 wants to merge 1 commit into
flutter:mainfrom
Hari-07:storekit2-manage-subscriptions

Conversation

@Hari-07

@Hari-07 Hari-07 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Adds a new showManageSubscriptions method which wraps around storekit's showManageSubscriptions(in:)

Fixes flutter/flutter#159664

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the showManageSubscriptions method to the InAppPurchaseStoreKitPlatformAddition class, enabling users to manage subscriptions via the App Store sheet on iOS 15+ using StoreKit 2. The changes include the Swift implementation, Pigeon-generated code, an example app button, and corresponding unit tests. Feedback recommends moving UIKit property access inside the @MainActor task block in Swift to ensure thread safety, and catching potential exceptions in the example app's onPressed callback to prevent unhandled asynchronous errors.

Comment on lines +410 to +426
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.showManageSubscriptions(in: windowScene)
completion(.success(()))
} catch {
completion(.failure(error))
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Accessing UIKit properties such as viewController, view, window, and windowScene must be done on the main thread (@MainActor). Currently, the guard statement retrieves the windowScene before entering the @MainActor task block, which can lead to thread-safety issues or crashes if this method is invoked from a background thread. Moving the entire guard statement inside the @MainActor task ensures safe UI-related operations.

Suggested change
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.showManageSubscriptions(in: windowScene)
completion(.success(()))
} catch {
completion(.failure(error))
}
}
Task { @MainActor in
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
}
do {
try await AppStore.showManageSubscriptions(in: windowScene)
completion(.success(()))
} catch {
completion(.failure(error))
}
}

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.

I think this is more correct but I was reflecting the pattern in presentOfferCodeRedeemSheet. Happy to update this one or both

backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
),
onPressed: () => _iapStoreKitPlatformAddition.showManageSubscriptions(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The showManageSubscriptions method returns a Future<void> and can throw an exception (for example, on unsupported platforms like macOS or iOS versions below 15). Since this future is not awaited or caught in the onPressed callback, any thrown error will result in an unhandled asynchronous exception. It is highly recommended to catch the error and display a user-friendly message (e.g., using a SnackBar) to handle these expected platform limitations gracefully.

            onPressed: () async {
              try {
                await _iapStoreKitPlatformAddition.showManageSubscriptions();
              } catch (e) {
                if (mounted) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Error: $e')),
                  );
                }
              }
            },

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.

I think this is ok for the internal example

@Hari-07

Hari-07 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

I wasn't sure if we need to do something in in_app_purchase. From what I can see the code change will get picked up automatically maybe just need to update the readme. And bump dependency to ^0.4.12 so that the readme is correct, if we want to

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[in_app_purchase_storekit] Add AppStore.showManageSubscriptions() for StoreKit2 wrapper

1 participant