最小限のSwiftプログラムを作ってみる

通常、macOSのプログラムを開発するには、Xcodeを使う。プロジェクトを新規作成すると、テンプレートによってアプリケーションの雛型が作成される。
が、このような雛型は、その中で何をしているのかよくわからないという欠点がある。そこで、最小限のSwiftプログラムを書いてみる。

以下を参考にした。
https://gist.github.com/habemus-papadum/11f069b6d074f4bca794bf9399432533

# 1. Swiftインタープリタ

まず、以下のファイルを作成する。

```take1.swift
print("Hello, world!")
```

これも有効なSwiftプログラムである。コマンドラインから実行してみる。

```
% swift take1.swift 
Hello, world!
```

次に、ウィンドウを表示してみる。

```take2.swift
import Cocoa
let window = NSWindow(contentRect: NSMakeRect(0, 0, 320, 200), styleMask: .titled, backing: .buffered, defer: true)
window.orderFrontRegardless()
NSApp.run()
```

左下に黒いウィンドウが表示されたはずである。これが最小限のウィンドウを表示するプログラムではないか。

次に、もう少しCocoaアプリっぽいプログラムにしてみる。

```take3.swift
import Cocoa
let _ = NSApplication.shared
class AppDel: NSObject, NSApplicationDelegate {
    var mainWindow: NSWindow?
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let window = NSWindow(contentRect: NSMakeRect(800, 600, 320, 200), styleMask: [.titled, .closable], backing: .buffered, defer: true)
        window.orderFrontRegardless()
        self.mainWindow = window
        NSApp.activate(ignoringOtherApps: true)
    }
    func applicationShouldTerminateAfterLastWindowClosed(_ app: NSApplication) -> Bool {
        return true
    }
}
NSApp.setActivationPolicy(.regular)
let del = AppDel()
NSApp.delegate = del
NSApp.run()
```

実行してみる。

```
% swift take3.swift
take3.swift:2:15: warning: expression of type 'NSApplication' is unused
NSApplication.shared
~~~~~~~~~~~~~~^~~~~~
```

さきほどと同様に、黒いウィンドウが表示される。
~~ただ、warningが出る。どうすればいいだろう。~~コメントでご指摘をいただき、warningは消すことができました。ありがとうございます。

# 2. Swiftコンパイラ
これを、コンパイラで実行ファイルを作り、実行してみよう。

```
% swiftc --version
Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
Target: x86_64-apple-darwin19.6.0
% swiftc take1.swift
% ./take1
Hello, world!
```

このように実行できる。

```
% swiftc take2.swift
% ./take2
```

うお、ターミナルが終了してしまった。take2は実行されている。アクティビティモニタからtake2を探して、強制終了するしかない。

```
% swiftc take3.swift
take3.swift:2:15: warning: expression of type 'NSApplication' is unused
NSApplication.shared
~~~~~~~~~~~~~~^~~~~~
% ./take3
```

こちらは普通に実行され、Ctrl-cで終了できる。

# 3. Swiftパッケージ

これまでは、1つのファイルにプログラム全てが書かれている形式だった。だが、通常のアプリケーションは、複数のファイルからなる。それは、Swiftパッケージと呼ばれる標準的な形式がある。
`swift package init --type executable`によって、ディレクトリが生成される。

```
% cd ~/dev
% mkdir HelloWorld
% cd HelloWorld
% swift package init --type executable
Creating executable package: HelloWorld
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/HelloWorld/main.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/HelloWorldTests/
Creating Tests/HelloWorldTests/HelloWorldTests.swift
Creating Tests/HelloWorldTests/XCTestManifests.swift
```

このように、現在いるディレクトリの名前を認識し、それを元にパッケージの名前を決定する。良いような気もするが、conventionで規定されるのはわかりにくい気もする。

```Sources/HelloWorld/main.swift
print("Hello, world!")
```

と、最初からHello, world!と出力する内容がかかれている。

```
% swift build
[3/3] Linking HelloWorld
% swift run
Hello, world!
```

このように、コンパイルされ、実行される。

さきほどと同様に、`Sources/HelloWorld/main.swift`の内容を、take2.swiftと同じようにしてみよう。

```
% swift run
[3/3] Linking HelloWorld
^C
```

こちらは普通のCtrl-cで終了できた。
`Sources/HelloWorld/main.swift`の内容を、take3.swiftと同じようにしてみよう。

```
% swift run
[3/3] Linking HelloWorld
^C
```

さきほどと同様にウィンドウが出て、ウィンドウを閉じると、アプリケーションも終了した。

done!