【お知らせ】
SwiftUIで作った macOS Todo アプリ
ToDone
を100ダウンロードまで無料にしました。マニュアルページは、ToDone サポートページ です。
【本文】
AppDelegate を使わずに、最後のウィンドウを閉じたら、アプリケーションも終了する方法を考えてみました。@ObservedObject というバインディング技術を使っています。なぜ AppDelegate を使うのをやめようとしているのかというと、Apple がアプリケーションのライフサイクルを AppDelegate から App へ移行しようとしているからです。
なお、このコーナーでは、任意のテキストエディタでコードを記述し、ターミナルを使ってビルドする方法で作業を進めています。Xcode をお使いの場合は、Xcodeで作業する場合 をご一読ください。
また、ターミナルで作業する場合も、Swift コンパイラや SwiftUI フレームワークなどをMac にインストールするために Xcode をインストールして、一度起動させなければなりません。インストールが終われば Xcodeは終了しても大丈夫です。
なお、作成したアプリケーションを App Storeに提出するためのファイルにするには、
Xcode を使わなければならなかったかもしれません。どこかで Xcode を使わずに作る方法を見たような気もするのですが...
私の開発環境は次のとおりです。
更新履歴
2022/07/12 コード説明をつけました。
任意のテキストエディタで次の二つのファイルを作成します。
ファイル名は自由ですが、 大文字で始めなければなりません。Swift ファイルの拡張子は .swift です。 Xcode で作業をする場合は、(プロダクト名App(プロダクト名App.swift)に次のコードを記述します。
/************************************
App.swift
copyright : vivacocoa.jp
last modified: Jul. 11, 2022
************************************/
import SwiftUI
class Count: ObservableObject {
@Published var count = 0
}
@main
struct FooApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
ファイル名は自由ですが、 大文字で始めなければなりません。Swift ファイルの拡張子は .swift です。 Xcode で作業を進める場合は、ContentView(ContentView.swift)に次のコードを記述します。
/************************************
View.swift
copyright : vivacocoa.jp
last modified: Jul. 11, 2022
************************************/
import SwiftUI
struct ContentView: View {
@ObservedObject var count = Count()
var body: some View {
VStack {
Text("Hello, world!")
.font(.largeTitle)
.fontWeight(.thin)
}
.frame(minWidth: 300, maxWidth:.infinity, minHeight: 200, maxHeight: .infinity)
.onAppear {
count.count += 1
}
.onDisappear{
count.count -= 1
if count.count < 1 {
NSApplication.shared.terminate(self)
}
}
}
}
swiftc App.swift View.swift -o foo
mv foo Foo.app/Contents/MacOS
Xcode で作業を進めている場合は、Product メニューの Run をクリックするか、 Xcode の左上の右三角 ▶︎ をクリックします。
作成した Foo アプリ(アプリケーションバンドル)をダブルクリックします。
Xcode で作業を進めている場合は何もする必要はありません。
しばらく待つとアプリケーションが起動します。
ウィンドウを閉じるとアプリケーションが終了します。 New メニューで、複数のウィンドウを作った場合は、最後のウィンドウを閉じた時だけアプリケーションが終了します。
そもそも、New(新規)メニューを削除したいのですが、AppDelegate を使わずに、メニューを削除する方法はまだ見つけられていません。