Slide 1

Slide 1 text

Sansan アプリで学ぶ iOS 13 対応 After iOSDC JAPAN 2019 Sansan 株式会社 Sansan 事業部 プロダクト開発部 中川 泰夫

Slide 2

Slide 2 text

⾃⼰紹介 iOSDC で Sansan ブー スでキーボードの質問し ていたおじさん

Slide 3

Slide 3 text

アジェンダ 1. 何故やるのか? 2. Sansan アプリを iOS 13 上で実⾏出来るようになるまでに 起こった問題 3. Sansan アプリを iOS 13 上で実⾏出来るようになった後に 起こった問題 4. まとめ

Slide 4

Slide 4 text

何故やるのか?

Slide 5

Slide 5 text

何故やるのか?

Slide 6

Slide 6 text

何故やるのか? Starting April 2020, all new app updates will neet to be built with the iOS 13 SDK and support the all-screen design of iPhone Xs Max or later. (2020年4⽉以降、新規Appと、Appのアップデートのすべて をiOS 13 SDKでビルドし、iPhone XS Max以降のオールスク リーンデザインをサポートする必要があります。)

Slide 7

Slide 7 text

Sansan アプリを iOS 13 上で実⾏出来るよう になるまでに起こった問題

Slide 8

Slide 8 text

iOS 13 SDK 対応に向けて 1. macOS Catalina Beta にアップデート 2. Xcode 11 をダウンロード 3. iOS 13 SDK でビルドしてみる

Slide 9

Slide 9 text

iOS 13 SDK 対応に向けて 1. macOS Catalina Beta にアップデート 2. Xcode 11 をダウンロード 3. iOS 13 SDK でビルドしてみる

Slide 10

Slide 10 text

iOS 13 SDK でビルドしてみる ⌘+B

Slide 11

Slide 11 text

iOS 13 SDK でビルドしてみる

Slide 12

Slide 12 text

iOS 13 SDK でビルドしてみる Module compiled with Swift 5.0 cannot be imported by the Swift 5.1 compiler:

Slide 13

Slide 13 text

Swift 5.0 でコンパイル済みのモジュールを import できない Sansan アプリでは Carthage でビルド済みバイナリを コード管理することでビルド時間の短縮をしていた 以前にコンパイルしたのは Swift 5.0 対応時

Slide 14

Slide 14 text

Swift 5.0 でコンパイル済みのモジュールを import できない sudo xcode-select --switch /Applications/Xcode_11.app/Contents/Developer carthage update --platform iOS --no-use-binaries

Slide 15

Slide 15 text

Swift 5.0 でコンパイル済みのモジュールを import できない *** Building scheme "XLActionController" in XLActionController.xcworkspace Build Failed

Slide 16

Slide 16 text

XLActionController が Swift 5.1 でコンパイルできない ビルドログを⾒ると、 /XLActionController/Resource/ActionCell.xib が コンパイル出来ていない模様 master ブランチに対して Xcode 11 beta 5 でビルドできるようにする 修正の PR がマージ済み https://github.com/xmartlabs/XLActionController/pull/123

Slide 17

Slide 17 text

XLActionController が Swift 5.1 でコンパイルできない Cartfile --- - github "xmartlabs/XLActionController" == 5.0.0 + github "xmartlabs/XLActionController" "master"

Slide 18

Slide 18 text

XLActionController が Swift 5.1 でコンパイルできない carthage update --platform iOS --no-use-binaries Build Succeeded

Slide 19

Slide 19 text

Swift 5.0 でコンパイル済みのモジュールを import できない ⌘+B

Slide 20

Slide 20 text

Swift 5.0 でコンパイル済みのモジュールを import できない

Slide 21

Slide 21 text

アプリを動かしてみる on iOS SDK 13 ⌘+R

Slide 22

Slide 22 text

アプリを動かしてみる on iOS SDK 13

Slide 23

Slide 23 text

アプリを動かしてみる on iOS SDK 13 2019-09-22 17:26:41.737974+0900 Sansan[32738:933703] *** Terminating app due to uncaught exception 'RLMException', reason: 'Primary key property 'id' does not exist on object 'User''

Slide 24

Slide 24 text

Realm のプライマリーキープロパティがオブジェクトに存在しない v3.18.0 にて Xcode 11 での互換性が追加されていた コミットログを⾒るに Swift 5.1 で明⽰的に String 型の インスタンス変数名が設定されなくなったために、 Primary key property を String 型で定義していた場合に パースできず、例外が発⽣する模様 (User オブジェクトの id プロパティは String 型だった)

Slide 25

Slide 25 text

Realm のプライマリーキープロパティがオブジェクトに存在しない Cartfile --- - github "realm/realm-cocoa" == 3.15.0 + github "realm/realm-cocoa" == 3.18.0 carthage update --platform iOS --no-use-binaries ⌘+R

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Sansan アプリを iOS 13 上で実⾏出来るよう になった後に起こった問題

Slide 28

Slide 28 text

Modal on Modal でナビゲーション バーの初回表⽰が おかしくなる

Slide 29

Slide 29 text

Modal on Modal でナビゲーションバーの初回表⽰がおかしくなる 初回表⽰の View Hierarchy を⾒ると、 UINavigationBar の⾼さは 56 しかし、内部の _UIBarBackground や _UINavigationBarContentView の⾼さは 44 この両者の差分、 12 が余⽩となって表⽰されてしまう 2 回⽬以降はすべて 56 で同じ

Slide 30

Slide 30 text

Modal on Modal でナビゲーションバーの初回表⽰がおかしくなる 試してみたのは以下 UINavigationBar の BarTint と同じ⾊を Background に 設定して、ごまかす ナビゲーションバーの影がない場合にしか有効でない なんとか、初回のみ UINavigationBar の⾼さを変えられ ないか? カスタムしたナビゲーションバーを準備すれば、⾏けそ うだが、個別の OS 対応のみでそこまで出来ない… 結局、セミモーダルをやめる (従来通り)

Slide 31

Slide 31 text

Modal on Modal でナビゲーションバーの初回表⽰がおかしくなる - + 遷移元も遷移先もセミモーダルをやめると従来の表⽰と同等に

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

ログイン時の遷移 アニメーションが おかしい

Slide 34

Slide 34 text

ログイン時の遷移アニメーションがおかしい 検証した感じ、セミモーダル上での push 遷移のアニメーシ ョンがイケてない 出来そうな解決策は 3 つ セミモーダル上でも違和感のない push 遷移⽤のカスタム アニメーションを作る セミモーダルをやめる (従来通り) push 遷移のアニメーションを無効にして、セミモーダル の⾮表⽰アニメーションを活かす

Slide 35

Slide 35 text

ログイン時の遷移アニメーションがおかしい 検証した感じ、セミモーダル上での push 遷移のアニメーシ ョンがイケてない 出来そうな解決策は 3 つ セミモーダル上でも違和感のない push 遷移⽤のカスタム アニメーションを作る セミモーダルをやめる (従来通り) push 遷移のアニメーションを無効にして、セミモーダル の⾮表⽰アニメーションを活かす

Slide 36

Slide 36 text

セミモーダルをやめる (従来通り) router.viewController.modalTransitionStyle = .crossDissolve + router.viewController.modalPresentationStyle = .fullScreen

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

push 遷移のアニメーションを無効にして、セミモーダルの⾮表⽰ アニメーションを活かす - +

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

UINavigationBar.titleView に UISearchBar を設定した 場合に制約が効かなくなった

Slide 41

Slide 41 text

UINavigationBar.titleView に UISearchBar を設定した場合に 制約が効かなくなった 元々、 iOS 11 で UISearchBar の⾼さが 56 になり、 UINavigationBar の⾼さが⼦ビューに合わせて、 56 になった ことに対する対応として、以下のコードがあった if #available(iOS 11.0, *) { searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true }

Slide 42

Slide 42 text

UINavigationBar.titleView に UISearchBar を設定した場合に 制約が効かなくなった iOS 12 までは設定した制約が Intrinsic Content Size より 優先されていた iOS 13 から設定した制約より Intrinsic Content Size が優 先されるようになった

Slide 43

Slide 43 text

UINavigationBar.titleView に UISearchBar を設定した場合に 制約が効かなくなった ⾊々、試したが以前と同じく 44 を設定できたのは以下の⽅法 Intrinsic Content Size が設定されていない UIView でラップ UISearchBar の translatesAutoresizingMaskIntoConstraints を false にする UINavigationBar.titleView にはラップした UIView を設定 viewDidLayoutSubviews で制約を設定

Slide 44

Slide 44 text

UINavigationBar.titleView に UISearchBar を設定した場合に 制約が効かなくなった if #available(iOS 11.0, *) { searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true } navigationItem.titleView = searchBar + if #available(iOS 13.0, *) { + searchBar.translatesAutoresizingMaskIntoConstraints = false + titleView.addSubview(searchBar) + navigationItem.titleView = titleView + } 続く

Slide 45

Slide 45 text

+ override func viewDidLayoutSubviews() { + if #available(iOS 13.0, *) { + // 各 UI の幅取得は省略 :bow: + let titleViewWidth = navigationBarWidth - (leftBarButtonItemWidth + rightBarButtonItemWidth) + titleView.widthAnchor.constraint(equalToConstant: titleViewWidth).isActive = true + titleView.heightAnchor.constraint(equalTo: searchBar.heightAnchor).isActive = true + titleView.centerYAnchor.constraint(equalTo: searchBar.centerYAnchor).isActive = true + titleView.leadingAnchor.constraint(equalTo: searchBar.leadingAnchor).isActive = true + titleView.trailingAnchor.constraint(equalTo: searchBar.trailingAnchor).isActive = true + } + + super.viewDidLayoutSubviews() + }

Slide 46

Slide 46 text

UINavigationBar.titleView に UISearchBar を設定した 場合に制約が効かなくなった しんどい

Slide 47

Slide 47 text

まとめ

Slide 48

Slide 48 text

まとめ iOS 13 SDK でビルドと実⾏に成功するところまでは以前の iOS 12 SDK のアップデート時とそこまで変わらなかった 実際に iOS 13 SDK でビルドしたアプリを iOS 13 上で動か すと様々な問題が発⽣した すべての画⾯をテストできたわけではないので、まだある かも…

Slide 49

Slide 49 text

Sansan アプリからの学び iOS 13 SDK で変更のあったモーダル遷移をしている箇所と その画⾯からの遷移先までは⼀通り確認してみよう 個別バージョン対応している箇所は SDK のアップデートの 影響で動かなくなるかもしれないので、その部分も確認しよ う

Slide 50

Slide 50 text

No content