Swiftの動向とアツさを追う try! Swift参加レポート

try! Swift 3日目 参加レポート

Swiftの世界的カンファレンス、try! Swiftが3月2日~4日の3日間にわたり、渋谷のサイバーエージェントのオフィスにて開催されました。

最終日である3日目に行われた11のセッションのうち、4つを抜粋してレポートします。

Hiroki Kato氏「Motivation based library abstraction」

初めにこの日最初のセッションでもあった、株式会社はてな所属のHiroki Kato氏@cockscombによるセッションを紹介します。

はてな社のアプリは現状ほぼすべてSwiftで書かれているそうですが、その過程で小さなライブラリを数多く作ってきたことを氏はまず紹介しました。その上で、ご自身がこれまで開発の際に作成してきた以下の3種類のライブラリを例として挙げました。

"必要は発明の母"と言うように、これらのライブラリが実務中で必要に迫られて作り上げたものであることを述べた上で、どういった背景があったのか、どのような解決したい問題に対して取り組んだ結果なのか、を紹介していく形でトークが進みました。

  • UTIKit
  • HUDKit
  • HTTPRequestMatcher(カンファレンス時点では未公開)
画像

このレポートでも順番に内容を振り返ってみます。

UTIKit

名前の通り、UTI(Uniform Type Identifier)を扱うこのライブラリは、素のSwiftのままMIMEタイプを扱おうとした際にコードが複雑になってしまう、という問題を解決するために作成されたものだそうです。UTI自体はデータの種類を一意に識別することができますが、独自の構造を持っていることもあり、例えばJPEGのデータに対してその拡張子を取り出すというだけで読みづらいコードとなってしまいます。UTIKitはこの問題を解決するために以下のような特徴・機能を提供し、SwiftらしいインターフェイスでUTIを扱うことができるようです。

  • 簡潔な記述
  • 同一性の確認(Equality)
  • パターンマッチによる識別(Confirmance)

例えば、MIMEタイプがimage/jpegであるものと、拡張子がjpegであるものの等値性を以下のようにして確認できます。

UTI(MIMEType: "image/jpeg") == UTI(filenameExtension: "jpeg")

HUDKit

続いて紹介したHUDKitもアプリケーション開発の中で生まれたもので、以下のような場面においてHUDを利用するために作成されたそうです。

  • ブログ記事投稿後のユーザの操作への割り込み
  • SNSへのシェアの際にシェアするかどうかの確認

HUDに関しては既存のライブラリもありますが、viewベースのものでは不十分で、viewControllerとして扱うことができるHUDKitを作成されたそうです。このライブラリでは以下の2つのコンポーネントが提供されていることを紹介しました。

HUDPresentationController
UIPresentationControllerベースで自由にviewControllerを指定できる
HUDProgressViewController
進捗状況をHUDとして簡単に表示できる

HTTPRequestMatcher

最後に紹介したHTTPRequestMatcherは、Universal Linkやhandoffなどの対応で、特定のURLのパスでは特定のviewControllerを出したい、という際の処理を簡単にするものです。PerlのRouterSimpleを参考にしたもので、文字列でパスの制約を記述し、正規表現でのマッチングとキャプチャを行うことができると説明しました。例えば、あるURLが指定したblogのURLパターンとマッチしているかの判定、また、そのパターン内のblog_idのキャプチャ部分を以下のように書くことができます。

let URL = NSURL(string: "http://example.com/blog/123/article/456")

if case .Match(let parameters) =
    PathMatcher("/blog/{blog_id:[0-9]+}").match(URL) {
        let blogID = parameters["blog_id"].first!
        // ..
    }
}

問題の一般化

これら3つライブラリはどれも実際に直面した問題について、一般化可能な問題である場合や、または他の人にとっても役に立つものかもしれない、と思った際にそれを抜き出して解決したものであると述べました。そういったコードに対し、再利用性を持たせるためには以下が重要であるとのことです。

  • Generalize
  • Parameterlize
  • Abstraction

この"一般化可能かどうか"については、

  • 直感
  • 向き合っている問題がどのドメインに属している問題なのか。
    • 自分たちの固有ドメインでなければチャンス

といったものを判断材料にしているとQ&Aで回答していました。我々開発者がやるべきことは誰かの要望を叶えるアプリを作ることですが、その過程で他の人にも役立つことがあればコードをシェアしていこうと語り、このセッションを締めました。

画像

Yasuhiro Inami氏「Parser Combinator in Swift」

続いてはLINE株式会社所属で、ReactKitなどのライブラリの作者としても知られるYasuhiro Inami氏@inamiyによる、Parser Combinatorについてのトークを紹介します。

Parser Combinator

Inami氏はまずParser Combinatorとそれを構成するParser(構文解析器)について、どういったものなのかについて次のように解説しました。

Parser
  • テキスト等のデータ、特にLexer(字句解析器)の結果としてのトークンを入力として受け取り、AST(Abstract Syntax Tree)のようなデータ構造を生成
  • ボトムアップなアルゴリズムとトップダウンなアルゴリズムの2種類が存在
Parser Combinator
  • Combinatorによって複数の小さなParserを組み合わせ、より複雑なParserを構成
  • 結果として1つの大きいParserが動いているように見える
画像

SwiftでのシンプルなParser

以上を踏まえた上で、実際にシンプルなParserをSwiftで複数定義し、それらを組み合わせて複雑なParserを構成する例を示しました。Parserのモナドとして以下を定義します。

struct Parser<A> {
    let parse: String -> (A, String)?
}

これは次の状態の変換を行うコンテナと言えます。

  • 入力: String
  • 出力: 出力と入力の残りのタプルのオプショナル値(失敗することがあるため)

これを利用し、例えば常に成功するParserは以下のように書くことができます。

func pure<A>(a: A) -> Parser<A> {
    return Parser { (a, $0) }
}

こういったシンプルなParserを多数定義していき、さらにそれらを組み合わせたParser(Parser Combinator)の例を多数紹介しました。それぞれの具体的な中身全てを今回のレポートに載せるのは難しいため、ぜひ発表資料を確認してみてください。例を挙げると、あるシンボルのParserは次のようにskipSpacesに挟まれたハンバーガー状になると紹介しました(個々のParserの定義は省略します)。

func symbol(str: String) -> Parser<String> {
    return skipSpaces() *>  string(str) <* skipSpaces()
}

その後、BNFで表現した自然数で構成される計算機に基づいた、小さなParserを組み合わせたParser Combinatorを構築し、実際に"(12 + 3) * 4 + 5"という数式を解く例を示しました。しかしこれはまだ単純な例ということで、トークは次のTryParsecの紹介へと続きます。

TryParsec

TryParsecは今回のカンファレンス用にInami氏が実装したParserで、以下のレポジトリでその内容を確認できます。

以下のような特徴を持っています。

  • CSV、XML、JSONのパースをサポート
  • HaskellのAttoparsec/Aesonにインスパイアされたもので、Monadicである
  • 独自のParserも簡単に作成可能

実際にSwift標準の機能を利用せず、TryParsecによりJSONデータをパースする例をまず示しました。さらに、マッピングルールを記述したモデルに対してのJSON Decoding/Encodingが簡単に行えることと、その例を紹介しました。例えばあるモデルに対するJSON DecodingについてはFromJSONを採用し、以下のように書くことができます。

extension Model: FromJSON {  
   static func fromJSON(json: JSON) -> Result<Model, JSON.ParseError> {  
       return fromJSONObject(json) {  
           curry(self.init)  
               <^> $0 !! "string"  
               <*> $0 !! "num"  
               <*> $0 !! "bool"  
               <*> $0 !! "null"  
               <*> $0 !! "array"  
               <*> $0 !! "dict"  
               <*> $0 !! "object"  
               <*> $0 !? "dummy"  
       }  
   }  
}

SwiftでJSONを扱う際の有名なライブラリの1つであるthoughtbot/Argoと同じApplicative Styleでの記述が可能になっており、非常に興味深い内容でした。まだパフォーマンス面が課題とのことですが、改善は継続していくとのことです。

画像

Jesse Squires氏 - Contributing to Open Source Swift(オープンソースSwiftへの貢献)

JSQMessagesViewControllerの作者としても知られる、Instagram社のiOSエンジニアであるJesse Squire氏@jesse_squiresの発表を紹介します。

Squires氏はまず以下を順に解説しました。

  • LLVMのコンパイラアーキテクチャ
  • Clangのパイプライン
  • Swiftのコンパイル時のパイプライン

例えばSwiftのコンパイル時のパイプラインは以下のようになることを述べました。

  1. Swiftで書かれたコードをパースしAST(Abstract Syntax Tree)を生成
  2. 意味解析によってAST*を生成
  3. SILGenでraw SIL(Swift Intermediate Language)を生成
  4. 最適化によりcanonical なSIL*を生成
  5. IRGenによってLLVM IR(Intermediate Representation)を生成
  6. LLVMによって最終的なバイナリを生成

実際にシンプルなコードに対し、swiftcコマンドを利用してAST, SILなどの各ステップの生成物を出力する例を紹介した上で、このパイプラインの各ステップがSwiftのレポジトリのどの部分に該当するのか、ということを紹介しました。例として、上記のステップ1, 2については以下のような対応関係があります。

画像

こういったことを説明した上で、Swiftを取り巻くコンポーネント毎のContributeのしやすさを紹介しました。

Swift core
  • コアの部分。コンパイラなどはC++の知識が必要で、難易度が高い
    • Compiler
    • stdlib
    • SourceKit
INFRA
  • 深い知識が必要で、Contributeするのが難しい部分
  • もうある程度固まったもので、開発が活発でない
Parckage Manager
Core libs
Evolution

try! contribute()

我々は具体的にどのようにContributeしたら良いのでしょうか。氏は次のように説明しました。

  • ディスカッションはメーリングリストでスタート
  • レベルに関係なく意見を言う
  • 困ったら助けを求める
  • Pull RequestについてはCONTRIBUTING.mdを守り、ベストプラクティスに従う
  • たとえPull RequestがRejectされてもそこで落ち込まず、Contributeをそこでやめるべきではない
  • コアチームはすべての人に参加してほしいと思っている

Pull Requestに関しては、英語話者ではない場合にはTypoがあるだけで理解が大変になることもあるため、Typo fixも大事であると述べました。Chris Lattnerの次の言葉を引用していたのも特徴的でした。

Making small improvements is the way everyone starts getting involved!

最後に以下のような熱いメッセージを残し、このセッションを閉じました。

  • Swiftの成功が我々開発者にとっての成功であるのだから、Contributeすべき
  • コードだけではなくアイデアもContribute
  • Swiftは単なる言語ではなくコミュニティ

Ash Furrow氏「An Arsty Testing Tour(Artsyにおけるテスト手法の紹介)」

try! Swift最後のトークとなったのは、Moyaなどの作者としても知られ、数多くのOSSに関わっているArtsyのiOSエンジニア、Ash Furrow氏@ashfurrowによるセッションです。冒頭で以下の3つの項目を述べ、これらについてはセッションを通して強調していました。

  • テストにおいては完璧、理想形を目指さない。100%のカバレッジを目指さない。
  • コンポーネントは小さくし、Publicなインターフェイスのみをテストする。
  • 新しいアプリケーションも小さなコンポーネントから始める。

その上で、Artsyで実際にどのようなテストの戦略を取ってきたのかについて、以下4つの実際のプロダクトを順に紹介しました(すべてGithub上に公開されています⁠⁠。

以下で順番に紹介します。トークを通してコードはほとんど用いず、図をメインで説明しているのが特徴的でした。

artsy/Emergence

Apple TV用のアートワークを見るためのアプリケーションであるEmergenceが最初の例でしたが、テストは全くないとのことです。プロジェクトのデッドラインが厳しく、作業は1人のみという最小限のリソースの中でバランスを考えた結果であるとのことで、テスト戦略に際してはバランスが重要だと語りました。ですが、同時にテストが書けないことを気にはすべきだと述べていました。

artsy/energy

アートギャラリーのアプリケーションのテストケースの紹介です。元々はテストはなかったのですが、非常に大きいコードベースだったため、途中でテストを書くことになったとのことです。

まず、Bus Factor(もしチームの誰かがバスに轢かれてもプロダクトを出荷できるかどうか⁠⁠、イコールどれだけチーム内の個人に情報が集中しているかの指標について触れ、その集中を避けるために行うべきこと・行ったことについて述べました。

  • 良いテスト => 外部に対しての振る舞いのテスト
  • クラスは小さく保つ
  • Dependency Injectionを多く活用
  • オブジェクトは必要のないものは生成しない
  • RSpecスタイルでのテストで、共通処理は外に出す

artsy/eigen

eigenというアートのアプリについても後からテストを加える形だったそうですが、以下の困難があったことを紹介しました。

  • 複数の箇所からネットワークアクセスがある状態へのテスト
    • => Mockを使用
  • iPhone, iPadという複数のプラットフォームに対してテストが必要
    • => shared_exampleを利用

また、特徴的なテストとして、Snapshot Testの紹介がありました。こちらはfacebook/ios-snapshot-test-caseを利用したもので、スクリーンショットの比較によってUIのテストを行っていたそうです。

画像

その他にも以下のような説明をしていました。

  • 新しいコードはテストがなければならないというルールを設けた
  • クラスはできるだけ小さく保つ
  • テストは小さな要素から始める
  • よくないコードを書かなければならない場合でも、どう修正したいのかを残しておく

artsy/eidolon

最後にアートオークションのアプリであるeidolonでのテスト事例の紹介です。Swiftが出た直後から始めたプロジェクトで、すべてが新しい中で、Unit Testが唯一慣れ親しんだもので、それがSwift自体を理解することにも繋がったと述べました。また、QuickNimbleを利用することで、RSpecスタイルのテストを効果的に書くことができたと述べました。特にNimbleの利用により、XCTestで記述していた部分を以下のようにシンプルに書くことができることを紹介しました。

// XCTest
XCTAssertEqual(1 + 1, 2, "...")

// Nimble
expect(1 + 1).to( equal(2) )

// Or 
expect(1 + 1) == 2

最後に冒頭の3つの項目を繰り返し、セッションを閉じました。

画像

終わりに

すべてのトークを紹介できないのが残念ですが、これ以外にも3日目の発表はSwiftでの統計学的な処理やサーバサイドでSwiftを利用する方法など、興味深い話が非常に多くありました。クロージングでは今回のカンファレンスでの様々な数値も発表されましたが、来場者は536名、そのうち147名は海外からの参加者だったそうです。

画像

日本でのMobile・Web技術系カンファレンスで海外からの参加者の比率がこれほど高いものはそれほど多くはないと思います。私自身も多くの海外からの開発者と話す機会を持つことができ、非常に濃密な3日間を過ごすことができました。最終日の夜には参加者全員での懇親会も開かれたのですが、通訳ができる方を有志で募り、海外からの参加者と日本人の参加者がより交流を持てるようにするという試みも行われました。そのこともあってか懇親会も大変盛り上がり、3日間のカンファレンスの幕が閉じられました。

以上がtry! Swift3日目のレポートになります。主催者のNatashaTheRobotさんが以下ブログで語っていますが、開催に至るまでの道のりは大変だったようです。運営に携わった皆様、本当にありがとうございました。素晴らしいカンファレンスでしたので、ぜひまた開催されることを期待したいです。

Do you believe in magic? The making of try! Swift Conference Tokyo 2016

おすすめ記事

記事・ニュース一覧