Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
23
Help us understand the problem. What are the problem?

iOSDC 2021 印象に残ったトークまとめ🎉

はじめに

今年も参加しました!iOSDC!:tada:
https://iosdc.jp/2021/
話題のSwift Concurrency、そして昨年に引き続きSwiftUI・Combine関連のトークも多く、とても学びの深いイベントでした。

どれも素晴らしいトークだったのですが、なかでも印象に残ったものをまとめていきたいと思います。
スライド画像多めに載せているので、ざーっと流し見するも良し、気になるものがあればURLから飛んで詳細を見るも良しです。

この記事が、少しでも誰かのお役に立てば幸いです:grin:
スクリーンショット 2021-09-17 17.08.44.png

掲載トーク一覧

Day0

大規模リファクタリングの極意

概要

内容(抜粋)

スクリーンショット 2021-09-18 9.25.13.png

既存設計の限界や、技術的負債の返済に時間がとれないことが課題となっていた。
目的を明確にしたうえで、大規模リファクタリングに取り組むことにした。

スクリーンショット 2021-09-18 9.26.07.png
ルーティング部分だけにRIBsアーキテクチャを適用することで、技術的負債の解消を目指した。

スクリーンショット 2021-09-18 9.26.18.png
チームを分割して、専門チーム発足。
事業案件が忙しいときでも、なるべく駆り出されないように調整した。

スクリーンショット 2021-09-18 9.26.32.png
リリースブロッカーにならないように注意した。
事業案件のロードマップ進捗に常に気を配り、PDMやQAと日頃からコミュニケーションを取ることで、リリースタイミングの調整をしやすくした。

スクリーンショット 2021-09-18 9.26.45.png
スクリーンショット 2021-09-18 9.26.52.png
リファクタリングのためのリファクタリングをおこなった。
その他、既存仕様や設計の理解を深めるためのコードリーディングなど、下準備を2ヶ月以上おこなったことで、本作業は滞りなく進んだ。

スクリーンショット 2021-09-18 9.27.21.png
実装時間を増やすために、どんどん自動化を進めた。

  • 自動的に指定したバージョンのXcodeが開けるようにした
  • CIによるベースブランチの自動マージ
  • ボイラープレートの自動生成

スクリーンショット 2021-09-18 9.27.30.png
技術的負債に打ち勝ち、安心安全な開発を取り戻した👏

ひとこと所感

情報のたくさん詰まった密度の濃い発表でした!自動化ツールを自作しちゃうのすごい…。
事業案件とは別に専門チームを作るあたりも納得感が強かったです。

agoraを使ってライブ配信機能を1ヶ月半でリリースした話

概要

内容(抜粋)

スクリーンショット 2021-09-18 22.24.25.png
Agoraとは、モバイル・PCアプリやWebサイトに、カスタマイズしたビデオ・音声通話やライブ配信を簡単に実装できるSDK。
Agoraをなぜ使う理由は以下2つ。(なるべくリソースをかけずにライブ配信機能を作りたかった)

  • 早くリリースしてユーザーの反応・数字を見たかった(実験的機能だった)
  • 人手不足

スクリーンショット 2021-09-18 22.24.46.png
提供されているは機能9つあり、その中でもライブ配信機能にはInteractive Live Streamingを使う。

スクリーンショット 2021-09-18 22.25.18.png
クライアントはAgoraに認証するためのトークンを取得するため、自社サーバーからAgoraのAPIを叩く必要がある。
そのトークンを用いてagoraに接続する。
RTN = Real Time Network
RTC = Real Time Communication

スクリーンショット 2021-09-18 22.25.39.png
ライブ配信を開始するにはチャンネルをまず作成する必要がある。
チャンネルとは配信の単位で、配信者はチャンネルを作成し、視聴者は各チャンネルに参加する形。

チャンネルを作成するために必要な情報は以下4つ。この情報をもとにRTCサーバーに認証して、チャンネルの作成・参加などをおこなう。

  • appId
  • channelName
  • uid
  • token

スクリーンショット 2021-09-18 22.25.49.png
RTCサーバーに接続するために、appIdを使って、Engineの初期化をまずおこなう。
joinChannelメソッドはチャンネルに参加するときに使う関数。
チャンネルに参加したときデリゲートメソッドに通知される。

チャンネルに参加すると、配信者は映像や音声を共有できて、リスナーは受け取ることができる。

ひとこと所感

個人的に気になっていたライブ配信を中心にまとめましたが、コメント機能や投げ銭機能についての説明もあって盛りだくさんのトークでした。
丁寧な解説のもと、Agoraを使ったライブ配信の実現方法について学ぶことができました!

振り返りながら学ぶPackage Manager

概要

内容(抜粋)

スクリーンショット 2021-09-18 10.24.05.png
CocoaPodsの概要。
ライブラリをバイナリで配布するのではなく、ソースコードで配布して、プロジェクトでビルドするという発想。
ライブラリはアプリのビルド時に一緒にビルドする。
Centralizedとは、Specsで中央管理してライブラリを探しやすくすること。
GitHubがそれほど浸透していなかった時代の名残かもしれない。

スクリーンショット 2021-09-18 10.25.48.png
Carthageの概要。
Swiftが登場して間もなくの2014年に登場。CocoaPodsへのアンチテーゼが基本発想としてある。
アプリに組み込む前にビルドして使う or ビルド済みバイナリをダウンロードしてきて使う。
中央管理の仕組みはなく、各GitHubのリポジトリを使う(= Decentralized)。

スクリーンショット 2021-09-18 10.25.55.png
Swift PMの概要。
Xcodeと統合されているので、マニュアルでの作業は不要。
標準なので「PackageManagerの対応待ち…」という事態がなくなる。

スクリーンショット 2021-09-18 10.41.37.png
CocoaPodsの仕組み。
Pod installされたら、podfileにしたがってSpecsを見に行く。
Specの記述からライブラリの置き場所(GitHubなど)を把握し、ソースをダウンロードしてPodsディレクトリを生成。
どのライブラリのどのバージョンをダウンロードしたのかをPodfile.lockに記載(環境再現のために重要)。
Podsディレクトリ内のファイルはPods.xcodeprojで管理され、アプリ本体のプロジェクトと紐付けられる。
Xcworkspaceで2つのプロジェクトをまとめて完成!

ライブラリをソースコードとして取り込むため、アプリのビルド時にライブラリもビルドされる。
一度ビルドされたものはキャッシュされるが、クリーンビルドなどでは再度ビルドされる。
アプリの規模が大きくなると、ビルド時間が長くなるという問題を引き起こす。

スクリーンショット 2021-09-18 12.42.49.png
Carthageの仕組み。
Cartfileを書いてコマンド叩くとライブラリが生成されるので、そのファイルをマニュアルでXcodeprojに紐付ける。

(裏でやっていること)
コマンドを叩くとソースコードのある場所(GitHubなど)からソースコードがダウンロードされ、Carthageディレクトリ配下のcheckoutsディレクトリに格納される。
同時にCartfile.resolvedが生成される。
ソースコードをもとにライブラリがビルドされ、Buildディレクトリに格納される。
Buildディレクトリ以下に生成されたファイルをプロジェクトにマニュアルで紐付ける。

最初にライブラリをビルドするのは時間がかかるが、その分アプリのビルドは早くなる。
シンプルな分、理解がないと適切な運用が難しい。
* --platform iOS を指定しないと、他のプラットフォーム向けのビルドも作成されてしまうので時間がかかる
* --use-xcframeworks を指定しないと、マニュアルでやらないといけないことが増えてしまう

スクリーンショット 2021-09-18 12.53.03.png
Swift PMの仕組み。
XcodeのプロジェクトにSwift Packagesという項目があるので、リポジトリのURLとバージョンを指定するとダウンロードされて使えるようになる。

動きはCarthageと似ていて、ライブラリの置き場(GitHubなど)からソースコードがダウンロードされ、すぐビルドされる。
DerivedData配下のBuildSourcePackageディレクトリに格納される。
マニュアルな作業なしにプロジェクトに自動でリンクされる。標準バンザーイ!

ひとこと所感

3つとも使ってはいたけれど、裏側まで詳しく理解できていなかったので勉強になりました。
易しい説明のもと、それぞれを比較しながら見ていくことができて大変わかりやすかったです!

Day1

初めてのハードウェア対応

概要

内容(抜粋)

スクリーンショット 2021-09-18 13.14.26.png
実店舗での会計の流れには様々なハードウェアが必要で、たくさんのハードウェア対応をおこなった。
Bluetoothの規格によって実装が異なっている。

スクリーンショット 2021-09-18 14.08.33.png
Bluetooth Low Energy(BLE)は、3系以前に比べて省電力の通信ができるのが特徴。
Core Bluetooth Frameworkを利用して実装する。

スクリーンショット 2021-09-18 14.08.44.png
BLEの規格では、以下2つの概念に分かれていて、Core Bluetooth Frameworkを使う上で大事になってくる。
* peripheralの情報をスキャンして接続するCentral(iPhone)
* 自分のデータをブロードキャストするPeripheral(プリンターなど)
Peripheralの中にはService(機能)と、Characteristic(特徴)という概念が含まれている。

スクリーンショット 2021-09-18 17.54.33.png
デバイスの仕様に関する情報を、静的情報として持っておく。

スクリーンショット 2021-09-18 17.56.11.png
検出されたPerifheral情報を取得 → デバイスに接続 → デバイスにデータ送信、という流れで実装。

スクリーンショット 2021-09-18 18.00.44.png
Bluetooth Classicは、Bluetooth 3.0以前の規格で、External Accessory Frameworkを使って実装する。
Info.plistをいじったり、MFi申請する必要もあってちょっと面倒。
(MFi登録申請とは、メーカーがiOSに対応したハードウェアを製造するときにAppleからの認証を通過する必要があり、その申請のこと)

スクリーンショット 2021-09-19 10.13.20.png
苦労した点としては、同じメーカーでも一部の端末で挙動が異なる場合があり、調査が難しかったこと。
また、リモートワークでハードウェア対応しようとしたところ、自宅にハードウェアブース(+レシートの山)ができてしまったりもした。

ひとこと所感

Bluetooth系のFrameworkは全く触ったことがないので新鮮でした(こういう新しい世界を気軽に垣間見ることができるのもiOSDCの楽しみの一つですよね〜)。
Bluetooth接続してるデバイスがどういう仕組みで動いているのかがなんとなくイメージできるようになりました!

Appleプライバシー保護の最新事情と適応戦略

概要

内容(抜粋)

スクリーンショット 2021-09-18 18.31.57.png
近年のプライバシー関連アップデート。なかでもATTは今年適用されて話題になった。

スクリーンショット 2021-09-18 18.33.54.png
WWDC2021のプライバシー関連アップデートの中から、業界に対して影響の大きそうな2つ。
トラッキング規制が強まる中で、ユーザーのリテラシーが上がり、プライバシーの重要性が増してきている。
プライバシーに配慮できているかが、サービスの信頼性の基準になっていく。

スクリーンショット 2021-09-18 18.39.56.png
Appleは「プライバシーは、基本的人権です」と言い切っており、プライバシーはAppleの中心にある理念の一つ。
大事なことを大事だと言い切る姿勢に、彼らの覚悟を感じる。

スクリーンショット 2021-09-18 18.42.23.png
そんなAppleはプライバシーをどう保護しているのか。
今年のWWDCでも発表のあった「プライバシー保護の4原則」がある。

スクリーンショット 2021-09-18 18.43.38.png
1つめは「データ最小化」。
データが増えれば増えるほどユーザーの輪郭が見えてきて、攻撃されやすくもなる。
データを持つことはリスク。目的に応じて最小限だけ取得すること。

スクリーンショット 2021-09-18 18.45.14.png
2つめは「オンデバイス処理」。
データは動かせば動かすほどリクスが上がるので、なるべく端末の中で処理して、外に持ち出さないようにすること。
もし持ち出す場合は、端末の中でデータを要約処理してから持ち出すこと。

スクリーンショット 2021-09-18 18.45.25.png
3つめは「透明性とコントロール」。
見えないところで情報を収集するのはNGで、理由を明示してユーザーに選択肢を与えること。
伝わらなければ意味がないので、わかりやすい言葉で。
当然、サードパーティ製ツールが利用するデータも把握する必要ある。

スクリーンショット 2021-09-18 18.45.34.png
最後は「セキュリティ保護」。
預かったデータは安全に取り扱う責任がある。通信の暗号化や保存データの暗号化も大事。

ひとこと所感

普段はどうしても目新しい機能に目が行きがちで、(大事であるとはわかっていながらも)セキュリティについてじっくり向き合うタイミングがなかったので、有り難いトークでした。
「プライバシー保護の4原則」、意識していきたいです。

noteのiOSアプリで実装したアクセシビリティの全て

概要

内容(抜粋)

スクリーンショット 2021-09-18 19.31.11.png
アクセシビリティは障害者や高齢者向けの対応と思われがちだが、全人類が情報に触れたり機能を体験できることを目指している。

スクリーンショット 2021-09-18 19.33.36.png
ユーザービリティはアクセシビリティが保たれた上で意識したい。
そもそもアクセスできなければ利用すらできないため。

スクリーンショット 2021-09-18 19.38.32.png
盲目の方へのインタビューを実施した際、実際に動く様子を見せてもらうと「バグやん…」と思った。
アクセシビリティ向上を掲げてもなかなかタスクは進みづらいと思うが、バグ修正というタスクに分解すれば自ずと優先度が上がるのではないか。

スクリーンショット 2021-09-18 19.46.10.png
実際に発生した問題の一つとして、「タップジェスチャーが設定されているviewが選択できないという問題」があった。
ただのUIViewはisAccessibilityElementがデフォルトでfalseになっているため、trueにしてあげることで解決した。

スクリーンショット 2021-09-18 20.55.11.png
更に体験を向上する施策として、「何か動作をしたら用意したテキストを読み上げる方法」を紹介。
UIAccessibilitypostメソッドに .announcementを設定してテキストを渡すだけでOK。

スクリーンショット 2021-09-18 21.07.09.png
次は「日付の読み上げを自然にする方法」。
dateFormatteryyyy/MM/ddを指定すると、区切り部分が「すらっしゅ」と読み上げれらてしまう。
フォーマットを指定せずにdateStyletimeStyleを指定したアクセシビリティ用のdateFormatterを別途用意して、accessibilityLabel に設定するとうまくいった。

スクリーンショット 2021-09-18 21.11.09.png
アクセシビリティの設定を確認するためのTips。
音声コントロールを有効にしてオーバーレイの設定を項目名にすることで設定済みのラベルを可視化することができる。
VoiceOver実際に使わなくてもラベルの確認ができて便利。

スクリーンショット 2021-09-18 21.13.00.png
アクセシビリティの向上は突き詰めようと思うとどこまでもできてしまう。
実際に利用している人が困っている点を改善するのが大事なので、定期的にユーザーインタビューを実施したりアンケートを取ったりして、利用者の声を拾い上げていく仕組みづくりをしていきたい。

ひとこと所感

アクセシビリティ対応をするうえでのTipsが盛りだくさんのトークでした。ここまでできてるnote社すごい!
動画だと断然わかりやすいので、気になる方はYoutubeを見てもらうと良いと思います。

Day2

Hello, Swift Concurrency world.

概要

内容(抜粋)

スクリーンショット 2021-09-19 12.18.30.png
Swift Concurrencyとは、非同期処理や同時並行処理を、わかりやすく、安全に書くための言語機能。
パフォーマンスの最適化も目指している。

スクリーンショット 2021-09-19 13.45.36.png
Async/awaitは、非同期処理を、同期処理と同じような方法で、より読みやすく、より正確に書けるようにした新しい構文。

スクリーンショット 2021-09-19 12.24.14.png
コールバックはネストが深く読みづらく、処理の流れが複雑で、Completionを手動で実行する必要もある(呼び忘れのリスク)。
一方、Async/awaitだとネストが減り、上から下に自然な流れで処理が行われ、コンパイラが処理の戻し忘れを検出してくれる。

asyncキーワードをつけることで、処理の途中でsuspend(=中断)する可能性をコンパイラに伝える。
結果が返ってくると処理をresume(=再開)する(await前と同じスレッドでresumeされるわけではないので注意!)。

スクリーンショット 2021-09-19 12.36.09.png
パフォーマンスの向上についてスレッドモデルから見ていく。
GCDはどんどんとスレッドを生成するので、メモリオーバーヘッドやスケジューリングオーバーヘッドなどの「Thread Explosion」を引き起こす可能性がある。
一方、Swift Concurrencyは固定数のスレッドを持ち、強調スレッドプールという仕組みでスレッドを再利用するので、必要以上にスレッドが生成されることがなく安全。

スクリーンショット 2021-09-19 12.51.25.png
スクリーンショット 2021-09-19 12.51.34.png
Actorとは参照型のデータ型で、struct、enum、classに近い機能を持っている。
一度に一つの処理のみをおこなうことで、複数のThreadからの同時アクセス(データ競合)を防いでいる。
classの代わりにactorを使って定義し、Actorの外からアクセスするにはawaitを付ける。

スクリーンショット 2021-09-19 13.02.20.png
MainActorとは、メインスレッドで処理を実行するActor。@MainActorを付ける。
メインスレッドの外からコードを呼び出す場合は、awaitをつけて呼び出す必要がある。
メインスレッドで実行する必要のある処理の場合、DispatchQueueだと実行時まで気づかないこともあるが、MainActorを使うとコンパイル時にチェックされるので、後から変更した場合のリスクが減る。

ひとこと所感

スライドが205枚(!)とすごい情報量で、ここではかいつまんでのまとめとなってしまいました…。
今後ごく一般的な機能になってくると思うので、何度か見返して理解したいと思います!

ケースに応じたUICollectionViewのレイアウト実装パターン

概要

内容(抜粋)

スクリーンショット 2021-09-19 14.20.26.png
4つそれぞれに特徴があり、要件を満たすためにどの実装を選択すべきか悩ましい。

スクリーンショット 2021-09-19 14.45.02.png
UICollectionViewFlowLayoutについて。
縦横にコンテンツを均等配置するシンプルなレイアウト。
簡単に設定が可能だが、セクションごとやアイテムの位置に応じた動的にレイアウト変更はできない。
固定のレイアウトを組む場合に使用すると良い。

スクリーンショット 2021-09-19 14.45.47.png
UICollectionViewDelegateFlowLayoutについて。
IndexPathを参照可能のため、アイテムやセクションごとにサイズを変更することができる。
アニメーションを伴う変更や、アイテム同士のサイズを比較しておこなう変更など複雑なレイアウトは苦手。

スクリーンショット 2021-09-19 14.45.58.png
UICollectionViewLayoutを継承したCustomレイアウトについて。
アイテム同士のの比較など、レイアウトを頻繁に更新するケースで利用する。
柔軟なレイアウトが組める反面、パフォーマンス面の考慮も必要で難易度は高め。
(CompositionalLayoutを使えば簡単に実現できたりもする)

スクリーンショット 2021-09-19 14.46.28.png
UICollectionViewCompositionalLayoutについて。
iOS13以上で使える。
ItemSectionの間に新たなGroupという概念が加わった。
Groupは入れ子構造が可能で、複雑なレイアウト構成を表現できる。
IndexPathにはアクセスできないので、データにアクセスして動的にサイズを変更するのは苦手。

スクリーンショット 2021-09-19 14.47.24.png
UICollectionViewCompositionalLayout + DiffableDataSourceの実装例を紹介。
ViewControllerは渡されたデータ構造をただ表示するだけで、「表示モデル = 画面そのもの」の直感的な実装ができる。

スクリーンショット 2021-09-19 14.47.38.png
DiffableDataSourceについて。
差分更新が特徴で、データとUIの不整合を型レベルで担保している。

ひとこと所感

各サブクラスの得意/不得意が分かりやすくまとまっていて良かったです。
UICollectionViewCompositionalLayoutDiffableDataSourceを使うシーンも増えてくると思うので、ちゃんとキャッチアップしていかないとなーと思いました!

iOSアプリのセキュリティ基礎

概要

内容(抜粋)

スクリーンショット 2021-09-19 16.06.09.png
http/https通信をする上でのセキュリティとして、iOSではATSがある。
Info.plistから強度が設定できるが、丸ごと無効化したりせず、できるだけデフォルトのASTに近い状態で動作するようにすることが大切。

スクリーンショット 2021-09-19 16.12.13.png
URLスキームの脆弱性について。
同じURLスキームを受け取るアプリをリリースすることが可能。
先にインストールしているアプリが受け取るので、もし攻撃者のアプリを先にインストールしていたら、攻撃者に大事なデータが渡ってしまう。
どのアプリにどのURLスキームが実装されているかはツールなどを利用すれば誰でもわかること。

スクリーンショット 2021-09-19 16.16.16.png
対策の一つがUniversalLinksを使うこと。
攻撃者はドメインを奪うことは難しく、そのドメインに紐づくアプリを作ることはできない。
URLスキームよりもデータを奪われる可能性が低く安全。

スクリーンショット 2021-09-19 16.22.17.png
対策の2つ目として、外部ブラウザでの認証などの場合、外部ブラウザではなくSFsafariViewControllerなどを使ってアプリ内でブラウザを開くこと。
ブラウザ内でURLスキームが生じた場合、先にインストールしたアプリではなく、アプリ内ブラウザを開いているアプリが優先してURLスキームを受け取るため安全。
また、URLスキームではセキュリティ上漏洩になるような重要なデータを渡さないことも大切。

スクリーンショット 2021-09-19 16.26.19.png
重要情報をローカルのどこに保存すべきか?については、Keychainに保存することを推奨。
Realm上のデータもKeychainに鍵を入れておくことによって守ることができる。
アプリをリバースエンジニアリングされる可能性があるので、ソースコード内に重要情報をハードコーディングするのは避けるべき。

スクリーンショット 2021-09-19 17.06.03.png
認証の仕組みについて、代表的なものはこの3つ。攻撃例と対応策は以下。

  • CSRFにはstateパラーメーターの付与で対応
  • id-tokenの改ざんはデジダル署名検証で対応
  • リプレイアタックにはnonceパラメーターの付与で対応

スクリーンショット 2021-09-19 17.10.38.png
OAuthやOpenID Connectを利用するときは、独自の実装ではなくできるだけ標準の仕様に則った実装にすること。
また、脆弱性を理解して、OAuthやOpenID Connectに則った検証をちゃんとすること。
ログインできればいいというものではない。

ひとこと所感

セキュリティについて基礎から説明してくださっていて、誰にでもわかりやすいトークだったと思います。
「脆弱性はいつも近くに潜んでいる」ということを胸に刻んで実装していきたいですね!

おわりに

今回もまた大作になってしまいました:yum:
(トーク見ながら記事に起こすのはわりとハードで、3日間におよぶ自分との戦いに勝った気分です:beer:
ここまで見てくださった方、ありがとうございました!
※昨年の記事はこちら →iOSDC 2020 印象に残ったトークまとめ🎉 - Qiita

スタッフの皆さん、スピーカーの皆さん、参加された皆さん、本当にお疲れさまでした:sparkles:
来年のiOSDCも楽しみにしています!
スクリーンショット 2021-09-19 18.42.43.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
23
Help us understand the problem. What are the problem?