複数アプリを開発している環境では、あるアプリの機能を別のアプリでも使いたいシチュエーションがあるかと思います。しかし、アプリ全体をパッケージとして公開するのは、規模の大きいアプリでは現実的ではありません。マルチモジュール化されたアプリであれば、必要なモジュールだけを公開したいところです。
Swift Package Manager(SPM)のローカルパッケージ機能を活用することで、特定のモジュールのみを公開し、そのモジュールが依存する他のモジュールは非公開に保つことが可能です。
本セッションでは、SPMを使って特定のモジュールだけを公開する具体的な方法を解説します。また、実際にこの手法を試した結果、期待していたモジュールの隠蔽が実現できず、最終的に採用を見送った経緯についても共有します。
iOSには、サーバーから送られるプッシュ通知と、アプリ内で発行するローカル通知の2種類の通知があります。通知といえばプッシュ通知が目立ちがちですが、実はローカル通知にもたくさんの活躍の場があり、通知UXを支えるうえで欠かせない存在です。状況に応じて、プッシュ通知よりも頼れる選択肢になることもあります。
たとえばアプリがフォアグラウンドにあるとき、プッシュ通知で通知内容を表示しようとすると、UIの更新に必要な情報の取得に失敗することで、アプリの表示と通知の内容が食い違ってしまうことがあります。このようなケースでは、アプリ内部の処理が成功してからローカル通知を表示することで、より安定した通知体験が実現できます。
本トークでは、ローカル通知の特徴や活用シーンを整理したうえで、チャットアプリの実装を例に、プッシュ通知との使い分けや、通知の見た目や動作を整えるための設計上の工夫について紹介します。
Communication Notifications、通知へのアクション、スレッド表示など、プッシュ通知でおなじみの表現がローカル通知でも実現できることを確認しながら、通知UXをより良くするための工夫を共有します。
あなたのアプリでも、ローカル通知が思わぬ形で役立つかもしれません!
リリース作業ってどうしてこんなにも面倒なのでしょう?
アプリを公開するには切っても切り離せないリリース作業。
会社やアプリの規模が大きくなるにつれて利用するツールも増えていきがちで、
・GitHubのリリースノート作成
・リリースブランチ作成
・マイルストーン更新
・Notionで各所に連絡するための資料作成
・QA用の項目列挙…
など多くの "頑張れば自動化できるが中々自動化するには腰が重い" 作業がつきまとってしまいます。
複雑なリリース作業は特定のメンバーに依存してしまうことや、新しいメンバーが覚えにくいなどの問題も発生する可能性もあります。
さらに、仮にBotを作成してもiOSエンジニアには馴染が薄い別の言語を選択せざる負えない状況になってしまうことや、複雑な実行環境が要求される可能性もあります。
こうした問題を解決するため、AWS Lambdaで実行できるSwift製のSlackアプリを開発しました。
本セッションでは、このSwift製リリース作業Slackアプリの開発・運用方法について紹介します。
我が家はかわいい猫と暮らしています。ネットワークカメラとして設置したGoogle Nest Camは、Google HomeのアプリとWebでカメラ映像をストリーミング視聴可能です。せっかくなのでペットの行動をリアルタイムで把握でき、安心して外出できるように、macOSやvisionOSでも実行可能なアプリが欲しくなりました。Smart Device Management APIとWebRTCを使って、ストリーミングアプリを手に入れましょう。Appleプラットフォームでアプリを実装することで、映像再生に留まらず、自分自身で機能拡張が可能になります。Google Nest Camからの映像をAppleデバイスで解析し、VNDetectAnimalBodyPoseRequest
を使って猫の骨格を検出、かわいいポーズを可視化するアプリを開発しました。
本LTでは「Smart Device Management APIの準備」「WebRTCでの映像接続」「Vision.frameworkでの映像解析」を経て、制御可能なストリーミングアプリを作成する過程をギュッと5分で紹介します。この発表を通じて、ハードウェアとAppleプラットフォーム技術を組み合わせる楽しさをお届けします。
猫は気まぐれ、開発では振り回されましたが、それもまたかわいいものです。
対象聴衆
現代の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がいいだけじゃダメですか?→ダメです
Swift 6と共にComplete Concurrency Checkingが導入され、1年が経ちました。これまで曖昧にしておくことができたSwift Concurrencyも、きちんと理解して正しく適用する必要性が高まっています。
Swift Concurrencyの関連仕様は多岐にわたり、Swift EvolutionのProposalも膨大です。それらのすべてを正確に把握するのは非常に困難です。しかし、Swift Concurrencyのコアとなる考え方はシンプルです。それさえ押さえてしまえばSwift ConcurrencyとComplete Concurrency Checkingについての見通しがよくなり、その挙動を体系的に理解しやすくなります。
本トークでは、Swift Concurrencyの根幹を成すものとして、Isolation Domain・Isolation Boundary・Sendableとは何か、それらを利用してコンパイラがどのようにデータ競合を防ぐのか(Complete Concurrency Checking)を解説します。
その上で、Actorがどのような仕組みで動作するのか、ActorとIsolation Domainの関係、Global Actor(特にMainActor)およびTaskについて解説し、Swift Concurrencyについての理解を深めます。
さらに、その説明の延長線上として、WWDC25の様々なセッションでも取り上げられたSwift Concurrency関連の新機能SE-0461・SE-0466について解説し、Swift 6.2のSwift Concurrencyにおけるそれらの役割を示します。
最後に、iOSアプリでそれらをどのように組み合わせて活用するのか、一例を示します。
多くのプロジェクトでCIは、テストや静的解析を通じて品質を保証する重要な役割を果たしています。
一方で、CIの待ち時間はプルリクエストをマージするまでの時間に大きな影響を与えています。
「家族アルバム みてね」のiOSアプリでは、各プルリクエストでユニットテストと静的解析を実行していますが、その待ち時間が最大で約50分に達し、開発スピードを阻害する要因になっていました。
特にiOSに関わるメンバーが10人から20人へと倍増したことで、全メンバーがこの待ち時間の影響を受け、ボトルネックとなる場面が頻発していました。
コードレビューによる修正が多くなると影響を受けるのはもちろんのこと、hotfix等の緊急対応が必要な場面で特にもどかしさを感じていました。
これらの課題を解決するために、CIで2つの並列化手法を実践し、待ち時間を約20分まで短縮することに成功しました。
本セッションでは、導入までのステップ、導入時の課題、得られた効果について詳しくご紹介します。
生成AIの目覚ましい進化により、LLM(大規模言語モデル)を活用した開発が急激な勢いで発展しています。
モバイル領域の開発も例外ではなく、LLMを活用して開発を効率化していくことが求められてきているかと思います。
本セッションでは、LLM活用して iOS/Android 両OS アプリの効率的な開発手法についてお話いたします。
具体的には、以下を深堀ってお話しいたします。
先日 担当しているアプリの譲渡をしたのですよ。
で、よくあるアプリ譲渡の手順で、事前準備もしっかりとして、つつがなく 譲渡が完了!
….と、思っていたのですが、「あれ、このAPIを使うには、Appleに許可がいるの?」という思わぬ事態に遭遇!
具体的には、PassKit
の requestAutomaticPassPresentationSuppression(responseHandler:)
を使っているのですが、これは特別なEntitlementをAppleに申請しないと利用できないAPIだったので、譲渡後に改めて申請をしました。
この経験をきっかけに、Appleに申請・許可が必要なAPI について調べてみたところ、他にも「申請必須API」があることが分かりました。
このライトニングなトークでは、Appleにメールを送信してから、APIが利用できるようになるまでのプロセスと、その他の許可が必要なAPIについてお話しします。
いざ許可が必要なAPIを利用する際に焦りたくない方におすすめです。
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
「目的地に行ったらスマホ制限解除」というアプリを作っていた時の話です。
開発は順調でした。近所のジムで何度テストしても完璧に動作。「位置判定範囲200mで実装完了!」そう思っていました。
ところが、友人からの一通のメッセージで事態は急変します。
「代々木公園の中にいるのに判定されない!バグってない?」
まさか、そんなはずは...。慌てて現地に向かい検証すると、確かに公園内部で全く反応しません。一方で、同じコードを使ったジムでは相変わらず正常動作。
いったい何が違うのか?
・GPS精度の問題?→同じ精度設定
・デバイスの問題?→同じiPhone
・通信環境?→どちらも良好
・コードの問題?→全く同じ実装
同じ位置判定機能なのに、なぜ場所によって動いたり動かなかったりするのか?
調査を進めるうち、ある重要な事実に気づきました。そして最終的に辿り着いた解決策は、なんとAIに「ある質問」を投げかけることでした。
この奇妙な現象の正体とは?
そして「ある質問」とは一体何だったのか?
同じような位置判定機能を実装している方、実は知らずに同じ罠にハマっているかもしれません。実際コードとデバッグの軌跡をお見せしながら、この謎解きの全貌をお話しします!