Xcode 26还没有适配SceneDelegate的app建议尽早适配

Xcode 26之前不需要多窗口的很多app没有适配SceneDelegate,升级到Xcode 26后运行没有问题,但是控制台有以下输出:

swift 复制代码
`UIScene` lifecycle will soon be required. Failure to adopt will result in an assert in the future.

UIApplicationDelegate 中的相关生命周期函数也有弃用标记:

scss 复制代码
/// Tells the delegate that the application has become active 
/// - Note: This method is not called if `UIScene` lifecycle has been adopted. 
- (void)applicationDidBecomeActive:(UIApplication *)application API_DEPRECATED("Use UIScene lifecycle and sceneDidBecomeActive(_:) from UISceneDelegate or the UIApplication.didBecomeActiveNotification instead.", ios(2.0, 26.0), tvos(9.0, 26.0), visionos(1.0, 26.0)) API_UNAVAILABLE(watchos);

建议尽早适配

方案举例

以下是我的适配方案,供大家参考

  • 兼容iOS13以下版本;
  • app只有单窗口场景。

1. 配置Info.plist

Delegate Class Name和Configuration Name 可自定义

2. 配置SceneDelegate

  • 创建SceneDelegate class 类名要和Info.plist中配置一致
  • appDelegate中实现代理
objectivec 复制代码
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options  API_AVAILABLE(ios(13.0)){
   //  name要和Info.plist中配置一致
  return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions  API_AVAILABLE(ios(13.0)){
  // 释放资源,单窗口app不用关注
}

3. 新建单例 AppLifecycleHelper 实现AppDelegate和SceneDelgate共享的方法

  • iOS 13 及以上需要在scene: willConnectToSession: options: 方法中创建Window,之前仍然在 didFinishLaunchingWithOptions:

AppDelegate:

less 复制代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [AppLifecycleHelper sharedInstance].launchOptions = launchOptions;
     // ... 自定义逻辑
    if (@available(iOS 13, *)) {
 
    } else {
        [[AppLifecycleHelper sharedInstance] createKeyWindow];
    }
}

SceneDelgate:

URL冷启动APP时不调用openURLContexts方法,这里保存URL在DidBecomeActive处理

objectivec 复制代码
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions  API_AVAILABLE(ios(13.0)){
    [[AppLifecycleHelper sharedInstance] createKeyWindowWithScene:(UIWindowScene *)scene];
    // 通过url冷启动app,一般只有一个url 
    for (UIOpenURLContext *context **in** connectionOptions.URLContexts) {
        NSURL *URL = context.URL;
        if (URL && URL.absoluteString.length > 0) {
            self.launchUrl = URL;
        }
    }
}

AppLifecycleHelper:

AppLifecycleHelper 复制代码
- (void)createKeyWindow {
    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self setupMainWindow:window];
}

- (void)createKeyWindowWithScene:(UIWindowScene *)scene API_AVAILABLE(ios(13.0)) {
    UIWindow *window = [[UIWindow alloc] initWithWindowScene:scene];
    [self setupMainWindow:window];
}

- (void)setupMainWindow:(UIWindow *)window {
}
  • 实现SceneDelegate后appDelegate 中失效的方法

AppLifecycleHelper中实现,共享给两个DelegateClass

AppDelegate 复制代码
- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[AppLifecycleHelper sharedInstance] appDidBecomeActive];
}

- (void)applicationWillResignActive:(UIApplication *)application {

}

- (void)applicationDidEnterBackground:(UIApplication *)application {

}

- (void)applicationWillEnterForeground:(UIApplication *)application {

}
  
 /// URL Scheme
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, **id**> *)options {

}

/// 接力用户活动
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<**id**<UIUserActivityRestoring>> * _Nullable))restorationHandler {

}

/// 快捷方式点击
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler API_AVAILABLE(ios(9.0)) {
}

SceneDelegate部分代码示例:

SceneDelegate 复制代码
- (void)sceneDidBecomeActive:(UIScene *)scene  API_AVAILABLE(ios(13.0)){
    [[AppLifecycleHelper sharedInstance] appDidBecomeActiveWithLaunchUrl:self.launchUrl];
    // 清空冷启动时的url
    self.launchUrl = nil;
}

这个方法总结下来就是求同存异,由Helper提供SceneDelegate与AppDelegate相同或类似的方法,适合单窗口、且支持iOS 13以下的app;

另外注意URL Scheme冷启动app不会执行openURL需要记录URL,在合适的时机(一般是DidBecomeActive)处理。

相关推荐
初级代码游戏10 小时前
iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
ios·swiftui·swift·弹窗·消息框
zhyongrui12 小时前
托盘删除手势与引导体验修复:滚动冲突、画布消失动画、气泡边框
ios·性能优化·swiftui·swift
Boxsc_midnight16 小时前
【openclaw+imessage】【免费无限流量】集成方案,支持iphone手机+macos
ios·智能手机·iphone
感谢地心引力1 天前
安卓、苹果手机无线投屏到Windows
android·windows·ios·智能手机·安卓·苹果·投屏
2501_915918412 天前
HTTPS 代理失效,启用双向认证(mTLS)的 iOS 应用网络怎么抓包调试
android·网络·ios·小程序·https·uni-app·iphone
Swift社区2 天前
Flutter 路由系统,对比 RN / Web / iOS 有什么本质不同?
前端·flutter·ios
zhyongrui2 天前
SnipTrip 发热优化实战:从 60Hz 到 30Hz 的性能之旅
ios·swiftui·swift
Andy Dennis2 天前
ios开发 xcode配置
ios·cocoa·xcode
JoyCong19982 天前
iOS 27 六大功能前瞻:折叠屏、AI Siri与“雪豹式”流畅体验,搭配ToDesk开启跨设备新协作
人工智能·ios·cocoa
linweidong2 天前
屏幕尺寸的万花筒:如何在 iOS 碎片化生态中以不变应万变?
macos·ios·移动开发·objective-c·cocoa·ios面试·ios面经