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)处理。

相关推荐
游戏开发爱好者82 小时前
苹果 App 上架流程,结合 Xcode、CI 等常见工具
macos·ios·ci/cd·小程序·uni-app·iphone·xcode
前端老白3 小时前
webview在微信小程序中,安卓加载失败,IOS正常加载
android·ios·微信小程序·webview
2501_915106323 小时前
用 HBuilder 上架 iOS 应用时如何管理Bundle ID、证书与描述文件
android·ios·小程序·https·uni-app·iphone·webview
2501_915909063 小时前
资源文件混淆在 iOS 应用安全中的实际价值
android·安全·ios·小程序·uni-app·iphone·webview
2501_915918413 小时前
iOS App 性能测试中常被忽略的运行期问题
android·ios·小程序·https·uni-app·iphone·webview
Name_NaN_None3 小时前
iPhone怎么投屏到电脑上?
ios·电脑·iphone
sweet丶15 小时前
UIWindowScene 使用指南:掌握 iOS 多窗口架构
ios
崽崽长肉肉20 小时前
swift中的知识总结(一)
ios·swift
2501_915106321 天前
HTTP 协议详解,HTTP 协议在真实运行环境中的表现差异
网络·网络协议·http·ios·小程序·uni-app·iphone