👋
UIApplicationDelegate内の一部のメソッドが動作しない
こうなればいいなと思った実装
import SwiftUI
import UIKit
@main
struct demoApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
+ func applicationWillEnterForeground(_ application: UIApplication) {
+ // バックグラウンドからフォアグラウンドに復帰したとき
+ }
+ func applicationDidEnterBackground(_ application: UIApplication) {
+ // フォアグラウンドからバックグラウンドに移行するとき
+ }
}
でも、UIApplicationDelegateのライフサイクルメソッドが動作しない
一旦、設定内容を確認しよう。もし、SceneDelegate関連の記述が使われている場合は、排除する。
AppDelegateからScene関連の記述を排除
import UIKit
@main
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
-
- // 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.
- }
-
-
}
AppDelegateにwindowプロパティを追加
SceneDelegate
に置かれていた UIWindow型のプロパティであるwindow
プロパティはAppDelegate
に移してみる。
import UIKit
@main
class AppDelegate: NSObject, UIApplicationDelegate {
+ var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
func applicationWillEnterForeground(_ application: UIApplication) {
// バックグラウンドからフォアグラウンドに復帰したとき
}
func applicationDidEnterBackground(_ application: UIApplication) {
// フォアグラウンドからバックグラウンドに移行するとき
}
}
Info.plist から UIApplicationSceneManifest をすべて消す
(省略)
:
- <key>UIApplicationSceneManifest</key>
- <dict>
- <key>UIApplicationSupportsMultipleScenes</key>
- <false/>
- <key>UISceneConfigurations</key>
- <dict>
- <key>UIWindowSceneSessionRoleApplication</key>
- <array>
- <dict>
- <key>UISceneConfigurationName</key>
- <string>Default Configuration</string>
- <key>UISceneDelegateClassName</key>
- <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
- <key>UISceneStoryboardFile</key>
- <string>Main</string>
- </dict>
- </array>
- </dict>
- </dict>
:
(省略)
んーーこれでもダメ
UIApplicationDelegateAdaptor設定しても、AppDelegate のすべてのメソッドが呼ばれるわけではないらしい。公式にも書いてありました。
代わりにNotificationCenterを使う。
import SwiftUI
import UIKit
@main
struct demoApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
+ .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
+ // フォアグラウンドからバックグラウンドに移行するとき
+ }
+ .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
+ // バックグラウンドからフォアグラウンドに復帰したとき
+ }
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
}
SceneDelegateを使用している場合
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func sceneWillEnterForeground(_ scene: UIScene) {
// バックグラウンドからフォアグラウンドに入る直前に行う処理
}
func sceneDidEnterBackground(_ scene: UIScene) {
// アプリがバックグラウンドに入るときに行う処理
}
}
Discussion
ScenePhaseでのactiveもある。