筆者はiOS開発についての技術記事を5年ほど継続的に書き続け、2025年には「iOS開発の教科書」という電子本を執筆するに至りました。本セッションではiOS開発という枠組みを超えて、テクニカルライティング(技術的な内容の文章作成)についての実践知を共有します。テクニックに関しては他にもっと専門的に論じられているものがあるので、モチベーションの部分を厚めに話します。
技術発信をしてみたいが躊躇している方の後押しになるのはもちろん、そうでもない方でも日常の技術情報の伝え方の改善につながる内容になるかと思っております。
複数アプリを開発している環境では、あるアプリの機能を別のアプリでも使いたいシチュエーションがあるかと思います。しかし、アプリ全体をパッケージとして公開するのは、規模の大きいアプリでは現実的ではありません。マルチモジュール化されたアプリであれば、必要なモジュールだけを公開したいところです。
Swift Package Manager(SPM)のローカルパッケージ機能を活用することで、特定のモジュールのみを公開し、そのモジュールが依存する他のモジュールは非公開に保つことが可能です。
本セッションでは、SPMを使って特定のモジュールだけを公開する具体的な方法を解説します。また、実際にこの手法を試した結果、期待していたモジュールの隠蔽が実現できず、最終的に採用を見送った経緯についても共有します。
iOSには、サーバーから送られるプッシュ通知と、アプリ内で発行するローカル通知の2種類の通知があります。通知といえばプッシュ通知が目立ちがちですが、実はローカル通知にもたくさんの活躍の場があり、通知UXを支えるうえで欠かせない存在です。状況に応じて、プッシュ通知よりも頼れる選択肢になることもあります。
たとえばアプリがフォアグラウンドにあるとき、プッシュ通知で通知内容を表示しようとすると、UIの更新に必要な情報の取得に失敗することで、アプリの表示と通知の内容が食い違ってしまうことがあります。このようなケースでは、アプリ内部の処理が成功してからローカル通知を表示することで、より安定した通知体験が実現できます。
本トークでは、ローカル通知の特徴や活用シーンを整理したうえで、チャットアプリの実装を例に、プッシュ通知との使い分けや、通知の見た目や動作を整えるための設計上の工夫について紹介します。
Communication Notifications、通知へのアクション、スレッド表示など、プッシュ通知でおなじみの表現がローカル通知でも実現できることを確認しながら、通知UXをより良くするための工夫を共有します。
あなたのアプリでも、ローカル通知が思わぬ形で役立つかもしれません!
リリース作業ってどうしてこんなにも面倒なのでしょう?
アプリを公開するには切っても切り離せないリリース作業。
会社やアプリの規模が大きくなるにつれて利用するツールも増えていきがちで、
・GitHubのリリースノート作成
・リリースブランチ作成
・マイルストーン更新
・Notionで各所に連絡するための資料作成
・QA用の項目列挙…
など多くの "頑張れば自動化できるが中々自動化するには腰が重い" 作業がつきまとってしまいます。
複雑なリリース作業は特定のメンバーに依存してしまうことや、新しいメンバーが覚えにくいなどの問題も発生する可能性もあります。
さらに、仮にBotを作成してもiOSエンジニアには馴染が薄い別の言語を選択せざる負えない状況になってしまうことや、複雑な実行環境が要求される可能性もあります。
こうした問題を解決するため、AWS Lambdaで実行できるSwift製のSlackアプリを開発しました。
本セッションでは、このSwift製リリース作業Slackアプリの開発・運用方法について紹介します。
現代のiOS開発において、パフォーマンス向上のために並行処理は不可欠です。
Swift Concurrencyは、async/awaitによる非同期処理の記述を簡潔にするだけでなく、Actorや構造化された並行処理によって、これまで開発者を悩ませてきたデータ競合という危険なバグから、コンパイル時という開発の早い段階で私たちを解放してくれます。
これは、これまでの並行処理技術にはなかった画期的な「コンパイラによる安全保証」という大きな特徴を持っています。
では、Swift Concurrency以前はどうでしょう?
例えばGCDやOperationQueue、さらにはNSThreadといった技術はどれほど簡潔ではなく安全ではなかったのでしょうか?
これらの技術は、スレッド管理を抽象化したり、排他制御の基礎機能を提供したりはしましたが、その安全性は常に開発者自身の厳密な規律に依存していました。
一つでも排他制御を忘れると、予期せぬクラッシュやデータの破壊を引き起こすリスクに常に晒されていたのです。
このトークでは、この並行処理の歴史を、現代のSwift ConcurrencyからNSThreadへと遡りながら、その安全性の進化を比較・解説します。
シンプルなカウンタからファイルダウンローダーを例にSwift Concurrency、OperationQueue、GCD、NSThreadの実装例をお見せします。
Swift Concurrencyが目指している安全性を歴史から学び、自信を持ってコードが書ける一助になれば幸いです。
XcodeのデフォルトデバッガであるLLDBはPythonで拡張できますが、あまり知られておらず広く使われていないようです。本トークではPythonによる拡張について、実際に使ってみて得られた知見をお話しします。
LLDBはPythonスクリプトによるコマンド作成をサポートしており、デバッガ内のメモリ・シンボル・ソースコードへのアクセスだけでなく、MacOSのファイルシステムやネットワークリソースも利用可能です。また、Pythonの豊富なライブラリを活用することも可能なので、手軽に実用的な拡張を作成できます。
例えば、変数のログを記録したい場合、コンソールに出力するのは手軽ですが、他のログと混ざってしまいますし、実行のたびに消えてしまいます。代わりに、値をファイルに追記するスクリプトを作成してブレークポイントで呼び出すことで、対象のログだけを記録することが、コードの変更なしに可能になります。
別の応用例として、C++で使っている独自形式の画像など、Xcodeでプレビューできない形式に対して、Pillowというライブラリを使用して画像変換を行いプレビュー表示を実現することができます。
さらに、ローカルhttpサーバーを利用してブラウザでの画像表示を行い、ほぼリアルタイムのプレビュー機能を実現する方法もご紹介します。
これらの知見が、デバッグ作業の効率を向上させる手助けとなれば幸いです。
XcodeCloudを快適に利用できていますでしょうか?
AppleはWWDC21にてCICDツールである "XcodeCloud" を発表しました。2021年登場から4年が経過し、他のCIツールに比べてコスト面の圧倒的優位性や導入の容易さ、署名周りの運用コストの低さなどから利用されることが多くなっています。
しかし、XcodeCloudは「マシンスペックの選択」ができないため、利用対象のアプリが巨大だとしても、より高価なマシンを選択することができず、1回の実行時間が普段の開発で利用するには耐えられないほど(40分〜)長くなってしまう問題があります。
本セッションでは、XcodeCloudを利用されている方や別のCIツールを利用している方を対象に、最小限の対応で現実的な実行時間(〜20分)に抑えるための改善についてお話します。具体的には最新のビルド改善方法やワークフローの最適化設定、差分テスト実行、パッケージ取得の効率化などの改善についてご紹介します。
以下の内容について紹介します。
・XcodeCloudの概要(実行環境、ワークフロー構築)
・XcodeCloudの改善 - 設定変更
・XcodeCloudの改善 - ワークフロー実行改善
・XcodeCloudの改善 - ビルド改善
・XcodeCloudの改善 - 差分テスト実行のための仕組み構築
現代のiOSアプリ開発ではSwiftUIの LinearGradient
や MeshGradient
、CIFilterの linearGradientFilter
などを使えば簡単にグラデーションを実現することができます。
多くの場合はこれらの強力なAPIを使うことで事足りるのですが、イラスト制作におけるグラデーション効果などにおいては、表現の幅を広げるためにより高機能なグラデーション描画を行いたいことがあります。
例えば、虹のような表現を行うためにグラデーションの制御点を複数用意したり、透明色からブラシ色に徐々にグラデーションするような表現が用いられたり、色の変化に緩急をつけるために補間関数を設定するようなケースがあります。
そのようなケースにおいて、既存コンポーネントでは実現することが難しいため、自分でシェーダーを記述して実現することになります。
このLTでは上記のような高度なグラデーションをAppleプラットフォーム向けのグラフィックスAPIであるMetalを利用して行った話と、その際にハマった透明色の扱いについて紹介します。
メソッドの命名は、処理の内容を語るものでなければならない──それは世の中に広く浸透し、誰もが当然のように従ってきた原則だった。
実際その教えは、長い間開発の秩序を保ち、プロジェクトの明瞭な設計へと導いてきた。
だがある時、この教えに一つの問いを投げかける者がいた。「ViewModelは、他の層と同じ命名規則では語りきれない存在ではないか。」と。
それは異端とされた。責務をわかりづらくし、統一性をなくし、抽象的で、実装を曖昧にするものだとされた。
それでも、複雑なUIと入り組んだ状態遷移の中で、その考え方は静かに、しかし確かに広がっていった。
これは、かつて正統派とされた命名に意を唱え、新たな視点を持ち込もうとした者たちの物語である。
本発表では、ViewModelの「UIとロジックの境界である」「Viewの抽象化である」という特性を踏まえ、そのメソッドの最適な命名について探っていきます。
また、一般的にメソッド名において是とされる「saveProfile」「fetchItems」のような処理内容中心の命名と比較し、UIイベントに即した「onSaveTapped」「onRetryRequested」といったイベント中心の命名が、どのような設計上の価値をもたらすかを検討します。
命名という小さな選択が、設計にどのような影響を与えるのか。
5分間で一緒に考えてみませんか?
みなさんSwift Package Managerで依存パッケージをブランチ指定している場合など、意図したバージョンが利用されずに困ったという経験はないでしょうか。
このような問題に直面した際、私たちはその根本原因が分からないまま、手探りでキャッシュを削除したり、Xcodeを再起動したりといった非効率な試行錯誤に多くの時間を費やしてしまいがちです。
特に、ライブラリのバージョンが古いまま残っているかどうかは、その挙動をしばらく観察しないと判明しないこともあり、問題解決までにかかる時間がさらに長引くケースも少なくありません。
本トークでは、Swift Package Managerのキャッシュの仕組みを深掘り、その適切な取り扱い方を理解することで「分からないから手当たり次第に試す」という状況から脱却できるようになることを目指します。
具体的には以下のようなトピックを取り扱います。
去年の私は、「@Environment(.keyPath)実践入門」というパンフレット記事を書きました。8ページにも及ぶボリュームでしたが、おかげさまで非常に好評をいただき、今年はその続編として、「@Environment(.keyPath)をフル活用したアーキテクチャ作り」のパンフレット記事を執筆する運びになりました。
しかし私の@Environment(.keyPath)への愛は、やはり文字だけでは伝えきれず、私が実際にどのように書いてきたか、この仕組みによってどんなメリットが得られるのか、そして思わぬ落とし穴!?まで、私がここ2年近く@Environment(.keyPath)と付き合ってきて得た全ての知見を、皆さんに共有したいと思います!
この発表は以下の内容を含める予定です:
この発表は、SwiftUIの初心者から上級者まで楽しんでいただける内容に仕上げる予定です。そしてこの発表を聞いて、一人でも@Environment(.keyPath)に興味を持ち、開発で今まで以上に活用してみてくれた方が増えたら、私にとってこれ以上に嬉しいことはないでしょう!
多くのユーザーはアプリを使用する際に「直感的に操作できること」を期待しています。1ユーザーとしてさまざまなアプリを触っていると、「こう思っていたのになんでこうなるんだ?」という違和感を覚えることがあると思います。
おそらくその違和感はアプリの設計の段階で、UI/UXの考慮が抜けてしまっていることが原因で生じているものだと考えられます。
もちろん、技術的な制約や実装上の理由から、理想的なUI/UXを実現するのが難しい場合もあります。
ですが、ユーザーは自分の期待通りにアプリが動作することを期待しています。想定と違うとユーザーは困惑してしまい、求めていた情報に辿りつかなかったり、嫌悪感を抱いて離脱してしまう、そんなことにつながってしまう可能性もあります。
たった一つのボタンの動きやアニメーションだけでせっかくのUIも台無しになる可能性さえあります。
こうした背景から、どのようなUI/UXの抜けがあってユーザーに違和感があるのか、それをどうしたら改善できるのかを考えたいと思いました。
このトークでは、どのようなUI/UXの欠落がユーザーに違和感を与えるのかを具体的に分析し、それをどのように改善できるのかを考察します。具体的には、以下のポイントを中心にお話しする予定です。
・失敗例(実例ではなくサンプルをお示しします)
・失敗をどのように改善できるかについての提案
つまりのところ言いたいこと:UIがいいだけじゃダメですか?→ダメです
多くのプロジェクトでCIは、テストや静的解析を通じて品質を保証する重要な役割を果たしています。
一方で、CIの待ち時間はプルリクエストをマージするまでの時間に大きな影響を与えています。
「家族アルバム みてね」のiOSアプリでは、各プルリクエストでユニットテストと静的解析を実行していますが、その待ち時間が最大で約50分に達し、開発スピードを阻害する要因になっていました。
特にiOSに関わるメンバーが10人から20人へと倍増したことで、全メンバーがこの待ち時間の影響を受け、ボトルネックとなる場面が頻発していました。
コードレビューによる修正が多くなると影響を受けるのはもちろんのこと、hotfix等の緊急対応が必要な場面で特にもどかしさを感じていました。
これらの課題を解決するために、CIで2つの並列化手法を実践し、待ち時間を約20分まで短縮することに成功しました。
本セッションでは、導入までのステップ、導入時の課題、得られた効果について詳しくご紹介します。
生成AIの目覚ましい進化により、LLM(大規模言語モデル)を活用した開発が急激な勢いで発展しています。
モバイル領域の開発も例外ではなく、LLMを活用して開発を効率化していくことが求められてきているかと思います。
本セッションでは、LLM活用して iOS/Android 両OS アプリの効率的な開発手法についてお話いたします。
具体的には、以下を深堀ってお話しいたします。
Kotlin Multiplatform(KMP)を使うことでかんたんにクロスプラットフォーム開発をすることができます。
最近ではAndroid開発でよく使われている便利なライブラリもKMPに対応し、より一層KMPの開発体験が向上しています。
例えば、ローカルでデータを永続化するためのライブラリ「Room」もKMPに対応しました。
Roomを使って開発をする場合はすべてのコードを共通化できるのではなく、プラットフォームによって実装が違う箇所があり、その場合はactual / expect 修飾子を使って実装します。
プラットフォーム別に動くコードは簡単に書くことができたのですが、テストコードを書こうとすると詰まる箇所があり苦労しました。
本セッションでは、Roomを使って開発する際にプラットフォーム別にactual / expectをどのように実装していくかと、そのコードに対してのテストの実装方法について、具体的なコード例を交えながら紹介します。
私が所属する大学の研究室では, 音声解析の結果や録音した音声からグラフを作成する機会が多くあります. しかし, 研究室全体で利用している既存の音声編集ソフトウェアのグラフ表示機能には, 「複数の音響データを同一のグラフに重ねて表示できない」, 「データ間の詳細な差分を比較できない」などといった問題があり指導教員がこの点に不満を抱いていました.
そこで普段からiOSアプリの開発をしている私は, AVFoundationで音声ファイルを読み込み, 音声信号が時間とともにどのような周波数成分を持っているかをAccelerate FrameworkのAPIを用いて高速フーリエ変換 (FFT: Fast Fourier Transform)を行うことで解析し, その結果をSwift Chartsを用いてスペクトログラムを描画するようなシンプルなアプリケーションを作成しました.
このアプリを使用することで, 複数の音声ファイルの音声スペクトルを重ね合わせて表示したり, 差分を表示したりすることが可能になり, より直感的な音声特性の分析を実現しました. これにより音響データの比較検討が効率化されたとともに, ゼミの発表資料などで成果の視覚的な説明ができるようになりました.
このトークでは
について, 高速フーリエ変換の基礎や作成したアプリケーションの実装に触れつつお話します.
macOS では InputMethodKit を活用することで、自作の日本語入力システムを開発できます。本トークでは、日本語入力機能を備えた Input Method の構築を目標に、
・InputMethodKit の基礎と使い方
・開発をスムーズに進めるコツ
・日本語入力機能を実装する際に役立つライブラリの紹介
を順に解説します。これをお聞きいただければ、誰でもデスクトップ向け日本語入力システムを DIY できるはずです。
私は iOS 向けに開発した日本語入力キーボードアプリ 「azooKey」 を macOS へ移植し、過去 1 年にわたり開発・運用を続けてきました。
GPUを用いた強力な変換機能を作ったり、端末外のAPIにアクセスすることによってLLMなどを活用することも、機能的制限の緩いmacOS環境なら容易に実現可能です。
本トークではこうした自作Input Methodの魅力を紹介します。
一方、macOS特有の制約も様々に存在します。変換候補ウィンドウの表示、容易にいかないデバッグなど、さまざまな難しさがあります。こうした地雷を避けつつ使い勝手の良いInput Methodを開発するための知見も紹介します。
※2023年のiOSDCではiOS向けのキーボードアプリの開発についても話しました。こちらもぜひご覧ください。
https://fortee.jp/iosdc-japan-2023/proposal/87be3428-5381-4aa3-8127-cfd714663429
音声でアプリの入力が完結したらとても便利だと思いませんか?
音声入力の代表格である Siri は2011年に iPhone に登場して以来年々進化を遂げ、「声で操作する」という動作は当たり前のものになりました。
音声入力をアプリに組み込む方法としては Speech framework があり、日本語もサポートされており、音声をそのままテキストに変換ができます。
しかしアプリの入力は、テキストだけではありません。
トグルやピッカーなど、テキスト以外のアプリ入力としては Speech framework 柔軟性に欠けていました。
ところが、WWDC25 で発表されたオンデバイスLLM Foundation Modelsを使うと状況が一変します。
@Generableマクロを使うことでプロンプトから任意のSwift型のデータを出力できるようになったのです。
つまり Speech frameworkで音声入力をしてテキストに変換し、Foundation Modelsのプロンプトとして渡せば、アプリの入力を音声で完結できるようになりました。
このトークではSpeech frameworkとFoundation Modelsでアプリの入力を簡便にする方法を発表します。
Todoアプリを例に実装例やオンデバイスLLMでの効果的な利用方法をお話します。
「目次」
・Foundation Modelsとは?対応機種や制限は?
・Speech frameworkと組み合わせる実装例
・効率の良いプロンプト作成方法
・実際のユーザーの評価とフィードバック
あなたのアプリもキーボード中心の UX を“声だけの入力”へアップグレードしてみませんか?
皆さんのアプリでは、分析ログを正確かつ漏れなく収集できていますか?
私たちのサービスでも多くのログを送信していますが、かつては実装漏れやデグレによる送り漏れが頻発し、効果測定ができず仮説検証に大きな支障が出ていました。
とはいえ、少人数チームかつiOS・Androidの両対応、さらに限られた予算の中で、導入できる手段には制約がありました。
そこで私たちは、「ログ送信箇所にテストコードを追加する」方針をとることにしました。
この実践により、徐々に実装漏れがなくなり、デグレによるログ欠損も減少しました。
テストコードといえば通常はビジネスロジックに対して書くものという認識があるかもしれません。
「なぜそこにテストを?」と思われるかもしれませんが、設計を工夫すればログ送信にも十分活用でき、ビジネス上の価値も高いと感じています。
本トークでは、ログ送信に対してテストを書くことの効果や実例、そして設計上の工夫についてご紹介します。
ログ品質の担保に課題を感じている方に、実践的なヒントをお届けいたします。
みなさんの開発チームにiOSエンジニアは何人在籍していますか?
中には少数のエンジニアで開発・運用しているケースもあるかと思います。
少人数体制では、チームにかかるリリース作業の負荷が大きくなりやすく、どうしてもリリース間隔が空いてしまい、頻度が低下しがちです。
しかしリリース頻度の減少は、ユーザーからのフィードバックを得る機会 = 仮説検証を通じたサービスの成長・改善機会の減少にもつながるため、可能な限り避けたいものです。
私が開発・運営に携わっているグルメサービス「Retty」のアプリチームは、iOSエンジニア2名を含む全3名という小規模チームながら原則「毎週リリース」を実現し、直近1年間のiOSアプリのリリース回数はのべ50回に達しました。
この継続的かつ高頻度なリリースによって、仮説検証や機能の軌道修正を機動的に行うことができ、ビジネス視点でも大きなメリットを得られていると実感しています。
もちろん、これは気合で成し遂げているわけではなく、開発メンバーの負荷を最小限に抑えながら「楽々」達成できるよう、さまざまな工夫とテクニックを活用しています。
本トークでは、毎週リリース実現のため、我々が実践してきた開発・運用手法や工夫についてわかりやすくご紹介します。
また高頻度リリースを実践するうえでの注意点や、直面した課題・失敗事例についてもお話しいたします。
「たくさんリリースして、たくさん学んで、たくさん成長する」
そんなアプリ開発・運用を目指す方にとって、きっと参考になる内容です。ぜひ本発表をご覧ください。
トーク内容