148 lines
4.9 KiB
Swift
148 lines
4.9 KiB
Swift
//
|
|
// LifeGameAppApp.swift
|
|
// Shared
|
|
//
|
|
// Created by Yusuke Hosonuma on 2020/07/15.
|
|
//
|
|
|
|
import SwiftUI
|
|
import FirebaseAuth
|
|
import FirebaseCore
|
|
import LifeGame
|
|
import Core
|
|
#if DEBUG && os(iOS)
|
|
import SwiftUISimulator
|
|
#endif
|
|
|
|
@main
|
|
struct Application: App {
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
|
|
#if os(iOS)
|
|
// TODO: とりあえず実験的に`@AppStorage`を使ってみたが、ボードの状態を保存するのは用途として間違っているので、たぶん将来的に削除する。
|
|
@AppStorage(wrappedValue: LifeGameBoard(size: 32), "currentBoard") private var currentBoard: LifeGameBoard
|
|
#endif
|
|
|
|
// Note: ✅
|
|
// SwiftUI 以外の文脈で参照する必要がなければ、`.shared`を用意しなくてもよい。
|
|
|
|
@StateObject var boardManager = BoardManager.shared
|
|
@StateObject var gameManager = GameManager.shared
|
|
@StateObject var settingEnvironment = SettingEnvironment.shared
|
|
@StateObject var networkMonitor = NetworkMonitor()
|
|
@StateObject var authentication = Authentication.shared
|
|
@StateObject var applicationRouter = ApplicationRouter.shared
|
|
#if os(macOS)
|
|
@StateObject var fileManager = LifeGameFileManager()
|
|
#endif
|
|
|
|
init() {
|
|
FirebaseApp.configure()
|
|
|
|
// ref: https://firebase.google.com/docs/auth/ios/single-sign-on?hl=ja
|
|
do {
|
|
try Auth.auth().useUserAccessGroup("P437HSA6PY.shared") // TODO: そのうちチームIDを除外したい
|
|
} catch let error as NSError {
|
|
fatalError("Error changing user access group: \(error.localizedDescription)")
|
|
}
|
|
|
|
#if os(iOS)
|
|
UITextView.appearance().backgroundColor = .clear
|
|
#endif
|
|
}
|
|
|
|
var body: some Scene {
|
|
#if os(macOS)
|
|
|
|
// Note:
|
|
// `WindowGroup`をもう一つ宣言しても無視されてしまいマルチウィンドウのアプリにはならない。(macOS-beta 5❗)
|
|
// 現時点では仕様なのかバグなのか、他にやり方があるのかは不明。
|
|
|
|
WindowGroup {
|
|
content()
|
|
}
|
|
.commands {
|
|
// Note: ✅
|
|
// `Commands`には environmentObject を利用できない仕様っぽい。
|
|
//
|
|
// ```
|
|
// .environmentObject(boardRepository)
|
|
// ```
|
|
LifeGameCommands(boardManager: boardManager,
|
|
gameManager: gameManager,
|
|
fileManager: fileManager)
|
|
}
|
|
|
|
Settings {
|
|
PreferenceView()
|
|
.environmentObject(settingEnvironment)
|
|
}
|
|
#else
|
|
WindowGroup {
|
|
#if DEBUG
|
|
SimulatorView {
|
|
content()
|
|
}
|
|
#else
|
|
content()
|
|
#endif
|
|
}
|
|
.commands {
|
|
// Note:
|
|
// 少なくとも iPad Simulator 上ではショートカットキーを受け付けていないように見える(beta 6)❗
|
|
LifeGameCommands(boardManager: boardManager,
|
|
gameManager: gameManager)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// MARK: Private
|
|
|
|
private func content() -> some View {
|
|
#if os(macOS)
|
|
configure(MacRootView())
|
|
.environmentObject(fileManager)
|
|
#else
|
|
configure(RootView())
|
|
.onAppear {
|
|
boardManager.setLifeGameBoard(board: currentBoard)
|
|
}
|
|
.onChange(of: scenePhase) { phase in
|
|
switch phase {
|
|
case .active:
|
|
AppLogger.appLifecycle.info("Will active...")
|
|
|
|
case .inactive:
|
|
AppLogger.appLifecycle.info("Will inactive...")
|
|
gameManager.stop()
|
|
currentBoard = boardManager.board // タスクスイッチャーから直接killされると`background`を介さないのでここで保存
|
|
|
|
case .background:
|
|
AppLogger.appLifecycle.info("Will background...")
|
|
|
|
@unknown default:
|
|
fatalError()
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private func configure<T: View>(_ view: T) -> some View {
|
|
view
|
|
.environmentObject(boardManager)
|
|
.environmentObject(gameManager)
|
|
.environmentObject(settingEnvironment)
|
|
.environmentObject(authentication)
|
|
.environmentObject(networkMonitor)
|
|
.environmentObject(applicationRouter)
|
|
//
|
|
// Handle launch events from widgets in the current window.
|
|
//
|
|
// 🌱 Special Thanks
|
|
// https://stackoverflow.com/questions/66647052/why-does-url-scheme-onopenurl-in-swiftui-always-open-a-new-window
|
|
//
|
|
.handlesExternalEvents(preferring: ["board"], allowing: ["*"])
|
|
.onOpenURL(perform: applicationRouter.performURL) // 🚀 Ignite
|
|
}
|
|
}
|