You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用showManageSubscriptions(in:)关闭订阅管理页后APP崩溃求助

解决showManageSubscriptions(in:)关闭后APP崩溃的问题

问题根源分析

  1. @objc函数不支持async throws:Objective-C运行时无法正确处理Swift的async throws组合函数,这会导致订阅界面关闭后的回调逻辑出错,引发崩溃。
  2. 重复添加按钮Target:在viewWillAppear中每次页面出现都给按钮绑定点击事件,会导致按钮被绑定多个相同action,触发时可能产生异常。
  3. WindowScene获取不可靠:直接取connectedScenes.first可能拿到非当前活跃的场景,导致界面生命周期管理异常。

修复后的代码

import UIKit
import StoreKit

class ViewController: UIViewController {
    @IBOutlet var managerBtn: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 仅在viewDidLoad中添加一次target,避免重复绑定
        managerBtn.addTarget(self, action: #selector(manageSubscriptionTapped), for: .touchUpInside)
    }

    // @objc函数仅做转发,不使用async throws
    @objc private func manageSubscriptionTapped() {
        Task {
            do {
                // 从当前控制器的view获取对应的WindowScene,更可靠
                guard let windowScene = view.window?.windowScene else {
                    print("无法获取当前WindowScene")
                    return
                }
                try await AppStore.showManageSubscriptions(in: windowScene)
            } catch {
                print("订阅管理界面展示失败: \(error.localizedDescription)")
            }
        }
    }
}

关键修复点说明

  • 拆分async逻辑:将@objc标记的点击事件函数和异步逻辑分离,用Task在主队列执行异步代码,避免Objective-C与Swift异步特性的兼容性问题。
  • 统一Target添加时机:在viewDidLoad中添加按钮点击事件,确保仅绑定一次,避免重复触发。
  • 可靠获取WindowScene:通过当前控制器的view.window?.windowScene获取对应场景,保证操作的是当前活跃的界面场景,避免场景不匹配导致的生命周期异常。

内容的提问来源于stack exchange,提问作者Kevin Alejandro Duron Martínez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:54:34