はじめに
今年も参加しました!iOSDC!
https://iosdc.jp/2021/
話題のSwift Concurrency、そして昨年に引き続きSwiftUI・Combine関連のトークも多く、とても学びの深いイベントでした。
どれも素晴らしいトークだったのですが、なかでも印象に残ったものをまとめていきたいと思います。
スライド画像多めに載せているので、ざーっと流し見するも良し、気になるものがあればURLから飛んで詳細を見るも良しです。
掲載トーク一覧
- 大規模リファクタリングの極意
- agoraを使ってライブ配信機能を1ヶ月半でリリースした話
- 振り返りながら学ぶPackage Manager
- 初めてのハードウェア対応
- Appleプライバシー保護の最新事情と適応戦略
- noteのiOSアプリで実装したアクセシビリティの全て
- Hello, Swift Concurrency world.
- ケースに応じたUICollectionViewのレイアウト実装パターン
- iOSアプリのセキュリティ基礎
Day0
大規模リファクタリングの極意
概要
- スライド:大規模リファクタリングの極意 - Speaker Deck
- プロポーザル:大規模リファクタリングの極意 by Yosuke Imairi | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
既存設計の限界や、技術的負債の返済に時間がとれないことが課題となっていた。
目的を明確にしたうえで、大規模リファクタリングに取り組むことにした。
ルーティング部分だけにRIBsアーキテクチャを適用することで、技術的負債の解消を目指した。
チームを分割して、専門チーム発足。
事業案件が忙しいときでも、なるべく駆り出されないように調整した。
リリースブロッカーにならないように注意した。
事業案件のロードマップ進捗に常に気を配り、PDMやQAと日頃からコミュニケーションを取ることで、リリースタイミングの調整をしやすくした。
リファクタリングのためのリファクタリングをおこなった。
その他、既存仕様や設計の理解を深めるためのコードリーディングなど、下準備を2ヶ月以上おこなったことで、本作業は滞りなく進んだ。
- 自動的に指定したバージョンのXcodeが開けるようにした
- CIによるベースブランチの自動マージ
- ボイラープレートの自動生成
ひとこと所感
情報のたくさん詰まった密度の濃い発表でした!自動化ツールを自作しちゃうのすごい…。
事業案件とは別に専門チームを作るあたりも納得感が強かったです。
agoraを使ってライブ配信機能を1ヶ月半でリリースした話
概要
- スライド:Game On – プレゼンテーション(16:9)、作成者:maiko morisaki
- プロポーザル:agoraを使ってライブ配信機能を1ヶ月半でリリースした話 by asa08 | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
Agoraとは、モバイル・PCアプリやWebサイトに、カスタマイズしたビデオ・音声通話やライブ配信を簡単に実装できるSDK。
Agoraをなぜ使う理由は以下2つ。(なるべくリソースをかけずにライブ配信機能を作りたかった)
- 早くリリースしてユーザーの反応・数字を見たかった(実験的機能だった)
- 人手不足
提供されているは機能9つあり、その中でもライブ配信機能にはInteractive Live Streaming
を使う。
クライアントはAgoraに認証するためのトークンを取得するため、自社サーバーからAgoraのAPIを叩く必要がある。
そのトークンを用いてagoraに接続する。
RTN = Real Time Network
RTC = Real Time Communication
ライブ配信を開始するにはチャンネルをまず作成する必要がある。
チャンネルとは配信の単位で、配信者はチャンネルを作成し、視聴者は各チャンネルに参加する形。
チャンネルを作成するために必要な情報は以下4つ。この情報をもとにRTCサーバーに認証して、チャンネルの作成・参加などをおこなう。
appId
channelName
uid
token
RTCサーバーに接続するために、appId
を使って、Engineの初期化をまずおこなう。
joinChannel
メソッドはチャンネルに参加するときに使う関数。
チャンネルに参加したときデリゲートメソッドに通知される。
チャンネルに参加すると、配信者は映像や音声を共有できて、リスナーは受け取ることができる。
ひとこと所感
個人的に気になっていたライブ配信を中心にまとめましたが、コメント機能や投げ銭機能についての説明もあって盛りだくさんのトークでした。
丁寧な解説のもと、Agoraを使ったライブ配信の実現方法について学ぶことができました!
振り返りながら学ぶPackage Manager
概要
- スライド:振り返りながら学ぶPackage Manager - Speaker Deck
- プロポーザル:振り返りながら学ぶPackage Manager by jollyjoester | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
CocoaPodsの概要。
ライブラリをバイナリで配布するのではなく、ソースコードで配布して、プロジェクトでビルドするという発想。
ライブラリはアプリのビルド時に一緒にビルドする。
Centralizedとは、Specsで中央管理してライブラリを探しやすくすること。
GitHubがそれほど浸透していなかった時代の名残かもしれない。
Carthageの概要。
Swiftが登場して間もなくの2014年に登場。CocoaPodsへのアンチテーゼが基本発想としてある。
アプリに組み込む前にビルドして使う or ビルド済みバイナリをダウンロードしてきて使う。
中央管理の仕組みはなく、各GitHubのリポジトリを使う(= Decentralized)。
Swift PMの概要。
Xcodeと統合されているので、マニュアルでの作業は不要。
標準なので「PackageManagerの対応待ち…」という事態がなくなる。
CocoaPodsの仕組み。
Pod install
されたら、podfileにしたがってSpecsを見に行く。
Specの記述からライブラリの置き場所(GitHubなど)を把握し、ソースをダウンロードしてPods
ディレクトリを生成。
どのライブラリのどのバージョンをダウンロードしたのかをPodfile.lockに記載(環境再現のために重要)。
Pods
ディレクトリ内のファイルはPods.xcodeprojで管理され、アプリ本体のプロジェクトと紐付けられる。
Xcworkspaceで2つのプロジェクトをまとめて完成!
ライブラリをソースコードとして取り込むため、アプリのビルド時にライブラリもビルドされる。
一度ビルドされたものはキャッシュされるが、クリーンビルドなどでは再度ビルドされる。
アプリの規模が大きくなると、ビルド時間が長くなるという問題を引き起こす。
Carthageの仕組み。
Cartfileを書いてコマンド叩くとライブラリが生成されるので、そのファイルをマニュアルでXcodeprojに紐付ける。
(裏でやっていること)
コマンドを叩くとソースコードのある場所(GitHubなど)からソースコードがダウンロードされ、Carthage
ディレクトリ配下のcheckouts
ディレクトリに格納される。
同時にCartfile.resolvedが生成される。
ソースコードをもとにライブラリがビルドされ、Build
ディレクトリに格納される。
Build
ディレクトリ以下に生成されたファイルをプロジェクトにマニュアルで紐付ける。
最初にライブラリをビルドするのは時間がかかるが、その分アプリのビルドは早くなる。
シンプルな分、理解がないと適切な運用が難しい。
-
--platform iOS
を指定しないと、他のプラットフォーム向けのビルドも作成されてしまうので時間がかかる -
--use-xcframeworks
を指定しないと、マニュアルでやらないといけないことが増えてしまう
Swift PMの仕組み。
XcodeのプロジェクトにSwift Packages
という項目があるので、リポジトリのURLとバージョンを指定するとダウンロードされて使えるようになる。
動きはCarthageと似ていて、ライブラリの置き場(GitHubなど)からソースコードがダウンロードされ、すぐビルドされる。
DerivedData
配下のBuild
やSourcePackage
ディレクトリに格納される。
マニュアルな作業なしにプロジェクトに自動でリンクされる。標準バンザーイ!
ひとこと所感
3つとも使ってはいたけれど、裏側まで詳しく理解できていなかったので勉強になりました。
易しい説明のもと、それぞれを比較しながら見ていくことができて大変わかりやすかったです!
Day1
初めてのハードウェア対応
概要
- スライド:初めてのハードウェア対応 - Speaker Deck
- プロポーザル:初めてのハードウェア対応 by Takeshi Yokokoji | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
実店舗での会計の流れには様々なハードウェアが必要で、たくさんのハードウェア対応をおこなった。
Bluetoothの規格によって実装が異なっている。
Bluetooth Low Energy
(BLE)は、3系以前に比べて省電力の通信ができるのが特徴。
Core Bluetooth Framework
を利用して実装する。
BLEの規格では、以下2つの概念に分かれていて、Core Bluetooth Framework
を使う上で大事になってくる。
- peripheralの情報をスキャンして接続する
Central
(iPhone) - 自分のデータをブロードキャストする
Peripheral
(プリンターなど)
Peripheralの中にはService
(機能)と、Characteristic
(特徴)という概念が含まれている。
検出されたPerifheral情報を取得 → デバイスに接続 → デバイスにデータ送信、という流れで実装。
Bluetooth Classic
は、Bluetooth 3.0以前の規格で、External Accessory Framework
を使って実装する。
Info.plistをいじったり、MFi申請する必要もあってちょっと面倒。
(MFi登録申請とは、メーカーがiOSに対応したハードウェアを製造するときにAppleからの認証を通過する必要があり、その申請のこと)
苦労した点としては、同じメーカーでも一部の端末で挙動が異なる場合があり、調査が難しかったこと。
また、リモートワークでハードウェア対応しようとしたところ、自宅にハードウェアブース(+レシートの山)ができてしまったりもした。
ひとこと所感
Bluetooth系のFrameworkは全く触ったことがないので新鮮でした(こういう新しい世界を気軽に垣間見ることができるのもiOSDCの楽しみの一つですよね〜)。
Bluetooth接続してるデバイスがどういう仕組みで動いているのかがなんとなくイメージできるようになりました!
Appleプライバシー保護の最新事情と適応戦略
概要
- スライド:Appleプライバシー保護の最新事情と適応戦略/Apple privacy - Speaker Deck
- プロポーザル:Appleプライバシー保護の最新事情と適応戦略 by Terasaka | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
近年のプライバシー関連アップデート。なかでもATTは今年適用されて話題になった。
WWDC2021のプライバシー関連アップデートの中から、業界に対して影響の大きそうな2つ。
トラッキング規制が強まる中で、ユーザーのリテラシーが上がり、プライバシーの重要性が増してきている。
プライバシーに配慮できているかが、サービスの信頼性の基準になっていく。
Appleは「プライバシーは、基本的人権です」と言い切っており、プライバシーはAppleの中心にある理念の一つ。
大事なことを大事だと言い切る姿勢に、彼らの覚悟を感じる。
そんなAppleはプライバシーをどう保護しているのか。
今年のWWDCでも発表のあった「プライバシー保護の4原則」がある。
1つめは「データ最小化」。
データが増えれば増えるほどユーザーの輪郭が見えてきて、攻撃されやすくもなる。
データを持つことはリスク。目的に応じて最小限だけ取得すること。
2つめは「オンデバイス処理」。
データは動かせば動かすほどリクスが上がるので、なるべく端末の中で処理して、外に持ち出さないようにすること。
もし持ち出す場合は、端末の中でデータを要約処理してから持ち出すこと。
3つめは「透明性とコントロール」。
見えないところで情報を収集するのはNGで、理由を明示してユーザーに選択肢を与えること。
伝わらなければ意味がないので、わかりやすい言葉で。
当然、サードパーティ製ツールが利用するデータも把握する必要ある。
最後は「セキュリティ保護」。
預かったデータは安全に取り扱う責任がある。通信の暗号化や保存データの暗号化も大事。
ひとこと所感
普段はどうしても目新しい機能に目が行きがちで、(大事であるとはわかっていながらも)セキュリティについてじっくり向き合うタイミングがなかったので、有り難いトークでした。
「プライバシー保護の4原則」、意識していきたいです。
noteのiOSアプリで実装したアクセシビリティの全て
概要
- 資料:noteのiOSアプリで実装したアクセシビリティの全て(文字起こし) #iosdc #a|かっくん / iOS Developer
- プロポーザル:noteのiOSアプリで実装したアクセシビリティの全て by かっくん | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:https://www.youtube.com/watch?v=rDX_tJ7t28M
内容(抜粋)
アクセシビリティは障害者や高齢者向けの対応と思われがちだが、全人類が情報に触れたり機能を体験できることを目指している。
ユーザービリティはアクセシビリティが保たれた上で意識したい。
そもそもアクセスできなければ利用すらできないため。
盲目の方へのインタビューを実施した際、実際に動く様子を見せてもらうと「バグやん…」と思った。
アクセシビリティ向上を掲げてもなかなかタスクは進みづらいと思うが、バグ修正というタスクに分解すれば自ずと優先度が上がるのではないか。
実際に発生した問題の一つとして、「タップジェスチャーが設定されているviewが選択できないという問題」があった。
ただのUIViewはisAccessibilityElement
がデフォルトでfalse
になっているため、true
にしてあげることで解決した。
更に体験を向上する施策として、「何か動作をしたら用意したテキストを読み上げる方法」を紹介。
UIAccessibility
のpost
メソッドに .announcement
を設定してテキストを渡すだけでOK。
次は「日付の読み上げを自然にする方法」。
dateFormatter
でyyyy/MM/dd
を指定すると、区切り部分が「すらっしゅ」と読み上げれらてしまう。
フォーマットを指定せずにdateStyle
とtimeStyle
を指定したアクセシビリティ用のdateFormatter
を別途用意して、accessibilityLabel
に設定するとうまくいった。
アクセシビリティの設定を確認するためのTips。
音声コントロールを有効にしてオーバーレイの設定を項目名にすることで設定済みのラベルを可視化することができる。
VoiceOver実際に使わなくてもラベルの確認ができて便利。
アクセシビリティの向上は突き詰めようと思うとどこまでもできてしまう。
実際に利用している人が困っている点を改善するのが大事なので、定期的にユーザーインタビューを実施したりアンケートを取ったりして、利用者の声を拾い上げていく仕組みづくりをしていきたい。
ひとこと所感
アクセシビリティ対応をするうえでのTipsが盛りだくさんのトークでした。ここまでできてるnote社すごい!
動画だと断然わかりやすいので、気になる方はYoutubeを見てもらうと良いと思います。
Day2
Hello, Swift Concurrency world.
概要
- スライド:Hello, Swift Concurrency world. - Speaker Deck
- プロポーザル:Hello, Swift Concurrency world. by shiz | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
Swift Concurrencyとは、非同期処理や同時並行処理を、わかりやすく、安全に書くための言語機能。
パフォーマンスの最適化も目指している。
Async/awaitは、非同期処理を、同期処理と同じような方法で、より読みやすく、より正確に書けるようにした新しい構文。
コールバックはネストが深く読みづらく、処理の流れが複雑で、Completionを手動で実行する必要もある(呼び忘れのリスク)。
一方、Async/awaitだとネストが減り、上から下に自然な流れで処理が行われ、コンパイラが処理の戻し忘れを検出してくれる。
async
キーワードをつけることで、処理の途中でsuspend(=中断)する可能性をコンパイラに伝える。
結果が返ってくると処理をresume(=再開)する(await前と同じスレッドでresumeされるわけではないので注意!)。
パフォーマンスの向上についてスレッドモデルから見ていく。
GCDはどんどんとスレッドを生成するので、メモリオーバーヘッドやスケジューリングオーバーヘッドなどの「Thread Explosion」を引き起こす可能性がある。
一方、Swift Concurrencyは固定数のスレッドを持ち、強調スレッドプールという仕組みでスレッドを再利用するので、必要以上にスレッドが生成されることがなく安全。
Actorとは参照型のデータ型で、struct、enum、classに近い機能を持っている。
一度に一つの処理のみをおこなうことで、複数のThreadからの同時アクセス(データ競合)を防いでいる。
class
の代わりにactor
を使って定義し、Actorの外からアクセスするにはawait
を付ける。
MainActorとは、メインスレッドで処理を実行するActor。@MainActor
を付ける。
メインスレッドの外からコードを呼び出す場合は、await
をつけて呼び出す必要がある。
メインスレッドで実行する必要のある処理の場合、DispatchQueueだと実行時まで気づかないこともあるが、MainActorを使うとコンパイル時にチェックされるので、後から変更した場合のリスクが減る。
ひとこと所感
スライドが205枚(!)とすごい情報量で、ここではかいつまんでのまとめとなってしまいました…。
今後ごく一般的な機能になってくると思うので、何度か見返して理解したいと思います!
ケースに応じたUICollectionViewのレイアウト実装パターン
概要
- スライド:ケースに応じたUICollectionViewのレイアウト実装パターン - Speaker Deck
- プロポーザル:ケースに応じたUICollectionViewのレイアウト実装パターン by to4iki | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
4つそれぞれに特徴があり、要件を満たすためにどの実装を選択すべきか悩ましい。
UICollectionViewFlowLayout
について。
縦横にコンテンツを均等配置するシンプルなレイアウト。
簡単に設定が可能だが、セクションごとやアイテムの位置に応じた動的にレイアウト変更はできない。
固定のレイアウトを組む場合に使用すると良い。
UICollectionViewDelegateFlowLayout
について。
IndexPathを参照可能のため、アイテムやセクションごとにサイズを変更することができる。
アニメーションを伴う変更や、アイテム同士のサイズを比較しておこなう変更など複雑なレイアウトは苦手。
UICollectionViewLayout
を継承したCustomレイアウトについて。
アイテム同士のの比較など、レイアウトを頻繁に更新するケースで利用する。
柔軟なレイアウトが組める反面、パフォーマンス面の考慮も必要で難易度は高め。
(CompositionalLayoutを使えば簡単に実現できたりもする)
UICollectionViewCompositionalLayout
について。
iOS13以上で使える。
Item
とSection
の間に新たなGroup
という概念が加わった。
Group
は入れ子構造が可能で、複雑なレイアウト構成を表現できる。
IndexPathにはアクセスできないので、データにアクセスして動的にサイズを変更するのは苦手。
UICollectionViewCompositionalLayout
+ DiffableDataSource
の実装例を紹介。
ViewControllerは渡されたデータ構造をただ表示するだけで、「表示モデル = 画面そのもの」の直感的な実装ができる。
DiffableDataSource
について。
差分更新が特徴で、データとUIの不整合を型レベルで担保している。
ひとこと所感
各サブクラスの得意/不得意が分かりやすくまとまっていて良かったです。
UICollectionViewCompositionalLayout
やDiffableDataSource
を使うシーンも増えてくると思うので、ちゃんとキャッチアップしていかないとなーと思いました!
iOSアプリのセキュリティ基礎
概要
- スライド:iOSアプリのセキュリティ基礎 - Speaker Deck
- プロポーザル:iOSアプリのセキュリティ基礎 by saten | トーク | iOSDC Japan 2021 #iosdc - fortee.jp
- Youtube動画:公開待ち
内容(抜粋)
http/https通信をする上でのセキュリティとして、iOSではATSがある。
Info.plistから強度が設定できるが、丸ごと無効化したりせず、できるだけデフォルトのASTに近い状態で動作するようにすることが大切。
URLスキームの脆弱性について。
同じURLスキームを受け取るアプリをリリースすることが可能。
先にインストールしているアプリが受け取るので、もし攻撃者のアプリを先にインストールしていたら、攻撃者に大事なデータが渡ってしまう。
どのアプリにどのURLスキームが実装されているかはツールなどを利用すれば誰でもわかること。
対策の一つがUniversalLinksを使うこと。
攻撃者はドメインを奪うことは難しく、そのドメインに紐づくアプリを作ることはできない。
URLスキームよりもデータを奪われる可能性が低く安全。
対策の2つ目として、外部ブラウザでの認証などの場合、外部ブラウザではなくSFsafariViewControllerなどを使ってアプリ内でブラウザを開くこと。
ブラウザ内でURLスキームが生じた場合、先にインストールしたアプリではなく、アプリ内ブラウザを開いているアプリが優先してURLスキームを受け取るため安全。
また、URLスキームではセキュリティ上漏洩になるような重要なデータを渡さないことも大切。
重要情報をローカルのどこに保存すべきか?については、Keychainに保存することを推奨。
Realm上のデータもKeychainに鍵を入れておくことによって守ることができる。
アプリをリバースエンジニアリングされる可能性があるので、ソースコード内に重要情報をハードコーディングするのは避けるべき。
認証の仕組みについて、代表的なものはこの3つ。攻撃例と対応策は以下。
- CSRFにはstateパラーメーターの付与で対応
- id-tokenの改ざんはデジダル署名検証で対応
- リプレイアタックにはnonceパラメーターの付与で対応
OAuthやOpenID Connectを利用するときは、独自の実装ではなくできるだけ標準の仕様に則った実装にすること。
また、脆弱性を理解して、OAuthやOpenID Connectに則った検証をちゃんとすること。
ログインできればいいというものではない。
ひとこと所感
セキュリティについて基礎から説明してくださっていて、誰にでもわかりやすいトークだったと思います。
「脆弱性はいつも近くに潜んでいる」ということを胸に刻んで実装していきたいですね!
おわりに
今回もまた大作になってしまいました
(トーク見ながら記事に起こすのはわりとハードで、3日間におよぶ自分との戦いに勝った気分です )
ここまで見てくださった方、ありがとうございました!
※昨年の記事はこちら →iOSDC 2020 印象に残ったトークまとめ🎉 - Qiita