@@ -3,6 +3,7 @@ import Flutter
33import NaturalLanguage
44import PostHog
55import Speech
6+ import StoreKit
67import UIKit
78import UserNotifications
89
@@ -1194,6 +1195,18 @@ private final class IOSAudioDecodeHandler: NSObject {
11941195 }
11951196 }
11961197
1198+ let subscriptionManagementChannel = FlutterMethodChannel (
1199+ name: " top.echo-loop/subscription_management " ,
1200+ binaryMessenger: controller. binaryMessenger
1201+ )
1202+ subscriptionManagementChannel. setMethodCallHandler { [ weak self] ( call, result) in
1203+ if call. method == " openManageSubscriptions " {
1204+ self ? . openManageSubscriptions ( result: result)
1205+ } else {
1206+ result ( FlutterMethodNotImplemented)
1207+ }
1208+ }
1209+
11971210 speechPracticeHandler = IOSSpeechPracticeHandler ( binaryMessenger: controller. binaryMessenger)
11981211 textEmbeddingHandler = IOSTextEmbeddingHandler ( binaryMessenger: controller. binaryMessenger)
11991212 audioDecodeHandler = IOSAudioDecodeHandler ( binaryMessenger: controller. binaryMessenger)
@@ -1202,6 +1215,47 @@ private final class IOSAudioDecodeHandler: NSObject {
12021215 return super. application ( application, didFinishLaunchingWithOptions: launchOptions)
12031216 }
12041217
1218+ /// 打开 iOS 系统订阅管理页。
1219+ ///
1220+ /// 使用 StoreKit 原生入口而不是浏览器 URL;Dart 侧会在本方法不可用或失败时回退
1221+ /// App Store 订阅管理链接,兼容旧系统与异常场景。
1222+ private func openManageSubscriptions( result: @escaping FlutterResult ) {
1223+ guard #available( iOS 15 . 0 , * ) else {
1224+ result ( FlutterError (
1225+ code: " unsupported " ,
1226+ message: " StoreKit subscription management requires iOS 15 or later " ,
1227+ details: nil
1228+ ) )
1229+ return
1230+ }
1231+
1232+ let foregroundScene = UIApplication . shared. connectedScenes
1233+ . compactMap { $0 as? UIWindowScene }
1234+ . first { $0. activationState == . foregroundActive }
1235+
1236+ guard let scene = foregroundScene else {
1237+ result ( FlutterError (
1238+ code: " no_scene " ,
1239+ message: " No foreground UIWindowScene for subscription management " ,
1240+ details: nil
1241+ ) )
1242+ return
1243+ }
1244+
1245+ Task { @MainActor in
1246+ do {
1247+ try await AppStore . showManageSubscriptions ( in: scene)
1248+ result ( true )
1249+ } catch {
1250+ result ( FlutterError (
1251+ code: " open_failed " ,
1252+ message: error. localizedDescription,
1253+ details: nil
1254+ ) )
1255+ }
1256+ }
1257+ }
1258+
12051259 /// 从 Info.plist 读取 API Key/Host,构造完整 PostHog 配置(含 Session Replay)并启动 SDK。
12061260 ///
12071261 /// 与 posthog_flutter 插件 initPlugin 的差异:插件版本不支持 sessionReplay 配置项,
0 commit comments