potatotips #55にiOSブログ枠として参加させていただきましたので、
iOSの発表内容をまとめました。
https://github.com/potatotips/potatotips/wiki/potatotips-55
私の知識が乏しく、
不足している箇所や間違いがある可能性がございますので、
何かご指摘があれば教えてください
iOS 11以降でUIViewControllerTransitionCoordinatorによるアニメーションが初回だけ効かない問題
発表者
スライド
参考資料
https://qiita.com/kazuhiro4949/items/e8df2a904cb994ce6ecc
https://github.com/kazuhiro4949/UIViewControllerTransitionCoordinatorBug
概要
UIViewControllerTransitionCoordinator
カスタムトランジションを書かなくても部分的なアニメーションがいい感じに実装できて便利。
だがiOS11以降では一部おかしな挙動を発見
画面遷移のアニメーションで起動後の最初の遷移でアニメーション後の状態が最初に表示されてしまう。
実はiOSのバグであったことが判明。
解決策
カスタムトランジションに処理をそのまま移して実行すると問題なく動く。
Embedded Unity
発表者
スライド
参考資料
概要
UnityのUI
ネイティブのUIではなく独自のUIで実装する。
UnityのUIをネイティブUIに組み込むのは大変
そこでUnityをネイティブアプリに埋め込む
UnityのiOSビルドの流れ
1. C#のコードをC#のコンパイラでマネージドアセンブリ化
2. 最適化
3. IL2CPPでC++のコードに変換
4. ClangでiOS用のバイナリへビルド
こうするとUnityのViewを引っ張ってくれば好きなところにUnityの画面を置ける
Embedded frameworkを作成する
- Unityから生成されたXcode用プロジェクトの.mmや.hファイルをほぼコピー(Unityの仕組みがよくわかっていないです...)
- framework外から使用するHeaderをPublicにする
- .xcconfigファイルを作ってプロジェクトの設定を書き換える(https://gist.github.com/tattn/d779acc86b7cd32996860f5fe97104c4)
- パスを変更したり、extern"C"などを追加する
※組み込む時は自動生成されたmain.mmを参考にすると良い
iOSとUnityのやりとり
UnitySendMessageでUnityにデータを送る
http://kan-kikuchi.hatenablog.com/entry/Safety_UnitySendMessage
iOS の HTTP キャッシュについて
発表者
スライド
概要
APIのレスポンスで更新内容がすぐには反映されない事象がありiOS側が疑われた。
そこでキャッシュについて色々調べてみた。
前提: キャッシュはパフォーマンス向上に必要
iOSでキャッシュを読み込まない方法
CachePolicyを変更
let configuration = URLSessionConfiguration.default
configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
※実は.reloadIgnoringLocalAndRemoteCacheDataは実装されていない
https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy/reloadignoringlocalandremotecachedata
CachePolicyの設定だけではキャッシュを読み込まないが💾保存はする💾
保存場所をシミュレータで確認してみると、
/Library/Developer/CoreSimulator/Devices/xxx/data/Containers/Data/Application/xxx/Library/Caches/(BundleID)
のcache.dbにあった
中身はSQLiteなのでツールで見ることができる
でも、読み込まれないなら良いのでは?
->もれたらまずい個人情報などは保存するべきではない
対策としてcapacityを0にする方法もあるがキャッシュを利用できるなくなりそう。
読み込みも保存もさせない方法
urlCacheをnilにする
let configuration = URLSessionConfiguration.default
configuration.urlCache = nil
.ephemeralを使用する
let configuration = URLSessionConfiguration.ephemeral
let session = URlSession(configuration: configuration)
しかし、既存のキャッシュは残っているので削除する方法を調べた。
キャッシュをすべて削除する方法(特定のキャッシュを消す方法はうまくいかなかった)
URLCache.shared.removeAllCachedResponses()
Pocochaにおけるアセットの管理
発表者
noppeさん
スライド
参考資料
https://github.com/noppefoxwolf/inaba
https://github.com/noppefoxwolf/AppIconGen
概要
今回の発表のアセットにはコードは含まれない。
画像や色やStoryboardなど。
Pocochaのアセット管理のルール
1. Asset Literalは使わない
Xcode上だと似たような画像や色が区別しづらい。
-> 名前を付けて呼び出すことがベスト。
-> 見た目と特徴で特定できる名前をつける + 共通で使用するものはCommonと頭に付ける
-> xcassetsのネームスペースを活用するとシンプルなファイル名でアクセスできる(ProfileEdit/Triangle/Largeなど)
2. 文字列でリソースは使わない
Typoするとランタイムでクラッシュする。
-> R.swiftやSwiftGenなどを使ってコンパイル時にTypoに気がつくようにする
3. Interface Builderで画像は設定しない
存在しない画像を設定してもビルドできてしまい、ランタイムでクラッシュする問題。
-> IBでは設定しないルールを設定
-> Inabaで確認する(上記参考資料を参照)
IBで画像を消すとAutoLayoutが壊れることがある
-> Intrinsic content sizeを設定する
4. アプリアイコンは単一ソースから生成
アプリアイコンはなぜかベクターpdfからラスタ画像をビルド時に自動生成してくれない
-> AppIconGenを活用する
5. ダミーアセットは明確にプロジェクトに分けて管理する
デバッグ用のアセットは隠しにくい。アプリにバンドルすると色々問題が出てくる可能性もある。
-> 機能ごとにターゲットを作成してターゲットごとのxcassetsを作成する
How to use Dictionary.compactMapValues
発表者
d_dateさん
スライド
参考資料
https://github.com/apple/swift-evolution/blob/master/proposals/0218-introduce-compact-map-values.md
https://speakerdeck.com/d_date/make-our-swift-better
概要
Dictionary.compactMapValuesがSwift5で導入される(作者は発表者のd_dateさん)
どうやって使うのか?
let d1 = ["a","1","b","2","c",nil]
d1.filter({ $0.value != nil}).mapValues({ $0! })
// ["b":"2","a":"1"](順番は任意)
これがこうなる↓
let d1 = ["a":"1","b":"2","c":nil]
d1.compactMapValues({ $0 })
// ["b":"2","a":"1"](順番は任意)
JavascriptのlodashのomitByを参考にしたとのこと
https://lodash.com/
http://tacamy.hatenablog.com/entry/2018/03/04/005938
どうやって使うのか?2
let d = ["a":"1","b":"2","c":"three"]
d.mapValues(Int.init).filter({ $0.value != nil}).mapValues({ $0! })
// ["b":2,"a":1](順番は任意)
これがこうなる↓
let d = ["a":"1","b":"2","c":"three"]
d.compactMapValues(Int.init)
// ["b":2,"a":1](順番は任意)
Swiftへのコントリビュート方法は下記を参照
Continuous Delivery With Unity Command line arguments
発表者
DayBySayさん
スライド
概要
Unityで開発中の話
「アプリの最新版を共有してほしい」との要望があり、
HockyApp経由でアップロードを行う。
Unityのビルド
すごい時間がかかる。
さらに、アップロード中にUnity Editorは触れない!!!
Xcodeのビルド
さらに1~2分かかる
悲劇
設定を間違えてしまった。。。
-> もう一度Unitiyのビルドからやり直し
そこで、Unityのビルド・配布の自動化
今回は社内サーバーのビルドマシン+Jenkinsで構成
Unity Player -> Xcode.projの吐き出し
Unity Command Line Argumentsを使用する
-executeMethod
ビルド起動前(Unity起動時)に処理を挟める
コマンドライン引数を受け取れる
Xcode.projの設定変更
fastlaneは事情により使えない
[PostProcessBuild]
Playerのビルド完了後に処理を挟める
AVPlayer周りの設計tips
発表者
スライド
参考資料
概要
AVPlayer周りのリファクタリング
方針
AVPlayerはUIとして捉えない
ViewControllerがAVPlayerを保持していると
コードが散らばったり、他のViewから参照する場合にViewControllerを経由しなければならない
そもそもAVPlayerってUIなのか?
AVPlayerの初期化や操作はメインスレッド必須は迷信
※ただしKVOの登録はメインスレッドの方が良いという記述あり
You can use Key-value observing (KVO)
to observe state changes
to many of the player’s dynamic properties,
such as its currentItem or its playback rate.
You should register and unregister
for KVO change notifications on the main thread.
加えて
サブスレッドの処理がメインスレッドの処理の後回しにされて動画視聴のUXを低下させる場合があるので要検証。
でも、UIに縛られる必要はないはず。
VideoPlayerManagerの導入
- UI層から分離したらすっきり
(RxSwiftを活用することでさらにすっきり) - 複数のクラスから共通のplayerの操作が可能になった
- Mockを使ってテストがやりやすくなった
Sourceryを使ってイベントログ実装を改善した話
発表者
スライド
参考資料
概要
イベントログをiOSに仕込む
元々の実装
- イベント名やパラメータ名をハードコーディング
- 型がAnyなのでなんでも入れられる
- 定義が散らばっていて迷子になる
これを改善しよう。
改善1
イベント名とパラメータにProtocolとenumを活用
結果
- 定義の集約と文字列ハードコーディングの削減
- 型推論を効かせて安全になった
Swiftらしい実装になったが、
イベント名とパラメータを毎回手で書くのは非常に大変
改善2
Sourceryによる自動生成
https://github.com/krzysztofzablocki/Sourcery
結果
200個くらいのボイラープレートの生成がSourceryを使って0.1-2秒でできるようになった