前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS 新创建项目中的SceneDelegate适配

iOS 新创建项目中的SceneDelegate适配

原创
作者头像
莫空9081
修改2021-04-21 14:30:23
2.6K0
修改2021-04-21 14:30:23
举报
文章被收录于专栏:iOS 备忘录iOS 备忘录

背景

Xcode 11之后新建工程,默认为有SceneDelegate,但是SceneDelegate是从iOS 13之后才有的,如果最低兼容版本到iOS 13以下,需要怎么做呢?

过程

首先来看一下,SceneDelegate是什么,为什么会有SceneDelegate

官方说明:

A UISceneSession object manages a unique runtime instance of your scene. When the user adds a new scene to your app, or when you request one programmatically, the system creates a session object to track that scene. The session contains a unique identifier and the configuration details of the scene. UIKit maintains the session information for the lifetime of the scene itself, destroying the session in response to the user closing the scene in the app switcher. You do not create session objects directly. UIKit creates sessions in response to user interactions with your app. You can also ask UIKit to create a new scene and session programmatically by calling the requestSceneSessionActivation(_:userActivity:options:errorHandler:) method of UIApplication. UIKit initializes the session with default configuration data based on the contents of your app's Info.plist file.

翻译解释:

在iOS 13(及以后版本)上,SceneDelegate将负责AppDelegate的某些功能。 最重要的是,window(窗口)的概念已被scene(场景)的概念所代替。 一个应用程序可以具有不止一个场景,而一个场景现在可以作为您应用程序的用户界面和内容的载体(背景)。

Xcode 11新创建的项目涉及到SceneDelegate的地方如下:

  1. AppDelegate类中两个“scene sessions”方法:application(:configurationForConnecting:options:) 和 application(:didDiscardSceneSessions:)
  2. 一个SceneDelegate类,其中包括生命周期事件,例如active,resign和disconnect。
  3. Info.plist文件中提供了”Application Scene Manifest“配置项,用于配置App的场景,包括它们的场景配置名,delegate类名和storyboard入口

那不需要SceneDelegate,要怎么处理?

两种方法,

a. 一种是直接把SceneDelegate相关的删除

b. 另外一种则是根据系统版本判断兼容

方法一:删除SceneDelegate

  1. 把AppDelegate中UISceneSession Lifecycle的两个代理方法删除,添加window属性,在application:didFinishLaunchingWithOptions:方法中初始化window,设置根视图
  2. 删除SceneDelegate文件
  3. 选中target,切换到info,删除Application Scene Manifest这行
代码语言:txt
复制
/// AppDelegate.Swift

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.backgroundColor = UIColor.white
        
        self.window?.rootViewController = HXBaseViewController()
        self.window?.makeKeyAndVisible()
        
        return true
    }

}
WeCom20210421-115403@2x.png
WeCom20210421-115403@2x.png

方法二:根据系统版本判断兼容,但是这种方法要注意,iOS 13之后有些程序状态的处理要在SeceneDelegate中

  1. 首先在SceneDelegate中加入@available(iOS 13, *)的声明,
  2. 然后把AppDelgate中UISceneSession Lifecycle的两个代理方法写到单独的Extension中,然后声明@avaiable(iOS 13, *),
  3. AppDelegate的启动方法中也需要修改,编译即可
代码语言:txt
复制
// SceneDelegate.swift
import UIKit

@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    xxx
}
代码语言:txt
复制
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        if #available(iOS 13.0, *) {
            // 不需要处理,走SceneDelegate
        }
        else {
            // 初始化UIWindow
            window = UIWindow.init()
            window?.frame = UIScreen.main.bounds
            window?.makeKeyAndVisible()
            window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
        }
        return true
    }
}



@available(iOS 13, *)
extension AppDelegate {
    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}

参考

iOS13 Scene Delegate详解

iOS 13 SceneDelegate适配

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 过程
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档