Objective-C - TECH PLAY - TECH PLAY

TECH PLAY

Objective-C

イベント

該当するコンテンツが見つかりませんでした

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

はじめに 株式会社エブリーは、2026年9月11日(金)〜13日(日)に有明セントラルタワーホール&カンファレンスで開催された iOSDC Japan 2026 に、ゴールドスポンサーとして参加しました! 開発本部から6名のエンジニアが現地参加したので、ブースの様子や印象に残ったセッションをご紹介します。 会場の様子 3日間で70本以上のトークや LT が行われ、現地には約1,000名規模の参加者が集まる大盛況でした。 セッションやブース以外の企画も盛りだくさんで、朝9:30からドーナツサービスに始まり(おいしかった!!!)、声優さんによる館内アナウンス、スポンサーブースを回るスタンプカードビンゴ、ペンライトが揺れる LT 大会など、会場全体がお祭りムードでした。 エブリーブース エブリーは今回、ゴールドスポンサーとしてブースを出展させていただきました。ブースでは、参加型のアンケートボードとデリッシュAI の実機デモの2つを展示しました。 当日は多くの方々にブースへお立ち寄りいただき、iOS や AI 開発についてさまざまなお話を伺うことができました。足を運んでいただいた皆様、本当にありがとうございました! アンケートボード「iOSアプリ開発、AIにどこまで任せていますか?」 「iOSアプリ開発、AIにどこまで任せていますか?」をテーマに、「開発工程のどの段階まで AI に任せているか」と「iOS エンジニアの経験年数」の2軸をシールで答えてもらう参加型のアンケートを実施しました。 3日間で皆様に、ボードいっぱいシールを貼っていただきました。 ざっくりまとめると 完全自律させている人はまだ少数 実装は AI に任せている方が大多数 最終的な確認・判断は人間が行っている エンジニア歴との相関関係は特になし という結果でした。 シールを貼っていただいた流れでリアルな開発事情を共有し合うこともできました。 特に盛り上がったのが「iOS の UI 確認や E2E テストをどう行っているか?」というテーマです。「実装は AI に任せられるけれど、動作確認はスピードやトークン消費の兼ね合いでまだ難しい…」という声が多く、現場のリアルな工夫を聞くことができました。 ドメインの複雑さや求められる品質レベル、個人開発か業務かによって AI 活用のアプローチは異なり、各社・各人が置かれた環境の中で、ベストな開発方法を模索している印象でした。ちなみに数少ない「完全自律させている」方にお話を聞くと、最後は「勇気と度胸」という声もありました。 AI 以外の話題では、iOS エンジニア歴15年以上の歴戦の猛者から、Objective-C / iPhone 3G / Xcode 3 時代の古き良きお話を聞けたのもリアルイベントならではの醍醐味でした。 デリッシュAI の実機デモ もう一つの展示は、iOS 版で新しくなった「デリッシュAI」の実機デモです。デリッシュAI は、チャットで相談するとレシピを提案してくれる『デリッシュキッチン』の AI アシスタントで、提示された選択肢をタップしていくだけで会話が進み、作りたいレシピにたどり着けます。無料プランでも1日5回までお試しいただけるので、ぜひ触ってみてください! 今回デリッシュAI のアップデートに伴い、Generative UI というアプローチを取り入れる技術的挑戦を行いました。 仕組みとしては、サーバー側の AI エージェントがおすすめレシピといったデータだけでなく「画面構成」までを返し、アプリ側がそれを SwiftUI で動的に描画しています。AI にはあらかじめ定義した数種類のコンポーネントのみを渡し、「どれをどの順で配置するか」の判断に絞らせることで、デザインの品質を保ちながらも、対話や選択肢のバリエーションを柔軟に拡張できるようにしました。 ブースでは、Generative UI という考え方そのものはもちろん、それを実際のプロダクトへ落とし込んでいる点に対して「面白い!」という声を多数いただき、非常に嬉しかったです。 他社のスポンサーブース 3日間で他社のブースも回らせていただきました。どこも工夫を凝らした企画で、ノベルティ含め個性豊かな展示でした。全部は回りきれなかったので、立ち寄れた中から一部を紹介します。 ピクシブ さん :デジタルシールを作成・交換できるアプリ「ぴくしーる」をデモ展示されていました。今年の iOSDC のために開発されたそうで、イベント専用にアプリを作り込まれる熱量に驚きました。 ZOZO さん :ZOZO検定というクイズ企画でした。社内で実施されたクイズの出張版とのことで、全10問に挑戦し、正解数に応じてノベルティがもらえました。 LINEヤフー さん :Yahoo!知恵袋を題材にした「#リアル知恵袋」。来場者が付箋で質問や回答を寄せ合う企画で、技術ネタから人生相談まで多様な交流が付箋上で生まれていました。 転職ドラフト さん :AI 時代に評価されるエンジニアとは何か、をテーマに、来場者が付箋で意見を貼っていくアンケートボードを実施されていました。AI 時代に iOS エンジニアとして、エンジニアとして生き残っていくために何が必要か、考えさせられる内容でした。 セッション紹介 ブース運営の合間に聴講したセッションから、印象に残ったものを紹介します。 柔軟性のあるUIで、多くの環境でアプリを活躍させる 発表者: noppe さん iOSDC 開幕前日の9月10日(日本時間)に折りたたみ iPhone「iPhone Duo」が発表されたこともあり、レスポンシブな UI 設計というタイムリーなテーマに会場は超満員でした。多様な画面サイズにどう適応していくかは、これから多くの iOS エンジニアが向き合うことになる課題であり、そこにどう向き合うかのヒントとなるようなセッションでした。 noppe さんは「UI の柔軟性」を、状況を問わずに価値を提供できること、と定義していました。UI を「目的(ユーザーが実現したいこと)」「コンテキスト(ユーザーが置かれた状況)」「インターフェース(目的を実現する手段)」という3つの要素の組み合わせとして捉え直すと、コンテキストが変わったときに目的を守るにはインターフェースの側が変わるしかない。マルチプラットフォーム対応や新しい画面サイズへの対応を「利用者が少ない割にコストが高いもの」として後回しにするのではなく、同じ目的に対して複数のインターフェースを持てる状態をつくろう、というのがセッションの主張です。 では、インターフェースはコンテキストの変化にどう応じるのか。セッションではそれを「連続的な適応」と「段階的な適応」の2つに整理していました。前者は枠のサイズに合わせて伸縮させる方法、後者は境界を越えたら情報量やレイアウトの構造そのものを切り替える方法で、その境界は「同じインターフェースのまま目的を十分に達成できるか」で決める、という基準もあわせて示されていました。 単に「デザインの崩れを修正する」のではなく、「目的とコンテキストに基づいて UI を設計する」という本質ベースなアプローチの重要性を再認識させるセッションでした。連続性と段階性という捉え方も、これまで感覚的に対応していた部分を言語化していただいた印象です。iPhone Duo へのリサイズ対応に限らず、UI の設計指針として参考になる内容でした。 世界の中心でAI(App Intents)を叫ぶ - App Intents中心設計の実践ガイド 発表者: touyou(藤井 陽介)さん(株式会社グッドパッチ) App Intents はアプリの機能をアプリの外部から呼び出すための仕組みであり、2022年の登場以来、Siri、ウィジェット、Spotlight、Apple Intelligence、そして今年の Siri AI と、年々呼び出し口を広げてきました。Apple はあらゆるアプリが Siri や Apple Intelligence と統合されたエコシステムを目指しており、その手段となる App Intents の重要性は年々高まっています。これほど重要になっているなら、後から対応するのではなく最初から App Intents を設計の中心に据えてしまおう、というのが本セッションの主題「App Intents 中心設計」でした。 原則として次の3つが挙げられていました。 App Intents から設計する なるべく DRY でいること 色んな動線で使ってもらうこと 実装としては、UI も Siri も Spotlight もウィジェットも同じ Intent を通して Service を呼ぶ構成にする、アプリ内のボタンも Button(intent:) で Intent 経由にする、などというものでした。処理が一箇所にまとまり、どの内部 / 外部システムからでも同じ機能が使えるようになります。 さらに AppIntent をアプリの「動詞」、AppEntity をアプリの「名詞」と捉えれば、App Intents から設計するとは、そのアプリで「誰が何をできるのか」を動詞と名詞で棚卸しすることに他ならない、つまり App Intents 中心設計はユースケース中心設計と同じ発想に立っている、という話でした。 これまで私のなかで App Intents は「ショートカットやウィジェットの実装に必要なもの」という位置づけで、そこに iOS 27 で Siri AI が登場したためAppIntent や AppEntity を用いて音声入力によるアプリ操作をできるようにしたいな、くらいに考えていました。が、Apple が想像以上に App Intents に注力していることを知り、であれば App Intents を起点に設計するという考え方(App Intents Driven Development)も面白そうだと感じました。とはいえ、既存アプリを全面的に App Intents 中心へ移行するのは相応の工数がかかりそうなので、やるとすれば主要なユースケースをいくつか Intent として切り出すところから始めるのが、現実的なアプローチかなと思っています。 アフターイベントのお知らせ ゆめみ、フェンリル、ヤプリ、ウェルスナビ、セーフィー、エブリーの6社合同で「DroidKaigi & iOSDC After Talks Night 2026」を開催します。DroidKaigi 2026 と iOSDC Japan 2026 の合同アフターパーティーで、iOS と Android のエンジニアが同じ場に集まり、各社の LT や懇親会でプラットフォームを越えた交流ができる会です。 項目 詳細情報 開催日時 2026年10月2日(金)19:00〜21:00 開催場所 住友不動産麻布十番ビル 9F アクセンチュア・イノベーション・ハブ 東京(東京都港区三田一丁目4番1号) 開催形態 オフライン / オンライン コンテンツ 各社の Android & iOS に関するセッション / 懇親会 現地参加の申込はすでに締め切られていますが、オンライン(配信)での参加は引き続きお申し込みいただけます。当日はエブリーのメンバーも LT で登壇予定ですので、ぜひご覧ください! 詳細やオンライン参加のお申し込みは以下からどうぞ。 yumemi.connpass.com 最後に 3日間、多くの方にブースに足を運んでいただきました。エブリーのことを知っていただくだけでなく、iOS 開発や AI 活用の話を情報交換できて、とても良い機会になりました。 これからもデリッシュキッチン、そしてエブリーをよろしくお願いします! 最後までお読みいただき、ありがとうございました!
こんにちは、株式会社LuupでEngineering Managerをしている瀧川です。 2026年9月1日(火)〜3日(木)にベルサール渋谷ガーデンで開催されたDroidKaigi 2026に、Androidエンジニアのメンバーといっしょに参加してきました! LuupではLUUPアプリをiOS・Androidともにネイティブで開発しているので、Android開発の最新動向やAI活用の事例をキャッチアップしたく参加してきました。 平日開催のため私は最終日しか参加できず残念でしたが、資料やセッション動画は後日公開されるはずなので、聴けなかったセッションはそちらで追いかけようと思っています。
はじめに こんにちは。WEAR部iOSブロックの坂倉です。 WEARは先日、 SceneDelegate へ移行しました。ライフサイクルそのものに関わる変更のため、画面数の多い歴史あるアプリではなかなか骨が折れました。 この記事では、 WEARが直面した課題 、 課題を解決するために取ったアプローチ 、そして 移行中につまずいた箇所と対処 をご紹介します。 WEARのような大規模アプリが、影響範囲の広い SceneDelegate 対応をどのように進めたのか、その実例として参考になれば幸いです。 目次 はじめに 目次 SceneDelegate対応で直面した課題 iOS 27以降、未対応のアプリは起動できなくなる アプリのライフサイクルに関わる変更のため、すべての画面に影響する ライフサイクルイベントがAppDelegateとSceneDelegateに分かれて呼ばれる すべての画面で問題が出ないか、慎重に調査しなければならない 課題を解決するためのアプローチ アプローチ1. AppDelegateとSceneDelegateの役割を理解する AppDelegateの役割 SceneDelegateの役割 役割と違いのまとめ どの処理をSceneDelegateへ移すか プッシュ通知はAppDelegateに残す アプローチ2. AIを使って影響範囲を特定し、QA観点をまとめる 1. AIを使って影響範囲を把握する 2. AIが高い精度で仕事できるように、デリゲートメソッドを1個ずつSceneDelegateに移す 3. AIにQA観点を書き出させる これから対応するならXcode 27の併用も検討を アプローチ3. リスクを抑えるため、最小限の変更にとどめる つまずいた箇所と対処 一番最初のウィンドウを取得するのは危ない 外部ソースからの起動判定はconnectionOptionsで行う さいごに SceneDelegate対応で直面した課題 WEARが直面した課題は大きく2つあります。「対応しないという選択肢がない」ことと、「対応がアプリの全画面に影響する」ことです。 iOS 27以降、未対応のアプリは起動できなくなる Appleは公式ドキュメント Transitioning to the UIKit scene-based life cycle で、 UIScene ライフサイクルの採用が必須になると明記しています。最新SDKでビルドするアプリが対象となり、iOS 27・iPadOS 27・Mac Catalyst 27・tvOS 27・visionOS 27以降、未対応のアプリは起動できなくなります。 つまり、対応しない限り最新SDKでのアップデートを続けられなくなります。 アプリのライフサイクルに関わる変更のため、すべての画面に影響する SceneDelegate に対応すると、これまで AppDelegate が受け取っていたUI関連のライフサイクルイベントは SceneDelegate が受け取るようになります。ライフサイクルはアプリの根幹であり、この変更はWEARが持つすべての画面に影響し得ます。 具体的には次のような難しさがありました。 ライフサイクルイベントがAppDelegateとSceneDelegateに分かれて呼ばれる まず大変だったのが、これまで AppDelegate だけに届いていたライフサイクルイベントが、 AppDelegate と SceneDelegate の2つに分かれて呼ばれるようになる点です。 AppDelegate 中心の頃、起動時のイベントは次の順番で、すべて AppDelegate に届いていました。 application(_:willFinishLaunchingWithOptions:) application(_:didFinishLaunchingWithOptions:) applicationDidBecomeActive(_:) 初期化処理も1つのクラスに集まっているため、実行順序を追うのは難しくありませんでした。 ところが SceneDelegate を採用すると、アプリ起動時の実行順序は次のように2つのクラスをまたぐ形になります。 application(_:willFinishLaunchingWithOptions:) (AppDelegate) application(_:didFinishLaunchingWithOptions:) (AppDelegate) scene(_:willConnectTo:options:) (SceneDelegate) sceneWillEnterForeground(_:) (SceneDelegate) sceneDidBecomeActive(_:) (SceneDelegate) 起動処理が2つのクラスに分散すると、「この初期化はあの処理より先に終わっているはず」という前提が崩れます。たとえば、 SceneDelegate へ移したUIのセットアップが AppDelegate 側の初期化に依存していると破綻します。 さらに、呼ばれるタイミング自体が変わるイベントもあります。 sceneWillEnterForeground(_:) は applicationWillEnterForeground(_:) と違い、アプリ未起動(Not Running)からの起動でも呼ばれます。フォアグラウンド復帰時の処理をそのまま移すと、起動時にも実行されてしまいます。 どの処理を、どちらのクラスの、どのイベントに置くべきか 。アプリ全体の初期化処理を1つずつ見極める必要がありました。 参考: About the app launch sequence すべての画面で問題が出ないか、慎重に調査しなければならない WEARには通常起動のほかに、URLスキーム・ユニバーサルリンク・プッシュ通知など複数の起動導線もあります。特定の条件が揃ったときだけ顕在化するリグレッションもあり得るため、すべての画面について「移行しても問題が出ないか」を1つずつ調査していく必要がありました。 画面数の多いWEARにとって、これは人力だけでやり切れる規模ではありません。 課題を解決するためのアプローチ これらの課題に対して、WEARでは次の3つのアプローチで移行を進めました。 AppDelegateとSceneDelegateの役割を理解する AIを使って影響範囲を特定し、QA観点をまとめる リスクを抑えるため、最小限の変更にとどめる アプローチ1. AppDelegateとSceneDelegateの役割を理解する まず取り組んだのは、Appleの公式ドキュメントを読み込み、 AppDelegate と SceneDelegate がそれぞれ何を担当しているのかを正確に理解することでした。 AppDelegateの役割 UIApplicationDelegate プロトコルに準拠する AppDelegate は、アプリ全体のライフサイクルイベントを管理します。 アプリレベルのイベント管理 :アプリの起動・終了、システムレベルのイベントなど、アプリプロセス全体のライフサイクルを担当する。 application(_:didFinishLaunchingWithOptions:) などを通じて、アプリの初期設定や起動準備をする 初期の環境設定 :アプリ全体のデータやリソースの初期設定、プッシュ通知の処理などを担当する シングルトン :1つのアプリにつき、 UIApplication は1つしか存在しない 注意したいのは、 SceneDelegate に対応すると、UIに関するライフサイクルイベントは SceneDelegate の担当に移り、 AppDelegate には届かなくなるという点です。 SceneDelegateの役割 UIWindowSceneDelegate プロトコルに準拠する SceneDelegate は、「シーン」のライフサイクルイベントに応答します。シーンとは画面に表示されるアプリのUIのひとまとまりのことで、たとえばiPadで同じアプリを2つのウィンドウで並べて開くと、それぞれが独立したシーンになります。 シーンの管理 :アプリのUIを「シーン」として表現し、それぞれのシーンが独自のライフサイクルと状態を持てる。これにより、複数のウィンドウを並べて表示するマルチウィンドウ環境が可能になる シーン固有のライフサイクルイベント :これまで AppDelegate が扱っていたUI関連のライフサイクルイベントを SceneDelegate が担当する 役割と違いのまとめ 特徴 AppDelegate SceneDelegate 責任範囲 アプリ全体のプロセスとライフサイクル(起動・終了・システムレベルイベント)を管理 シーンのライフサイクルを管理 UIの管理 従来はアプリで唯一のUIとウィンドウを管理。iOS 13以降はUI管理の責任が軽減された 各シーンのUIのセットアップ・ウィンドウ管理・UIライフサイクルイベントを処理 マルチウィンドウサポート 単一のウィンドウのみ 複数のウィンドウをサポート 要するに、 AppDelegate はアプリの「プロセス」レベルの管理を担い続けます。一方の SceneDelegate は、シーンごとのUIの管理と、ライフサイクルイベントへの応答を担当します。 どの処理をSceneDelegateへ移すか 役割が分かれば、対応方針は明確です。 AppDelegate で処理していた次の処理を SceneDelegate に移行しました。 説明 移行前(AppDelegate) 移行後(SceneDelegate) 具体例 アプリ起動時のWindow生成処理 application(_:didFinishLaunchingWithOptions:) scene(_:willConnectTo:options:) Windowの生成、起動に必要なデータ取得、GA送信のための設定、URLスキームの受け取り シーンがアクティブになったときの処理 applicationDidBecomeActive(_:) sceneDidBecomeActive(_:) プッシュ通知バッジのリセット シーンが非アクティブになる直前の処理 applicationWillResignActive(_:) sceneWillResignActive(_:) — シーンがフォアグラウンドに入る時の処理 applicationWillEnterForeground(_:) sceneWillEnterForeground(_:) 必要に応じたリロードとAPI実行 シーンがバックグラウンドに入る時の処理 applicationDidEnterBackground(_:) sceneDidEnterBackground(_:) バックグラウンド移行時のUI後処理 ユニバーサルリンク処理 application(_:continue:restorationHandler:) scene(_:continue:) ユニバーサルリンクの受け取り URLスキーム処理 application(_:open:options:) scene(_:openURLContexts:) URLスキームの受け取り プッシュ通知はAppDelegateに残す ここで1つ注意点です。 プッシュ通知はアプリ全体に関わるイベントなので、引き続き AppDelegate で処理します 。 Appleのドキュメント にもある通り、デバイストークンの登録や通知の受信といったプッシュ通知のハンドリングには、 SceneDelegate 側に対応する移行先が用意されていません。 なお、通知への応答がシーンと無関係というわけではありません。通知へのユーザーの応答(タップなどの操作)をシステムがどのシーンに反映するかを示す UNNotificationResponse.targetScene というプロパティが用意されています。通知タップ後の処理でシーンが必要な場合は、このプロパティから取得できます。 アプローチ2. AIを使って影響範囲を特定し、QA観点をまとめる 13年の歴史を持ち、300個ものViewControllerを抱えるWEARにとって、影響範囲の調査は人力だけでやり切れる規模ではありません。そこで、Claude CodeやGitHub CopilotなどのAIをフル活用し、3つのステップを踏んで対応を進めました。 AIを使って影響範囲を把握する AIが高い精度で仕事できるように、デリゲートメソッドを1個ずつSceneDelegateに移す AIにQA観点を書き出させる 1. AIを使って影響範囲を把握する 先ほど触れた どの処理をSceneDelegateへ移すか の表をAIに読み込ませ、影響範囲を特定しました。また、具体的にどんな処理が入っているのかも表にさせたことで、必要な対応の解像度を上げました。 2. AIが高い精度で仕事できるように、デリゲートメソッドを1個ずつSceneDelegateに移す どの処理をSceneDelegateへ移すか で洗い出した対象メソッドは、もれなくSceneDelegateへ移す必要があります。しかし、一度にやってしまうと対応漏れが出かねません。AIの出力の質やスピードを上げる意味でも、範囲を絞って1個ずつ移すのが良いと判断しました。 3. AIにQA観点を書き出させる ここが一番助かった部分です。今まで、QAに提出する観点は人の手で書いていました。これを機に、その大半をAIが書く形へ変えました。 具体的な手順は次のとおりです。 まず、AIにSceneDelegate対応をさせてプロトタイプを作り、それをベースに全体の影響範囲とQA観点をざっと把握する メソッド移行ごとにブランチを切り、PR作成時、Diffの内容からJiraへQA観点を出力する プロトタイプで書き出したQA観点とブランチごとのQA観点を見比べて不足がないか確認する こうすることで、人間が気づかなかった範囲も調べて出力してくれるので、質の良いQAにつながりました。 具体的には、特定の地域からアクセスしたときだけ表示する利用規約Windowや、メンテナンス画面の表示・非表示のように複数のライフサイクルイベントにまたがって初めて成立する処理などが対象でした。普段意識する機会が少ない処理ほど、人力でQA観点を洗い出す際には抜け落ちがちです。AIに列挙させたことで、こうした処理も取りこぼさずQA観点に反映できました。 これから対応するならXcode 27の併用も検討を WEARのSceneDelegate対応は2025年に行ったため、Xcode 27を使うことはできませんでした。これから対応する場合は、Xcode 27の併用も検討してみてください。 WWDC26のセッション「 Modernize your UIKit app 」では、Xcode 27同梱の「uikit-app-modernization」スキルが紹介されています。このスキルはSceneDelegate対応だけでなく、UIScreen.mainやinterfaceOrientationのモダナイズなどにも対応しています。今進めているAdaptiveレイアウト対応でも役立っています。 また、Xcode 27は、Appleの公式ドキュメントやテックノートはもちろんのこと、Apple Developer Forumsの情報も参照してくれるため、非常に便利です。正式リリースが待ち遠しいですね。 アプローチ3. リスクを抑えるため、最小限の変更にとどめる 影響範囲の広さに対するもう1つの答えが、移行のスコープを必要最低限にとどめることです。WEARでは以下の方針で移行を進めました。 シーンのライフサイクルにのみ対応する 処理の移行を最優先し、処理のリファクタリングは後で行う マルチウィンドウの対応は一旦見送る SceneDelegate に対応すれば、iPadでのマルチウィンドウなど、できることは増えます。しかし、リスクを最小限に抑えるため、まずシーンのライフサイクル対応だけを完結させると決めました。 また、WEARの AppDelegate はObjective-Cで書かれた非常に古いコードだったため、本音を言えばリファクタリングもしたいところでした。今回、 SceneDelegate へ移行した処理に限りSwiftへの置き換えを行いましたが、処理そのものには手を加えず、挙動を変えない必要最小限の修正にとどめています。 つまずいた箇所と対処 最後に、移行中に直面した代表的な不具合と、その対処を紹介します。 一番最初のウィンドウを取得するのは危ない SceneDelegate 対応後は、 UIWindow が各シーン( UIWindowScene )に紐づき、シーンごとの持ち物へと変わります。 本来は良くない実装ですが、WEARはこれまでSceneDelegateに対応していなかったため、以下のコードでWindowを取得しても問題になっていませんでした。 extension UIApplication { var firstKeyWindow : UIWindow? { let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene return windowScene?.windows.first( where : \.isKeyWindow) } } しかし、SceneDelegate移行後はマルチウィンドウが可能になるため、最初に取得したシーンのWindowが、いま操作しているWindowとは限らなくなります。 よって、ViewControllerからWindowを取得する場合は、 view.window を使って「いま表示しているシーンのWindow」を取得する形へ修正しました。ただし view.window は、Viewがウィンドウ階層に追加されるまでは nil のままなので、呼び出すタイミングには注意が必要です。 // Before: アプリ全体のkeyWindowに依存していた let rootVC = UIApplication.shared.firstKeyWindow?.rootViewController as? RootViewController // After: 自分が表示されているシーンのWindowから取得する let rootVC = view.window?.rootViewController as? RootViewController 外部ソースからの起動判定はconnectionOptionsで行う これまでは AppDelegate の launchOptions のキーで「外部から開かれた起動か」を判定し、ダイアログ表示などを制御していました。 SceneDelegate では、この起動情報は scene(_:willConnectTo:options:) に渡される connectionOptions へ集約されています。型は UIScene.ConnectionOptions です。 これを参照することで、URLスキームやユニバーサルリンク、プッシュ通知など、「どこで起動されたのか」を判別できます。 WEARでは次のように判定しています。 userActivities や urlContexts からディープリンクを取り出して種別を判定します。それらがなくリモート通知での起動であれば .remoteNotification を、いずれにも当てはまらない通常起動なら nil を返します。 extension SceneDelegate { enum ExternalSource { case urlScheme case universalLink case remoteNotification } } extension SceneDelegate.ExternalSource { @MainActor init? (_ connectionOptions : UIScene.ConnectionOptions ) { let userActivityURL = connectionOptions.userActivities.first { $0 .activityType == NSUserActivityTypeBrowsingWeb }?.webpageURL let urlSchemeURL = connectionOptions.urlContexts.first?.url if let deepLinkURL = userActivityURL ?? urlSchemeURL { switch deepLinkURL.scheme { case "URLスキーム名" : self = .urlScheme case "https" : self = .universalLink default : return nil } return } if connectionOptions.notificationResponse != nil { self = .remoteNotification return } return nil } } func scene (_ scene : UIScene , willConnectTo session : UISceneSession , options connectionOptions : UIScene.ConnectionOptions ) { let externalSource = SceneDelegate.ExternalSource(connectionOptions) } さいごに 「技術調査で役割を正確に理解する」「AIで影響範囲を特定する」「最小限の変更にとどめる」という3つのアプローチにより、 SceneDelegate 対応を無事完了できました。 なかなか骨が折れましたが、 SceneDelegate に対応したことでマルチウィンドウに対応する土台ができ、AIエージェントを使って大規模な修正に取り組む経験も得られました。 この記事が、 SceneDelegate 対応を控えている方の一助になれば幸いです。 ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。 corp.zozo.com

動画

該当するコンテンツが見つかりませんでした

書籍