Slide 1

Slide 1 text

差分Buildでサクサク開発 Embedded Frameworkのススメ ⾼⽊ 豪 ⽇本経済新聞社インターン Otemachi.swift #02

Slide 2

Slide 2 text

‣ Status • 東京⼯業⼤学 M2 ‣ SNS • @shimastripe / @shimastriper / @root ‣ Intern Task (iOS) • 電⼦版の3d touch • Modulesをフレームワーク化 ←Now!! ‣ Fav Language • Go (は?) ✴ ⼿持ちのMBPはiOSのBuildが⻑くて⾟い Go Takagi 2

Slide 3

Slide 3 text

翻訳「Buildを待つ僕」 3

Slide 4

Slide 4 text

1. スペックで殴る • iMacProを購⼊しましょう 2. プロダクトのボトルネックを減らす • 例えば型推論 • 重複コンパイルを減らす • 差分Buildを促進したい • Build時間改善⽅法 4 Embedded Framework !!

Slide 5

Slide 5 text

‣ Embedded Frameworkの紹介 ‣ 電⼦版への導⼊に必要だったタスク ‣ Build時間改善した?? Agenda 5

Slide 6

Slide 6 text

Embedded Framework

Slide 7

Slide 7 text

‣ Info • AppとExtension間でコード共有する埋め込みFramework ‣ Build時間改善 • App, Extensionをまたぐ重複コンパイルの削減 ✴ Target Membershipの場合各々にコピーしてコンパイル • 差分Buildの促進 ✴ 「1⾏しかいじってないのに全体に…」が減らせる ‣ Appのサイズを⼩さくできる(起動時) • Dynamic Framework ‣ 名前空間 • 依存関係・レイヤーを嫌でも意識、例えばAPI Clientで切る Embedded Framework (iOS8) 7

Slide 8

Slide 8 text

電⼦版の導⼊の経緯 8 RichNotification実装しよう! Ref. Human Interface Guidelines

Slide 9

Slide 9 text

電⼦版の導⼊の経緯 9 RichNotification実装しよう! 共有Moduleが多い… Membership全部に 貼るの⾯倒くさい!!

Slide 10

Slide 10 text

電⼦版の導⼊の経緯 10 RichNotification実装しよう! 共有Moduleが多い… 未来のExtensionの数だけ
 コンパイルが遅くなる… Extension毎にコピー 重複コンパイルされる

Slide 11

Slide 11 text

電⼦版の導⼊の経緯 11 RichNotification実装しよう! 共有Moduleが多い… 未来のExtensionの数だけ
 コンパイルが遅くなる… 今のうちにFrameworkに!!

Slide 12

Slide 12 text

導⼊

Slide 13

Slide 13 text

‣ Emb に依存するLibrary/Framework ‣ 移⾏するModuleの設計 ‣ 躓きやすいところ 導⼊に向けて確認すべき項⽬ 13

Slide 14

Slide 14 text

‣ FrameworkはBridging-Headerが使えない • Clang Modulesを利⽤してモジュール化 • Headerをバイナリ化するためコンパイル時間の短縮にも C LibraryをModule Mapでモジュール化 14 ※ CommonCryptoはXcode10から標準Moduleに #import #import shim.h module CommonCrypto [system] { header "shim.h" export * } module.modulemap CommonCrypto Module import CommonCrypto Swift 1. ModuleMapに読み込むHeaderを記述 2. Header Search Pathを指定 3. Swiftファイル上でImport可能になる

Slide 15

Slide 15 text

‣ Emb FrameworkはApp専⽤APIを持てない • Extensionが使えないAPIはダメ(リジェクト) ✴ Ex.) UIApplication.shared • Require Only App-Extension-Safe API: YES ↑でBuildしたFrameworkしか利⽤できない ✴ してないものをLinkするとwarning ๏ linking against dylib not safe for use in application extensions ✴ 後述しますが、もちろん⾃前のコードに対しても対象 Dynamic Framework Link時の注意点 15

Slide 16

Slide 16 text

‣ EmbeddedFrameworkで使えるよう改善 • Bridging-Headerで読んでいたものをModuleMapに • OSSにSafe APIフラグのPR • Carthage化(Membershipの重複改善) • どうしようもなかったらUnsafeなAPIをforkして削除 PR投げたりCarthage化したりコード消したり… 16

Slide 17

Slide 17 text

‣ 設計構造の⾒直し • 移⾏する前に設計が悪い箇所は直しておく ✴ Ex. UIViewControllerの型を⾒て分岐する箇所を取り除く ✴ Ex. App限定のAPIをApp側に持たせる(先述) ‣ Framework化 1. Modulesの移⾏、Framework単体でBuild Succeed 2. 外部(AppやExtension)から参照したいモジュールに
 アクセス修飾⼦を付加(public / open class) 3. AppやExtensionから参照する箇所にimportを付加 • statement毎にError出るのでものすごいエラー数になります Module群を移⾏ 17

Slide 18

Slide 18 text

‣ 直感的じゃないError • 何かが抜けて明⽰的に指定する必要性が⽣じるError ✴ ambiguous use of ✴ frameworkのimportし忘れ ✴ frameworkのextensionがPublicになってないとか • Repositoryを複製して何が参照できなくなったか
 確認できるようにしておくといい ‣ 他ブランチとのpbxprojの衝突がとても多い • (オススメMergeツールあったら教えてください) 躓きやすいところ 1/2 18

Slide 19

Slide 19 text

‣ Emb Frameworkで利⽤できないFramework • CrashlyticsはInstanceをAppにしか持つことができない • 【対策】 ✴ Emb Framework上ではprotocolとして抽象的に定義
 ApplicationからEmb Frameworkに逆Injection ‣ protocol extensionの衝突が解決できない • StringをextensionしてisEmptyフィールドを定義、
 Framework同⼠で衝突すると区別することができない • 【対策】 ✴ 冗⻑な名前を避ける/extensionを⼯夫して名前空間(疑似)作る ๏ Ex. RxSwift 躓きやすいところ 2/2 19

Slide 20

Slide 20 text

‣ Build回数がとにかく多い • Error潰してBuildしてのサイクル • 作業はスペックいいPCでやるべき ‣ スペック低いとXcodeが死ぬ • 適当に移⾏するとエラー700件とか平気で出る • Indexing Prebuilding って常にクルクルする • 静的解析が終わらない ✴ ジャンプ先が意味不明なファイルに⾶ぶ • 儚げに落ちる 感覚的に⾟いところ 20

Slide 21

Slide 21 text

Build時間改善した??

Slide 22

Slide 22 text

‣ 実機iPhone7plusで3回測って平均 ‣ 重複コンパイルしてた箇所が効いてる • Full Buildチェック 22 iMacPro2017 MBP2013 (Xcode10) Base Embed Base Embed Debug (second) 35.87 30.03 57.93 51.03 Release (second) 125.83 98.87 213.23 172.47 (あくまでゆるふわな実測値です)

Slide 23

Slide 23 text

‣ 差分Buildが効率的に起きててサクサク!! 差分Buildチェック 23 iMacPro2017 MBP2013 (Xcode10) FullBuild 差分Build FullBuild 差分Build Debug (second) 35.87 (30.03) 19.0 57.93 (51.03) 39.3 (あくまでゆるふわな実測値です)

Slide 24

Slide 24 text

‣ 従来の2分の1以下にBuild時間が短縮 • 僕が闘った 数秒は〜〜〜(完全にインパクト⾷われる) ✴ 重複・差分コンパイルの恩恵はちゃんと効いてます (ところで) Xcode10のBuildが凄い 24 iMacPro Xcode9 Xcode10 Debug (seconds) 81.94 30.03 今こそEmbeddedFrameworkに⼿をつけるチャンス!!

Slide 25

Slide 25 text

まとめ

Slide 26

Slide 26 text

‣ Build時間改善に役⽴つ • 差分Buildの促進 • 重複コンパイルの除去 • TargetMembership貼らなくていい • Appのサイズを⼩さくできる ✴ Dynamic Link過多に対するAppの⽴ち上がりの遅延は要確認 • レイヤーを意識した設計にも役⽴てる ‣ 移⾏するぞ!! 1. 作業時はスペックが⾼いPCでやるべき ‣ Build回数が通常より明らかに増えるため 2. 依存するLibrary / Frameworkの精査 ‣ 個⼈的にはここで苦労する⼿戻りが多かった 3. レイヤーの切り分け・設計構造の⾒直し 4. 移⾏ -> ひたすらErrorをつぶす Embedded Frameworkのススメ 26