[in_app_purchase_storekit] Replace deprecated offer code API#11223
[in_app_purchase_storekit] Replace deprecated offer code API#11223LouiseHsu wants to merge 17 commits intoflutter:mainfrom
Conversation
|
This pull request is not mergeable in its current state, likely because of a merge conflict. Pre-submit CI jobs were not triggered. Pushing a new commit to this branch that resolves the issue will result in pre-submit jobs being scheduled. |
|
@gemini-code-assist hewwo |
There was a problem hiding this comment.
Code Review
This pull request adds support for offer codes in StoreKit 2 for the in_app_purchase_storekit package. Key changes include the implementation of presentOfferCodeRedeemSheet in the Swift backend, updates to the Dart platform addition to support StoreKit 2, and the addition of a redemption button in the example application. The iOS example was also updated to utilize scene delegates and implicit engine delegation. Review feedback highlights a potential issue where the Dart Future could hang if OS version requirements are not met in the Swift code, the need for a minimum Flutter version constraint in the plugin's pubspec, and the presence of accidental changes to the example app's bundle identifier and Xcode project version.
| 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 | ||
| } |
There was a problem hiding this comment.
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
}There was a problem hiding this comment.
this is fine bc users should not be on storekit 2 below ios 15
| environment: | ||
| sdk: ^3.9.0 |
There was a problem hiding this comment.
The plugin now utilizes new Flutter APIs such as registrar.addSceneDelegate and FlutterSceneLifeCycleDelegate. A minimum Flutter version constraint should be added to the environment section to prevent compilation failures for users on older Flutter SDKs.
environment:
sdk: ^3.9.0
flutter: ">=3.38.0"| "$(PROJECT_DIR)/Flutter", | ||
| ); | ||
| PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample; | ||
| PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.inAppPurchaseExample9; |
There was a problem hiding this comment.
| classes = { | ||
| }; | ||
| objectVersion = 60; | ||
| objectVersion = 54; |
|
Hello! How can I help you with this pull request today? |
Fixes flutter/flutter#162914
Pre-Review Checklist
[shared_preferences]///).