書いて覚えるSwift入門

第31回収穫の秋にWatchすべきなのは

人類にはまだ早すぎるApple Watch

もはや恒例となった「Apple秋の収穫祭⁠⁠、今年2017年9月12日のイベントで読者のみなさんが最も注目したのはどの製品でしたか? 全面ガラス張りのSteve Jobs Theater? 全面ディスプレイのiPhone X? まさか4K HDR対応したApple TV?

筆者が最も注目したのは、フォームファクターが一番変化していない製品。そう、Apple Watchです写真1⁠。実質iPhone 7sなiPhone8でさえ、背面がアルミニウムからガラスに変わったというのに、Apple Watchときたらそれすらない。フォームファクターが変わる都度、iPhoneはケースやバンパーといったアクセサリーも変化しますが、Apple Watchのバンドは初代のものがそのままSeries 3でも使えますし、最新のものが初代でも使えます。そうでないと困ります。何しろ今回「廃盤」になったのは初代ではなくSeries 2だったのですから。

写真1 Apple Watch Series 3
写真1 Apple Watch Series 3
図1 マップのアイコンもApple Parkに引っ越し
図1 マップのアイコンもApple Parkに引っ越し

しかし、今回のSeries 3のCellular Modelは、ほかのApple WatchとはiPhoneとiPod Touch以上の違いがあります。Series 3 CellularはiPhoneがなくてもオンラインなのです。これは何を意味するか?

真の全裸コンピューティングが実現するのです! 実際に露天風呂でSiriにたずねてみたら、このように答えてくれるのです図2⁠。

図2 siriに「ここはどこ」と問うと……
図2 siriに「ここはどこ」と問うと……

Wi-FiからCellularへの切り替えはとてもスムーズ。iPhoneを見失うとが表示されますが図3⁠、数秒でセルラー接続に切り替わります図4⁠。

図3 iPhoneとの接続が
切れたときの表示
図3 iPhoneとの接続が切れたときの表示
図4 わずか数秒で
セルラー接続
図4 わずか数秒でセルラー接続

全裸コンピューティングは人類には早すぎにしても、脱スマホコンピューティングなら筆者を含め少なからぬ人が待ちわびていたのではないのでしょうか。ジョギングやワークアウトのとき、あるいは温泉街を浴衣で練り歩くとき……スマホですらかさばり過ぎて大き過ぎると感じるシーンは決して少なくありません。そんなときでもメッセージは出せますし図5、図6……。

図5 iPhoneなしでも
図5 iPhoneなしでも
図6 メッセージ送信
図6 メッセージ送信

電話もできますし図7……。

図7 もちろん電話も!
図7 もちろん電話も!

支払いだって問題ありません図8⁠。

図8 Apple PayもOK!
図8 Apple PayもOK!

まあ、どこでもオンラインってことは……、どこでも仕事が追いかけてくるということ図9でもありはするのですが。

図9 Slackの通知もOK!
図9 Slackの通知もOK!

もちろんApple WatchがiPhoneの代わりを100%つとめるというのには無理があります。何と言っても世界で一番使われているとAppleが豪語するカメラがありませんし、セルラー契約の1つをとっても、初期設定にはiPhoneが必須です。しかし今回の「どこでもオンライン」と同じぐらい感心したのは、複数のデバイスをどう組み合わせるか。たとえばAirPodsは、iPhoneがあるときにはiPhoneの、Apple WatchしかないときにはApple Watchの(イヤ|マイクロ)フォンに全自動で切り替わります図10⁠。

図10 自動的にAirPodsも接続される
図10 自動的にAirPodsも接続される

だとしたら、Apple Watch、いやユーザのコンピューティング環境が全自動で切り替えられる道理がないわけがありません。デバイス自身が今、自分が使われていることを判定し、自動的に切り替わる。音声に関してはAirPodsですでにそれが実現しています。映像だってそうならない道理はありません。すでにApple TVはiPhoneやiPadやMacのディスプレイとしても機能していますが、ワン(クリック|タップ)必要だという点でAirPodsに及びません。それがAirPodsなみにシームレスになるのだとしたら?

次はARディスプレイ+カメラということになるでしょう。Google GlassにせよHololensにせよはたまたPS VRにせよ、VR/MRがマスマーケットに来ていない最大の理由は、Steve Jobsが言っていたところの⁠Connecting the dots⁠に成功していないこと。今回iOS 11にARKitが搭載され、iPhoneのカメラとCPUがARに十分な性能があることを示したAppleが、いまだヘッドアップディスプレイを欠いている状況を放置するとは筆者には考えられません。

そのときの「ハブ」は、いまだiPhoneでしょうか? それともApple Watchでしょうか?

Apple Watch Series 3で後者の可能性が見えてきました。iPhone以上に身近になりうるデバイスは今のところそれだけなのですから。

どう転んでもSwift

しかし未来がどちらに進んでも、これだけは変わらないだろうということが1つあります。それが開発言語。iOSもwatchOSもtvOSも、メインの開発言語はSwift。Linuxへの移植とSwift Playgrounds for iPadでSwiftはXcodeの専売特許ではなくなって久しいのですが、Swiftが「言語ハブ」であり続けることだけは確かだと弾言しておきます(断言までするのはちょっとこわい⁠⁠。

とはいえ、2017年秋現在の主力開発環境はXcode on Mac。iOS 11と同じく日本時間9月20日に9が正式リリースされています。Swiftも4に上がりました。主な新機能および変更点は第28回(本誌2017年8月号)のWWDC 2017特集で紹介したとおりですが、同記事で紹介しきれなかった分もあらためて紹介します。

総称型のsubscript

subscriptで総称型が扱えるようになりました。たとえばこんな書き方ができます。

struct JSON {
    var value: [String:Any]
    init(_ value: [String:Any]) {
        self.value = value
    }
    subscript<T>(k: String) -> T? {
        return value[k] as? T
        }
}

let json = JSON([
    "bool":true,
    "number":42.195,
    "string":"Swift",
    ]
)

var bool:Bool? = json["bool"]
var number:Double? = json["number"]
var string:String? = json["string"]

最終的な型はコンパイル時に決まる必要があるため、左辺は型を明示しないとコンパイル時エラーになります。

Dictionaryのデフォルト値

Dictionaryの要素はOptionalなので、dict[key]keyが存在しない場合の値はnilですが、dict[key, default:val]と書くことで、nilの代わりにvalを返すようになりました。

これは統計を取るときなどにとても便利で、今まで、

var count = [String:Int]()

for k in words {
    if count[k] == nil {
        count[k] = 0
    } else {
        count[k]! += 1
    }
}

のように初期化の有無で必要だった条件分岐が、

for k in words {
    count[k, default:0] += 1
}

のように不要になります。

"""複数行"""引用符

"""で複数行に渡る文字列リテラルが書けるようになること自体は同記事でも軽くふれたのですが、この機能が最も威力を発揮するのは、Swift内でソースコードを表記するときでしょう。

たとえばSwift 3でSwiftのソースコードを書くには、

let howmany = 42
let fizzBuzzSwift = [
    "#!/usr/local/bin/swift",
    "extension Int {",
    "    var fizzbuzz:String {",
    "        let fb = (\"Fizz\", \"Buzz\")",
    "        switch (self % 3, self % 5) {",
    "        case (0, 0) : return fb.0 + fb.1",
    "        case (0, _) : return fb.0",
    "        case (_, 0) : return fb.1",
    "        default : return \"\\(self)\"",
    "        }",
    "    }",
    "}",
    "_ = (1...\(howmany)).map{ print($0.fizzbuzz) }"
].joined(separator: "\n")

のように「分かち書き」する必要がありましたが、

let howmany = 42
let fizzBuzzSwift = """
#!/usr/local/bin/swift
extension Int {
    var fizzbuzz:String {
        let fb = ("Fizz", "Buzz")
        switch (self % 3, self % 5) {
        case (0, 0) : return fb.0 + fb.1
        case (0, _) : return fb.0
        case (_, 0) : return fb.1
        default : return "\\(self)"
        }
    }
}
_ = (1...\(howmany)).map{ print($0.fizzbuzz)
}
"""

とずいぶんとスッキリ書けるようになります。もう一例として、Swift Playgroundでちょっと変わったFizzBuzzをこさえてみました。見てのとおり、"""でくくられているJavaScriptを実行しています図11⁠。

図11 FizzBuzzの実行例
図11 FizzBuzzの実行例

"""も変数展開(interpolate)する点は注意してください。この例では\(howmany)が変数展開されていますし、\\(self)は変数展開されないよう\をエスケープしています。

Swift 4でもなお変数展開なしの引用符(PerlやRubyでは'はサポートされていません。

次回予告

そろそろ紙幅も尽きるので今回はここまで。次回はSwift 4で大いに整理された整数型のプロトコルをおもに取り上げます。

Software Design

本誌最新号をチェック!
Software Design 2022年9月号

2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)

  • 第1特集
    MySQL アプリ開発者の必修5科目
    不意なトラブルに困らないためのRDB基礎知識
  • 第2特集
    「知りたい」⁠使いたい」⁠発信したい」をかなえる
    OSSソースコードリーディングのススメ
  • 特別企画
    企業のシステムを支えるOSとエコシステムの全貌
    [特別企画]Red Hat Enterprise Linux 9最新ガイド
  • 短期連載
    今さら聞けないSSH
    [前編]リモートログインとコマンドの実行
  • 短期連載
    MySQLで学ぶ文字コード
    [最終回]文字コードのハマりどころTips集
  • 短期連載
    新生「Ansible」徹底解説
    [4]Playbookの実行環境(基礎編)

おすすめ記事

記事・ニュース一覧