読者です 読者をやめる 読者になる 読者になる

Apple Engine

Apple, iPhone, iOS, その周辺のことについて

iOS と App Extension、そこにつながるデバイス

iOS のアプリは、
基本的には異なるアプリとの同士では会話ができない隔離されたシステムで運用されている。

macOS では LION ぐらいの頃 XPC Service というものが出て、アプリ間での通信ができたわけだが、
iOS の XPC はプライベートフレームワークとなっており、
ストアに申請する事はできず使用できなかった。

 

そこで、歳月が経ち出現したのは App Extension。
文字どうりアプリの拡張機能である。

拡張機能は、アプリ本体とは別のプログラムファイルで、
開発したアプリと他のアプリをつなげるものだったり、
カスタムキーボードなどシステムに紐付いているものがある。

(ステッカーパック、いわゆるスタンプは Message アプリに紐付いており、本体アプリは必要ない。ずるい)

 

別のプログラムファイルという事でわかるかもしれないが、 本体のアプリとは別の環境で動き、実は互いには直接アクセスはできなく、OS が間に入る。

そして、OS はアプリと拡張機能のアプリが同じグループ内いる場合、他のアプリが入れない部屋をつくり、そこを通じてデータを操作できるようにする。

このことによって、アプリは拡張機能を通じて安全なデータの受け渡しができたりしている。

 

一応、2017年4月の時点で作ることのできる拡張機能
(時間があったら下の詳細を書くかも?)

f:id:x67x6fx74x6f:20170409032211p:plain

 

ここにはないが、WatchKit App(watchOS)と watchOS の Game 用の 拡張機能がある。

要するに、App ストアに並んでいる Apple Watch のアプリは拡張機能で実装されている。
同じアプリでデバイス間でデータアクセスするとなると、拡張機能で作成するのが現状もっとも適しているからだろう。

 

今後、もし新しいデバイスが増えるなら、噂されている AR 的のものやデバイスが実装されるのなら、
そこには App Extension が使用されるだろう。

 

あ、ちなみに、 Unity など Xcode のプロジェクトファイルを直接いじれない、
ほとんどのマルチプラットフォーム開発では
App Extension が簡単に開発ができなかったりする。

 

次期 iPhone の GPU

iPhoneImagination Technologies 社の PowerVR を使用していて、 ちょいと前に「PowerVR」の新世代GPUアーキテクチャ「Furian」を発表された。

プレリリース(英語) https://www.imgtec.com/news/press-release/imaginations-new-powervr-furian-gpu-architecture-will-deliver-captivating-and-engaging-visual-and-vision-experiences/

たぶん、iPhone も Furian な Series 8XT? を載せてくるだろうと思う。 AppleImagination Technologies の株主だし、 ARM チップ同様に自前でカスタマイズできる権利を持っているのでやりたい放題だ。

プレスリリースによると7シリーズと比べて以下の性能向上とのこと

  • FLOPS で 35 %
  • Fill rate で 80 %
  • ゲーム性能で 70 ~ 90 %

iPhone 6s が 384 GFLOPS で、 iPhone 7 は 50% 向上と言っていたので 576 GFLOPS ぐらい。 そこから 35% 向上となると 777 GFLOPS 近くなる。

多分、Nintendo Switch をドックに刺した時と同じぐらいになる可能性はある。

Fill rate が 80 % 向上という点から見ても AR とかをやり始めてもおかしくないかもね。

Windows 10 から macOS sierra に移行した時に覚えておきたいショートカット、機能

control が command となっており、
command + C でコピー、command + X で切り取り、command + V でペースト、
command + A で全選択、command + Z で取り消し、
command + S の保存、command + tab でアプリの切り替えなどはかわらないが、
Windows での操作では利かない動作があるのでご紹介。

 

ファイル選択して enter キーを押してもファイルが開かない。

Mac の場合、ファイルやフォルダのリネームになるので、
command + O を押す。

 

ファイル選択して delete キーを押してもゴミ箱に行かない。

command + delete キー
command + option + delete キーで削除となる。

 

ゴミ箱を空にしたい。

command + shift + delete キー

 

全体的に検索したい (Windows キー + F)

command + space キー

 

ファイルやフォルダの情報が見たい

command + i

複数選択してこのショートカットを使うと選択した数だけ開く。
1000個ぐらい開いてしまい固まったことがある。

 

まとめて内容を表示したい場合は複数選択して

command + option + i

 

スクリーンショット

command + shift + 3 で全体。

command + shift + 4 で任意の箇所。

command + shift + 4 を押した後にスペースキー
ウインドウを選択しクリックでスクリーンショットを撮る。

スペースキー後 option とクリックでウィンドウの影が消せる。

 

重なっているウインドを広げて確認したい

control + 上カーソルキー

クリックすると前面に出る。

 

ウインドウのスナップ

標準機能ではない。

アプリを利用する。

Magnet マグネット

Magnet マグネット

  • CrowdCafé
  • 仕事効率化
  • ¥120

 

Dock を選択、カーソルキーで移動させたい

control + F3 (環境によっては Fn キーも)

左右キーで移動、上で右クリックの表示、enter でアプリ起動。

 

ファイルやフォルダのパスを知りたい

選択後、command + Alt + C でコピーしテキストエディタなどにペーストする。

もしくはフォルダーの場合だが FinderPath を使うのも良い。

bahoom.com

上のアプリ、そのままだと使えないので、
システム環境設定のセキュリティとプライバシーをクリックし、
プライバシータブのアクセシビリティから許可のチェックを入れる。

 

パスを入力してそのフォルダに移動したい

Finder で command + shift + G を押し、入力して、移動ボタンを押す。
上記の FinderPath でも可能。

 

他の仮想デスクトップ移動したい

control + 左右キー

仮想デスクトップがない場合は動作しない。
control + 上キーをクリックして右の「+」ボタンを押して増やすべし。

ちなみに新規の仮想デスクトップや
使わなくなった仮想デスクトップの削除のショートカットはない。

 

クリップボードの内容が知りたい

テキストだけだが、Finder のメニューの「編集」のクリップボードを表示で確認できる。

 

キーボードで操作したい

デフォルトだと
ポインティングデバイスだけでしか操作できないものがある。 以下の操作で Tab キーでアラートのボタン等移動できるようになる。

「システム環境設定」アプリを起動し、 キーボードクリック。
「ショートカット」のタブの「キーボード」の項目をクリックし、
「Tabの操作操作対象を変更する」にチェック。
下にある「すべてのコントロール」を選択する。

 

キーボードシュートカットを変更したい。

上記のショートカットのタブである程度の機能は変えられる。
ただ、一部システムで使用できないキーがある。

 

アプリの強制終了

command + option + esc

リストが出るので応答しなくなったアプリを選択して終了させる。

 

Safari で Metal のような API が実装されるかも?

WebKit で WebGPU というローレベルの 3DCG 命令にアクセスするための API の草案が公開された。
機能的に足りない部分があるし、ブラウザで実装されるのは当分先になりそう。

現状、Apple が出したネタなので Metal に近く、
シェダーも Metal に近く Vulkan の SPIR-V や DirectX の DXIL のように事前コンパイルさせ中間言語になるらしい。
シェダーのファイルを人が読めるようなものにするかは検討中とのこと。

Metal を基にしているが、Metal に縛られる必要はないとのことで、
今後、改定していきたいとのこと。

 

参照元(英語)

Next-generation 3D Graphics on the Web | WebKit

WebGPU API

iPhone、iPad の GPU はいつか据え置き型ゲーム機超えるかもしれない(多分当分超えない)

一応、iPhone 7 の GPU が何なのか明確にはわかっていないが Wikipedia によると GT7600 Plus らしい。
カタログスペックによると GT7600 の約倍の 729.6 GFLOPS という性能。
周波数を落としたり、色々やって動作させたりしているっぽく、
iPhone 7 の発表によると iPhone 6s の 50% アップらしい。

でもって、iPhone 6s の GPU
PowerVR Series7 XT の6シェーダクラスタで192演算ユニットを持つ
PowerVR GT7600 が使われている。

性能的には単精度浮動小数点数で 384 GFLOPS
iPhone 6s の時点で PlayStation 3Xbox 360 を超えている。

 

ハードウェア別でまとめてみた

ハードウェア FLOPS
PlayStation 3 224 GFLOPS
Xbox 360 240 GFLOPS
Wii U 352 GFLOPS
iPhone 6s 384 GFLOPS
Xbox One 1.2 TFLOPS
PlayStation 4 1.8 TFLOPS
GeForce 1060 3.8 TFLOP
PlayStation 4 Pro 4.2 TFLOPS
GeForce 1080 8.8 TFLOPS

 

iPhone 6s の 50% アップとのことなので iPhone 7 は最大 576 GFLOPS となるだろう。

また、iPadGPU はコア数が倍になるので、 A10X は 1152 GFLOPS となり Xbox OnePlayStation 4 に近づくかもしれない。

あと、Nintendo Switch は 768 GFLOPS ではないかと予想されている。

 

以上を踏まえて、まとめてみた

ハードウェア FLOPS
PlayStation 3 224 GFLOPS
Xbox 360 240 GFLOPS
Wii U 352 GFLOPS
iPhone 6s 384 GFLOPS
iPhone 7 576 GFLOPS ?
Nintendo Switch 768 GFLOPS ?
次期 iPad 1.1 TFLOPS ?
Xbox One 1.2 TFLOPS
PlayStation 4 1.8 TFLOPS
GeForce 1060 3.8 TFLOP
PlayStation 4 Pro 4.2 TFLOPS
GeForce 1080 8.8 TFLOPS

 

次期 iPhone では集積率が上がるため、さらに速度の向上があると信じている。

 

とりあえず、据え置きの方もスペックが上がるので、 追い抜くのはまだまだ当分先だろう。

 

Apple A10X を予想する

Geekbench のベンチマークからの推測
iOS Benchmarks - Geekbench Browser

iPhone

端末 チップ名 周波数 シングルコア デュアルコア
iPhone 7 Apple A10 Fusion 2.3 GHz 3293 5369
iPhone 6s Apple A9 1.8 GHz 2369 3964
iPhone 6 Apple A8 1.4 GHz 1465 2445
iPhone 5s Apple A7 1.3 GHz 1205 2009

 

iPad

端末 チップ名 周波数 シングルコア デュアルコア
iPad Pro (9.7-inch) Apple A9X 2.3 GHz 2934 4729
iPad Air 2 Apple A8X 1.5 GHz 1782 3978
iPad Air Apple A7 1.4 GHz 1308 2190

 

変遷

iPhone

端末 周波数 シングルコア デュアルコア
A7 → A8 1.08 倍 1.22 倍 1.22 倍
A8 → A9 1.28 倍 1.61 倍 1.62 倍
A9 → A10 Fusion 1.27 倍 1.39 倍 1.35 倍

 

iPad

チップ 周波数 シングルコア デュアルコア
A7 → A8X 1.07 倍 1.36 倍 1.81 倍
A8X → A9X 1.53 倍 1.64 倍 1.18 倍

 

 

正直、わからん!

 

とりあえず、iPhone の伸び率が同じぐらいなので、その伸び率でいうと、 Geekbench のベンチマークのスコア的には、

 

以下のものと同等になってしまう。

シングルコアで
MacBook Pro (15-inch Late 2016)
Intel Core i7-6920HQ @ 2.9 GHz (4 cores)

デュアルコア
MacBook Pro (13-inch Retina Early 2013)
Intel Core i7-3540M @ 3.0 GHz (2 cores)

 

まとめ

バッテリーの問題等このスペックになるかはわからないが、 近しいものになるような予感はしている。

SoC のプロセスルール、GPU の強化、次世代のメモリーとかが使用されれば、さらに iPad の体感速度は上がるだろう。

A10 Fusion のように big.LITTLE な構成にしコア数を増やしてきても面白いし。

また、Snapdragon 835 では旧来の Windows アプリケーション(クラシック デスクトップ アプリ)が動くらしく、Photoshop を動かすデモを行っていた。
次の Windows Phone の Continuum 使用時にクラシック デスクトップ アプリが使用可能という噂もある。
(もし、スマートフォン秀丸とか使えたら面白い)

これらを踏まえると、もう一般範疇で使用されるパソコンの時代は終わりそうな勢いである。
もしくは、MacApple A シリーズのチップが載るというところ。

面白くなってきていると思われる。

Swift で Touch Bar 開発 - 今更だけど寿司を回す

前回のものがそのままでは動かなくなってしまい、そのまま直すのあれなので、今更だが寿司を回すことにする。

f:id:x67x6fx74x6f:20170124005816p:plain

あと、前回すっ飛ばした概要の説明。

 

今更だけど Touch Bar とは

宇宙に衝撃を与えるため、
ESC、ファンクションキー、電源ボタンを過去のものにして代わりにタッチセンサーを載せたもの。
アプリケーションの状態によって適切な機能が表示され、使用できるようになっている。
(物理の ESC キー返せ)

キーボードの拡張としてつくられたものなので、アプリケーションの表示上にない機能は実装してはならないらしい。
例外として、フルスクリーン時にクリックや右クリックがされない限り操作でにないものは、
画面上に表示されていなくても使用可能とのこと。

よって、残念ながら今回のタッチバーの機能は実装してもアプリの審査を通ることはない。

 

Touch Bar 動作

NSTouchBar クラスを呼び、デリゲートから NSTouchBarItem をぶち込むだけだ。

NSTouchBarItem は大概カスタムの NSCustomTouchBarItem で、
ボタンなどの UI や ViewController をぶち込む。

 

ちゃんとした説明

Touch Bar は NSTouchBar オブジェクトであり、NSTouchBarItem の配列である。
でもって、NSTouchBar オブジェクトは以下の条件を満たす必要がある。

  • キーボードの拡張らしいのでレポンダーチェインが使用されており、NSResponder のサブクラスのインスタンスである
  • NSTouchBarProvider プロトコルに準拠する
  • そのプロトコル内で makeTouchBar() メソッドを実装する

AppKit のほとんどのレスポンダーは、
NSTouchBarProvider プロトコルに準拠し、
Key-Value Observing (KVO) をサポートしていて、
キーの値の変更で通知し、delegate に書かれた振る舞いで Touch Bar の中身が変わる。

どうやら NSTouchBarProvider プロトコルに準拠するオブジェクトを Bar provider というらしく、
Bar provider が持つ touchBar プロパティ に nil を渡すと makeTouchBar() -> NSTouchBar? が動き、
NSTouchBar を設定値とともに返り値として、touchBar プロパティに渡す。

touchBar プロパティはデフォルトで空なので、
makeTouchBar() が呼ばれるが何もないので、
Touch Bar は何も表示されていない状態になる。

と、書いたが、 NSResponder も NSTouchBarProvider も makeTouchBar() も組み込まれているので、
とりあえず、つくる上では今回はあんまり深く考えなくてもよい。

 

今回の環境

Touch Bar がない場合はエミュレータを使って開発が可能。
Xcode を立ち上げてメニューバー Window > Show Touch Bar で表示される

 

下準備

プロジェクト作成

macOSCocoa Application を選択し、「Next」ボタンを押す。

f:id:x67x6fx74x6f:20170124005940p:plain

ファイル名を入力。
ちなみに、Swift を使うので Language は「Swift」を選択。
問題がなければ、「Next」ボタンを押す。

f:id:x67x6fx74x6f:20170124010644p:plain

保存先を選んでプロジェクト作成完了。

 

NSWindowController 的なクラスをつくる

今回は真面目につくる。
Command + N を押して新しいファイルをつくり、 Cocoa Class を選択して「Next」ボタンを押す。

f:id:x67x6fx74x6f:20170124010728p:plain

Class 名はなんでもよいが、とりあえずここでは「WindowController」に。
でもって、サブクラスを NSWindowController を選択。

f:id:x67x6fx74x6f:20170124010759p:plain

プロジェクト作成時の Main.Storyboard を使用するので、 「Also create xib file for user interface」チェックボックスを外し、
「Next」ボタンを押す。

 

つくったクラスを Storyboard で紐付ける

Main.Storyboard 開き
左側 Document Outline の「Window Controller Scene」を選択
Command + Control + 3 を押して、右側の Identity Inspector
最初の項目 Custom Class の Class の下矢印から 先ほど作成した「WindowController」を選び変更。

これで下準備完了。

f:id:x67x6fx74x6f:20170124010908p:plain

 

とりあえず、Touch Bar に寿司を表示させてみる

まず、ESC キーの横に寿司を1つ表示させるよ。

はじめに Touch Bar に表示させる ViewController を作成から。

NSWindowController の時と同様に、 Command + N を押して新しいファイルをつくり、 Cocoa Class を選択して「Next」ボタンを押す。

Class 名はなんでもよいが、とりあえずここでは「SushiController」に。 でもって、サブクラスを NSViewController を選択。 プロジェクト作成時の Main.Storyboard を使用するので、 「Also create xib file for user interface」チェックボックスを外し 「Next」ボタンを押す。

f:id:x67x6fx74x6f:20170124011101p:plain

SushiController.swift を開いて書いていく。

viewDidAppear() で Touch Bar 表示させるのだが、 loadView() で self.view を設定しないと怒られるので、 super.viewDidLoad() の下に self.view = NSView() を書く

override func loadView() {
    super.viewDidLoad()
    
    self.view = NSView()
}

そんでもって、Touch Bar 中身である viewDidAppear() の中を書いていく。

流れ

  • 表示するための NSView をつくる
  • NSView の大きさと位置を決める
  • SushiController の view に addSubview で作成した NSView を入れる
  • NSTextView に絵文字の寿司を設定する
  • NSView に addSubview で作成した NSTextView を入れる

以下、コード。

override func viewDidAppear() {
    
    let sushiView = NSView()
    
    sushiView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
    sushiView.layer?.position = CGPoint(x: 0, y: 0)
    
    self.view.addSubview(sushiView)

    let sushi = NSTextView(frame: NSRect(x: 0, y: -2, width: 30, height: 30))
    sushi.string = "🍣"
    sushi.drawsBackground = false
    sushi.font = NSFont.systemFont(ofSize: 20)
        
    sushiView.addSubview(sushi)
}

あ、寿司は TextView で表示しているので drawsBackground で false を設定しないと
寿司の背景が白くなるので気をつけて。

とりあえず、Touch Bar 中身はつくったのだが、 表示する設定はしていないので、
続いて書いて行く

 

NSWindowController.swift をいじっていく。

もう忘れている可能性があるが、最初の方に説明している動作を実装する。

流れ

  • 表示する NSTouchBarItem の識別子をつくる
  • デフォルトで呼び出される makeTouchBar() をオーバーライドして NSTouchBar や識別子などを設定する
  • Touch Bar のデリゲートで識別子からカスタムの TouchBarItem を設定する

この3つを設定するを表示できる
てことで、以下コード。

まず、初めに
import Cocoa の下に Touch Bar 表示させるための識別子を設定する。
とりあえず、以下のコードを書く

fileprivate extension NSTouchBarItemIdentifier {
    static let sushiID = NSTouchBarItemIdentifier("jp.food.touchbar.sushi")
}

NSTouchBarItemIdentifier を拡張して NSTouchBarItemIdentifier を設定。
今回は一つしかないが複数ある場合は、被らないような文字列に。
ちなみに、fileprivate というアクセス修飾子は Swift 3.0 から導入されたもので
そのファイル内でしか使用できない。 今回の場合だと NSTouchBarItemIdentifier.sushiID は NSWindowController.swift でしか使用できない。
試しに、SushiController.swift に 「NSTouchBarItemIdentifier.s」まで打ち込んでも入力候補に出てこないはずだ。

次は override func windowDidLoad() { ... } の下に 以下の初期設定のコードを入力

@available(OSX 10.12.2, *)
override func makeTouchBar() -> NSTouchBar? {
    let mainBar = NSTouchBar()
    mainBar.delegate = self
    mainBar.defaultItemIdentifiers = [.sushiID]
    
    return mainBar
}

NSTouchBar を設定し、デリゲートとアイテムの識別子を設定し NSTouchBar を返す。 識別子は先ほど設定したものを配列として入れている。
ちょっと前に書いたように、オーバーライドした makeTouchBar() の返り値 NSTouchBar は WindowController が持つ
self.touchbar プロパティ渡される。
self.touchbar に自前の NSTouchBar を返す関数を放り込むことで Touch Bar の表示を変えることができる。

ちなみに @available(OSX 10.12.2, *) は見たままだが、
これを書いた下のブロックは macOSX 10.12.2 以降で動作するというやつ。

 

続いてデリゲートの設定
class WindowController {} の下に
以下のコードを書く

 

@available(OSX 10.12.2, *)
extension WindowController: NSTouchBarDelegate {
    func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
        
        if identifier == .sushiID {
            let item = NSCustomTouchBarItem(identifier: identifier)
            item.viewController = SushiController()
            
            return item
        }
        
        return nil
    }
}

前回同様、WindowController を拡張してデリゲートを書いている。
内容は識別子が sushiID だったら NSCustomTouchBarItem を設定し、
viewController の中身を最初につくった SushiController() にしている。

 

入力した WindowController.swift は 以下のようになる。

import Cocoa

fileprivate extension NSTouchBarItemIdentifier {
    static let sushiID = NSTouchBarItemIdentifier("jp.food.touchbar.sushi")
}

class WindowController: NSWindowController {
    
    override func windowDidLoad() {
        super.windowDidLoad()
    }
    
    @available(OSX 10.12.2, *)
    override func makeTouchBar() -> NSTouchBar? {
        let mainBar = NSTouchBar()
        mainBar.delegate = self
        mainBar.defaultItemIdentifiers = [.sushiID]
        
        return mainBar
    }
    
}

@available(OSX 10.12.2, *)
extension WindowController: NSTouchBarDelegate {
    func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
        
        if identifier == .sushiID {
            let item = NSCustomTouchBarItem(identifier: identifier)
            item.viewController = SushiController()
            
            return item
        }
        
        return nil
    }
}

Command + R を押すとビルドされ、アプリ起動後に、
Touch Bar の ESC キーの横に寿司が表示される。

 

f:id:x67x6fx74x6f:20170124012011p:plain

 

寿司を並べてみる

ただ複数配置するだけ。

 

SushiController.swift を開いて再度編集

こちらを

let sushi = NSTextView(frame: NSRect(x: 0, y: -2, width: 30, height: 30))
sushi.string = "🍣"
sushi.drawsBackground = false
sushi.font = NSFont.systemFont(ofSize: 20)

sushiView.addSubview(sushi)

 

こちらに変更

for i in 0...10 {
    let sushi = NSTextView(frame: NSRect(x: i * 80, y: -2, width: 30, height: 30))
    sushi.string = "🍣"
    sushi.drawsBackground = false
    sushi.font = NSFont.systemFont(ofSize: 20)
    
    sushiView.addSubview(sushi)
}

 

Command + R を押すとビルドされ、アプリ起動後に、
寿司がたくさん表示される。

 

f:id:x67x6fx74x6f:20170124015218p:plain

 

寿司を動かしてみる

ただ Core Animetion で横移動するだけ。

 

SushiController.swift を開いて再度編集

先ほどループさせたブロックの後に以下のコードを追加。

let anim = CABasicAnimation(keyPath: "position")
anim.repeatCount = .infinity
anim.duration = 1
anim.fromValue = sushiView.layer?.position
anim.toValue = NSValue(point: NSPoint(x: -80, y: 0))
sushiView.layer?.add(anim, forKey: "position")

アニメーションの種類は移動で、リピートは無限、1秒で -80px 左にアニメーションする。
このままだと、アニメーションが途切れるので、sushiView.frame の 幅を +80 する。

 

以下、SushiController.swift の全コード。

import Cocoa

class SushiController: NSViewController {
    
    override func loadView() {
        self.view = NSView()
    }
    
    override func viewDidAppear() {
        
        let sushiView = NSView()
        
        sushiView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width + 80, height: self.view.frame.height)
        sushiView.layer?.position = CGPoint(x: 0, y: 0)
        
        self.view.addSubview(sushiView)

        for i in 0...10 {
            let sushi = NSTextView(frame: NSRect(x: i * 80, y: -2, width: 30, height: 30))
            sushi.string = "🍣"
            sushi.drawsBackground = false
            sushi.font = NSFont.systemFont(ofSize: 20)
            
            sushiView.addSubview(sushi)
        }
        
        let anim = CABasicAnimation(keyPath: "position")
        anim.repeatCount = .infinity
        anim.duration = 1
        anim.fromValue = sushiView.layer?.position
        anim.toValue = NSValue(point: NSPoint(x: -80, y: 0))
        sushiView.layer?.add(anim, forKey: "position")
        
    }
    
}

Command + R を押すとビルドされ、アプリ起動後に、 寿司が回る。

 

 

おまけ

Command + W などで
アプリのウインドウを閉じてもアプリは終了しないので
class AppDelegate にその処理を追加する。

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
}

 

おまけ2

今回ウインドウに Touch Bar を設定したため、Dock にぶち込んで戻すと Touch Bar に以前のものが表示されつつ、新しいアニメーションが表示されてしまう。
なので、見えなくなったら初期化するコードを SushiController へ書く。

override func viewDidDisappear() {
    self.view = NSView()
}

 

AppDelegate.swift で Touch Bar の処理を書くと上の処理はいらない。
self.touchBar の self を指す場所が NSApplication になるためだが、Apple のサンプルコードや Apple 謹製のアプリの振る舞いを見ていると NSWindow に touchBar プロパティを設定しているっぽい。

   

まとめ

以上、寿司を回してみた。
Touch Bar に NSViewController を表示させているため、かなりの自由なことができるようになっている。

 

スポンサーリンク