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

MacCatalyst中NSUserActivity状态恢复异常,session.stateRestorationActivity始终为nil

Mac Catalyst应用重启后窗口状态恢复:session.stateRestorationActivity始终为nil的解决办法

针对你遇到的session.stateRestorationActivity始终为nil的问题,可以从以下几个方面排查和修复:

1. 完善Info.plist的场景状态恢复配置

确保UIApplicationSceneManifest下的场景配置正确启用了状态恢复:

  • 确认UIApplicationSupportsMultipleScenes设置为YES
  • 每个UISceneConfiguration条目下添加UISceneStateRestoration字典:
    • 添加UISceneRestorationEnabled并设置为YES
    • 添加UISceneRestorationClass,值为你的SceneDelegate类名(比如YourApp.SceneDelegate)

2. 确保NSUserActivity被正确填充并关联到场景

当前stateRestorationActivity(for:)直接返回scene.userActivity,但如果这个userActivity本身是nil,系统就无法保存恢复状态。需要在用户操作改变内容时主动更新场景的userActivity:

// 在内容变化时调用,比如ContentViewController中
func saveCurrentState() {
    let activityType = "com.yourapp.detail" // 替换为你注册的活动类型
    let userActivity = NSUserActivity(activityType: activityType)
    // 存入需要恢复的数据,比如当前选中的内容ID
    userActivity.userInfo = ["selectedContentID": "123"]
    // 将活动关联到当前窗口场景
    view.window?.windowScene?.userActivity = userActivity
    // 标记活动为当前需要保存的状态
    userActivity.becomeCurrent()
}

3. 调整场景配置逻辑

在application(_:configurationForConnecting:options:)中,不要仅依赖options.userActivities.first来选择场景配置。状态恢复的场景会话可能不会携带这个参数,建议补充对connectingSceneSession.stateRestorationActivity的判断:

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    var configurationName = "Default Configuration"
    
    // 同时检查session的恢复活动和options中的活动
    let targetActivity = options.userActivities.first ?? connectingSceneSession.stateRestorationActivity
    if let activityType = targetActivity?.activityType {
        switch activityType {
        case .UserActivity.SystemActivityType, .UserActivity.TagActivityType, .UserActivity.ProjectActivityType:
            configurationName = "Detail Configuration"
        default:
            break
        }
    }
    
    return UISceneConfiguration(name: configurationName, sessionRole: connectingSceneSession.role)
}

4. 给需要恢复的视图控制器设置恢复标识

系统需要通过restorationIdentifier来重建视图控制器层级,给你的ContentViewController及其他需要恢复的控制器添加标识:

class ContentViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        restorationIdentifier = "ContentViewController"
        // 如果导航控制器也需要恢复,同样设置其restorationIdentifier
        navigationController?.restorationIdentifier = "MainNavigationController"
    }
}

5. 调试状态保存流程

在stateRestorationActivity(for:)中添加日志,确认系统是否调用了这个方法:

func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
    print("State restoration activity requested: \(scene.userActivity)")
    return scene.userActivity
}

如果该方法未被调用,说明系统未触发状态保存,可能是应用未进入正确的生命周期阶段(比如需要正常退出应用,而非强制杀死),或者场景配置存在问题。

内容的提问来源于stack exchange,提问作者Nikodem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:15:37