解放区在住氷翠 緑の閃光

AppDelegateを共有しよう【Swift】

2018-05-28 07:57

このページの環境は
Swift4をベースにしています。
また、開発環境はXcode9
MacosはHighSierra 10.13となります。

氷翠です。やっほー

今回はViewController.swiftからAppDelegate.swiftを呼び出します。
それが何故、AppDelegateを共有することになるのか?というのは後ほど。

今回のアプリは「他のファイルを作って、クラスを実装してみよう。【Swift】」で作成したアプリケーションを元にします。
なので、途中までは上記のページをご覧ください。

デザインはこれで。
まぁ動きとしては上記のアプリケーションと同じものですからw


import Cocoa
class ViewController: NSViewController {
    @IBOutlet weak var textLabel: NSTextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }
    @IBAction func 足す(_ sender: NSButton) {
    }
    @IBAction func 引く(_ sender: NSButton) {
    }
}

下準備としても、ViewController.swiftの中身もこんな感じで。
ただ、今回は別のファイルとして、AppDelegate.swiftを使用します。
つまり、前のように、特に別のファイルを用意しなくてもいいということになりますが、そこはスルーの方向でw

AppDelegate.swiftの中身です。


import Cocoa
@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
    }
    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
}

はい、もうすでによくわかりません。

とはいえ、このファイルはViewController.swiftよりも先に読み込まれ実行されます。
で、今回はこのファイルがメインになります。
では早速1行追加します。

このクラスの中で自由に使える変数を一つ作成します。
「func applicationDidFinishLaunching」の前にでも置いてください。


var viewController: ViewController!

この1行が今回の鍵になります。
ということで、この変数の中には「ViewController.swift」の内容が入っていると思ってください。
これがあると、この「AppDelegate.swift」から「ViewController.swift」で定義されているグローバルな変数とか関数にアクセスすることができるのです。

つまり、このファイルはいろんなファイルと、「ViewController.swift」との橋渡しの役目をもっているわけです。
しかもそれがこのたった1行で可能になるのだから便利w

もちろん、他のファイルでも、この「AppDelegate.swift」を使うための準備は必要ですが。


func getAnswer(orig: Int, add: Int) {
    var answer: Int = 0
    answer = orig + add
    viewController.textLabel.stringValue = String(answer)
}

「AppDelegate.swift」に前回のアプリケーションで作成した関数をコピーしてきました。
が、今回は少しいじってあります。
まず、返り値がないということ。「-> Int」がなくなっていることに気づいてください。
何故ないのか?

簡単です。
ここで出力しているからです。

中の3行目を見てみると、「return」の代わりに別のプログラムがあります。
先程も書きましたが、「viewController」という変数の中には「ViewController.swift」の中身があるんです。
で、グローバルに定義されたものは扱うことができると。。。
つまり、そこで定義されたラベルの変数がここで扱うことができるわけです。

では、次に「ViewController.swift」を開きましょう。

まず注目するのはここ。


var appDelegate:AppDelegate = NSApplication.shared.delegate as! AppDelegate

これをグローバルな場所に置いておきます。
「appDelegate」という変数は共有されてますよって宣言なんです。

次にこれ。


override func viewDidLoad() {
    super.viewDidLoad()
    // 初期値を設定 ここでは「0」を用意
    textLabel.stringValue = String(0)
}

これは前回と同じものです。

これを以下のように改良します。


override func viewDidLoad() {
    super.viewDidLoad()
    // 初期値を設定 ここでは「0」を用意
    textLabel.stringValue = String(0)
    appDelegate.viewController = self
}

まぁ、最後の1行を加えただけですが。

では各ボタンの設定です。
前回と同じように「足す」も「引く」も同じプログラムなので、一つだけ。


@IBAction func 足す(_ sender: NSButton) {
    let orig: Int = Int(textLabel.stringValue)!
    appDelegate.getAnswer(orig: orig, add: 1)
}

前回より1行減ってますw

最初の行で元の数字を取得しています。
次の行で「AppDelegate.swift」の中で定義した「getAnswer」の関数を呼び出しているのです。

これで共有が完了。
プログラムを見ていくと、どっちからでもお互いを呼び出すことができるようになっています。
他のファイルを使う場合でも、他のビューを使う場合でもこのAppdelegareを共有してあげると、データの共有もできるようになるわけです。