音楽:トランスクライブのすすめ

ある YouTube 動画を見て、そういえばと思ったこと。

先日、コンボジャズでは5年ぶり?に人前で演奏した(ドラム)。反省は多々あれど、手前味噌ながら自分の成長をおおきく感じたステージでもあった。そしてその成長の根底にあると実感しているのが、トランスクライブだ。


トランスクライブの効果として感じることは

  • 音符の羅列としてしか捉えられなかったフレーズの数々が、ジャズやビバップのボキャブラリとして認識できるようになる(必然性に気がつける)
    • ルーディメンツや基礎練習への意欲向上
    • 意外と名ドラマーも同じフレーズ「使い回してる」んだなあ、などの発見
  • ミュージシャンそれぞれのスタイルが分かるようになる、自分の好きなスタイルが知れる
  • 自分の好きなドラマーのフレージングなので、自信を持って本番演奏で繰り出せる(成功せずともチャレンジはできる)
  • 自分で題材を決めてトランスクライブすることで、日々の練習やレッスンに対して課題感を持って挑める

などなど、、挙げ出したらキリがない。が、多くのプロミュージシャンがオススメするとおり効果が絶大なのは間違いないので、筆者と同じジャズ学習者にはすすめている。

しかし、ひとりで取り組むには限界があるので、可能なら講師など誰かに見てもらうべきだと思う。


筆者の場合、2022年末から月1でドラムの先生にレッスンしてもらっているのだが、去年からは自分で決めた課題曲を譜面に起こして見てもらっている。はじめて持っていった(先生にLINEで送った)のが、2024年5月のコレ。

Larry Vuckovich Trio – Srreet Scene から、”Blue Bohemia Suite”, “News for Lulu” Tana Akira のソロパート

まともに譜面なんて書いたことなく、それまでレッスンでもらった譜面を見よう見まねで採譜したので、はじめは譜面の書き方からの指導だった。以降、平均して 2ヶ月〜3ヶ月に1曲くらいのペースで持っていっている。

一番最近はこんな感じ(↑の譜面からちょうど1年後)。

Freddie Redd – Lonely City から、”Emily Reno” Ben Riley のソロパート

筆者の先生は、LINEで送った譜面写真やPDFファイルをそのまま紙にプリントアウトしてくるので、Notes.app の書類スキャン機能と PDF のマークアップ機能を使い、

  • コントラスト比の高いPDFファイルにする
  • 曲名や各段の秒を書き入れる
  • 音符だけでなく手順(左右や強弱)も書き入れる

ことで、レッスン中のコミュニケーションがスムーズになるよう心がけている。

これを題材に、内容(聞き取ったこと)の是非、違った場合はなぜそうなのか?を、手順(ルーディメンツ)的背景を交えて教えてもらう。こればかりは無知な自分が独学するには効率が悪すぎるため、先生についてもらう醍醐味だと毎度感じている。

レッスンを重ねながら育てていくと、譜面はこうなる。


本当はこのブログを始めた際、トランスクライブした譜面もアップロードしていきたいと思っていたが、清書するのが大変でできていなかった。そろそろ、いろんな譜面に埋もれて自分がどの曲をトランスクライブしたかが把握できなくなってきたので、形式はわからないがデジタルで一覧できるようにアーカイブしていきたい。

WWDC25:Meet SwiftUI spatial layout

SwiftUI による 3D レイアウトについて。


0:00 – Introduction

  • visionOS 26 で SwiftUI の新しい Spatial Layout 機能について紹介
  • 既存の 2D レイアウトツールとアイデアを使って 3D アプリケーションを構築可能
  • アニメーション、リサイズ、状態管理の組み込みサポートを活用

2:47 – 3D views

  • visionOS では全ての View が 3D になり、width, height に加えて depth, Z position も計算される
  • カスタムの debugBorder3D modifier を用いて解説
  • Model3DImage と同様に固定の width, height, depth を持つ
  • Image, Color, Text などは depth が 0 で iOS と同様の動作
  • RealityViewGeometryReader3D は利用可能な depth を全て使用
    • 従来の SwiftUI と同じレイアウトシステム
  • scaledToFit3D モディファイアでアスペクト比を維持しながら 3D 空間にフィット可能
    • Window では width-height のアスペクト比はユーザー操作によって代わるが、奥行きの提案はウインドウで固定されている
    • Volume は深さもサイズ変更可能
  • ZStack の挙動

7:18 – Depth alignments

  • visionOS 26 で DepthAlignments が追加され、既存の Layout タイプを 3D View に適応
    • VStackLayout などで depthAlignment モディファイアを適用して深度方向の配置を制御 (e.g. VStackLayout().depthAlignment(.center)  {…)
    • front, center, back の標準的な depth alignment を提供
  • Custom Depth Alignment で DepthAlignmentID プロトコルに準拠した独自の配置を定義可能
    • e.g. .alignmentGuide(.customAlignment) { $0[DepthAlignment.center] }

11:41 – Rotation layout

  • rotation3DLayout モディファイアで View の回転をレイアウトシステムに反映
    • 従来の rotation3DEffect は視覚効果のみでレイアウトには影響しなかったが、rotation3DLayout はレイアウトも変更
  • 任意の角度と軸での回転をサポート
  • 例:カスタム実装の RadialLayout と組み合わせて 3D カルーセルを構築可能
  • 複数の rotation3DEffect を組み合わせて複雑な 3D 配置を実現

16:28 – Spatial containers

  • SpatialContainer で複数の View を同じ 3D 空間に配置(入れ子人形方式)
  • 3D alignment(bottomFront, topTrailingBack など)で配置を制御
  • 選択状態の表示や UI 要素の重ね合わせに活用
  • spatialOverlay で単一の View を別の View と同じ 3D 空間に重ねる
  • debugBorder3D modifier の実装方法
    • spatialOverlay で実装

WWDC25:Enhance your app’s audio recording capabilities

Vision Pro 用にオーディオを扱うアプリを開発しているのでチェック。実はオーディオ周りはほぼ体系的な理解なしに、つぎはぎで作ってきた経緯あり、ちゃんと勉強しようと思っている。

オーディオの記録とその編集や視覚化を同時に行えるのは魅力的。これまでオーディオファイルをローカルに保存し、その後ファイルを読み込んで波形表示するよう実装していた。このため、録音→UI反映に時間差が発生してしまっていた。ここで紹介されたアップデートで解決できるのかも。


0:00 – Introduction

  • iOS 26 で追加された音声録音機能の強化について紹介
  • 入力デバイス選択、音声キャプチャ、再生の API 更新を説明

1:02 – Input route selection

  • iOS 26 で AVInputPickerInteraction が追加され、アプリ内から音声入力デバイスを選択可能に
  • システム設定を開かずに、アプリ内で直接デバイス切り替えができる

3:06 – Recording with AirPods

  • iOS 26 で AirPods の高品質録音モード(bluetoothHighQualityRecording)が追加
  • コンテンツクリエイター向けのメディアチューニングで、音声と背景音のバランスを最適化
  • AVAudioSessionAVCaptureSession の両方でサポート
  • AirPods のステムボタンで録音開始・停止も可能

5:11 – Spatial Audio capturing

  • Spatial Audio の仕組み
    • マイク配列から3Dシーンを録音
    • ambisonics と呼ぶ形式に変換
    • 1次 ambisonics(FOB: First Order Ambisonics)として保存
      • 4つの9面調和関数コンポーネント(omni-component, x/y/z方向の垂直双極子)
  • 空間オーディオ再生だけでなく、オーディオミックスエフェクト用のAPIにより前景背景のバランス調整が容易に
  • iOS 26 で AVAssetWriter を使った Spatial Audio 録音が可能に
  • 新しい QuickTime Audio(.qta)形式で音声のみの Spatial Audio ファイルを保存可能
    • 複数のオーディオトラックをサポート
    • 2 つの音声トラック(ステレオ + Spatial Audio)と再生用情報のメタデータトラックで構成
      • ステレオは空間非対応デバイスでの互換性担保のため
  • MovieFileOutput でない独自ファイルを AVAssetWriter で構築する方法
  • AVCaptureSessionMovieFileOutputAudioDataOutput の同時動作もサポート
    • AudioDataOutput はサンプルバッファへのアクセスを提供、エフェクトや波形描画が可能
    • 同時動作をサポートすることで、ファイル書き込みとサンプルへの処理や視覚化を同時に行える

11:04 – Audio Mix

  • iOS 26 と macOS 26 で Cinematic Framework に Audio Mix 効果の制御機能が追加
  • 前景音(音声)と背景音(環境音)のバランスを調整可能
  • ミックスモードは Cinematic, Studio, In-Frame の 3 つの基本モードと 6 つの追加モードを提供
  • AVPlayer では CNAssetSpatialAudioInfoAVAudioMix で実装
  • AVPlayer を使わず AUAudioMix で直接処理も可能(AU: Audio Unit)
    • e.g. 話し声と環境音の分離
    • AU を使用し多くの設定が自動で行われる
    • AUAudioMix の使い方、SpatialAudioMixMetadata
    • 録音停止時に自動生成されるメタデータでチューニングパラメータを適用

WWDC セッション動画の要約方法

細々とWWDC25のセッション動画要約を続けていたのが、いつの間にか30本になっていた。全体で120本近くあるようなので4分の1。興味があるものから順に手をつけているが、まったく興味がないものもあるので、すべてを要約するつもりはない。50本を目処で終わりにしようと思っている。

ところで、要約を始めたきっかけだが、キャッチアップの形跡を残し続けることで、学習意欲や発信のモチベーションにつながるのと、継続した結果が後から振り返って形としてわかりやすいと思ったからだ。

例年は2倍速再生で1日に何本も「消化」する方法をとっていたが、ただ量をこなすだけで、結局あとから思い返しても、何を見て/見ていないかすら曖昧になってしまっていた。

今年は、すでにこうして1ヶ月近く続けられるので、継続できて嬉しい限り。さらに、要約した内容はある程度は記憶に残せているので、無駄にはなっていなさそう。検索してさかのぼりやすいという副次的な効果も実感できている。他にも、勉強会での会話のネタを増やしてくれたり、Recap系イベントで発表する準備を省略できたのもよかった。


ところで、こうした要約をどのように行なっているかというと、当然すべてを手作業でやっているわけではなく、がっつり AI に頼っている(Cursor)。

ありがたいことに、Apple はすべてのセッションビデオに対して文字起こしを提供してくれているので、これをフル活用している。AI に丸投げするだけでは意味がなく、映像としての情報量も大事なので、以下のステップを踏み、自らもビデオを見るようにしている。

  1. セッションビデオのトランスクリプトを Cursor に与えて要約してもらう
    • 特別なプロンプトは与えていないが、セッションの概要(About)に示された関連する章(Chapters)を合わせて提供すると、これに沿って構造化してくれるので追いやすくなる。
      e.g.
      0:00 - Introduction
      1:02 - Input route selection
      3:06 - Recording with AirPods
      5:11 - Spatial Audio capturing
      11:04 - Audio Mix
  2. 要約を一読してから、セッションビデオを見る(1.5〜2倍速)
  3. 要約を自分なりに再整理したり、理解を追記する
    • 要約を Markdown 形式で出力してもらい、Markdown エディタ上で編集

真面目に見て理解するため、1本まとめるのになんだかんだ30分か、それ以上は掛かっているが、内容を先読みできる分、ゼロイチでまとめるよりもはるかに時間は短縮できている。

あと、トランスクリプトや要約のファイルが蓄積するので、過去見た内容について AI に質問することもできる。(このポストの最後)

WWDC25:Set the scene with SwiftUI in visionOS

シーン復元や物理空間との連携について。Clipping Margins でボリュームの領域外部にコンテンツを描画できるようになったのはありがたい。システム許容のマージン領域としてどんな値が取れるのか(たとえば床より下、天井より上、壁より向こうは許容されない?)が気になっている。

ユーザーの視点移動に応じたコンテンツの変化(onVolumeViewpointChange)も具体的にどのような情報の取れ方や、コンテンツへの活かし方が可能か実験してみたい。


0:00 – Introduction

  • visionOS 26 で追加された新しいシーン機能の概要を紹介
  • Window, Volume, Immersive Space の シーンタイプに追加されたAPI の解説

2:11 – Launching and locking

  • シーンのロックと復元(locking, restoration)API が追加され、物理空間の特定の部屋にウインドウやボリュームを固定できる(イマーシブ空間は復元されない)
    • ほとんどのユーザーが復元できることを望むため、シーン復元を優先するべき
    • 一時的、コンテンツ依存なUI、ワンタイムアクションなどには .restorationBehavior(.disabled) で復元を無効化可能
  • defaultLaunchBehavior でアプリ起動時に表示するウインドウを柔軟に制御できる
    • e.g. ウェルカム画面の表示
    • Info.plist Preferred Default Scene Session Role と起動ウィンドウの役割との一致が必要
      • e.g. Window Application Session Role 指定はボリュームが無視される
    • .defaultLaunchBehavior(.supressed)でアプリ再起動時の再表示を抑制
  • Unique Window で重複しないウインドウを作成可能
    • WindowGroupWindow

8:15 – Volumetric enhancements

  • surface snapping(物理環境へのスナップ)の対応
    • ウインドウは壁など垂直面に
    • ボリュームは机など水平面に
    • ウィジェットは垂直水平どちらも
    • surfaceSnappingInfo environment でスナップ状態を取得可能
      • isSnapped
      • ARKit によるスナップ表面の分類情報を取得可能
        • ユーザー許可が必要:Info.plist に設定
  • onVolumeViewpointChange modifier で、視点の切り替えに表示を追従
    • 例:視点を遮る壁を非表示にする
  • Presentations(popover, menu, sheet など)が Volume, RealityView, RealityKit でも利用可能に
    • presentationBreakthroughEffect で 3D コンテンツとの重なり方を制御
  • Clipping Margins API の追加
    • preferredWindowClippingMargins で、シーン境界外にビジュアル表現を拡張できる
    • 視覚のみでインタラクティブではない
    • windowClippingMargins environment で、システムによって許可されたマージンを取得

15:58 – Immersive space

  • Immersive Space で world recentering イベントや immersion style のカスタマイズが可能に
  • .onWorldRecenter でリセンタリングを検知(位置の再計算)
  • Progressive immersion style でのポータルのアスペクト比や範囲を調整可能に
    • .landscape, に加え .portrait
    • .portrait は iOS ゲームや多くの動きが含まれる体験に有効
  • Mixed immersion style で周囲環境に溶け込む
    • システム環境(e.g. 月)との共存も実現 .immersiveEnvironmentBehavior(.coexist)
  • Remote immersive space で macOS から Vision Pro へ Metal レンダリングを転送し、即時プレビューが可能
    • CompositorContentCompositorLayer に SwiftUI の環境変数やモディファイアを適用可能

22:16 – Scene bridging

  • UIKit アプリでもシーンブリッジングにより SwiftUI の Volume, Immersive Space を統合可能
    • Safari なども Spatial Browsing でこの仕組みを活用
  • UIHostingSceneDelegate を使い SwiftUI シーンを UIKit/macOS アプリに追加できる
  • configurationForConnectiong でホスティングデリゲートクラスを設定し外部イベントにも対応可能

登壇メモ:potatotips #92 iOS/Android開発Tips共有会

potatotips で登壇してきたので感想。

イベントページ:https://potatotips.connpass.com/event/358217/

前回は Recap イベントというのもあり個人で発表したのだが、今回は仕事で得た知見を発表したかったので会社で初登壇。HealthKit で睡眠ログを集計するのに試行錯誤があったのでその内容を共有した。

といっても、持ち時間5分ということですべてをつぶさに話すわけにもいかないので、挿絵をふんだんに使いかなりざっくりとしたアルゴリズムの解説になった。聞いている側からすると恐らく(伝わっていればだが)単純すぎて意外性がなかったかもしれない。が、実際はさまざまなデータパターンをもとに、ヘルスケアアプリの統計とすべてにおいて一致できるように何度も修正を重ねてたどり着いたものだった。

発表の反響に関して、如何せんニッチなテーマなので需要はないかも、と思いつつも挑んだのだが、懇親会で HealthKit から睡眠統計を取ろうとしている方とお話しでき、今回の発表内容が刺さったと言っていただけた。とても嬉しく思うと共に、ささやかであっても誰かの需要に応えられたことで安心もした。まずは発信してみるものだ。

また、会場提供の REALITY 様(GREE様)には、大変豪華な食事を提供いただいたり、社員の方から、Unity 開発に関することや、VR/AR での体験作りなど、興味深い話をたくさん聞かせていただき、とても充実した時間だった。


今回紹介した機能実装について。HealthKit との連携からデータの集計まで含めて、ベース部分は ChatGPT に作ってもらったので初速は早かったし、アルゴリズム実装も要件さえ決まれば正直あとは作るだけなので、そこも ChatGPT に土台を作ってもらったので、データとと都合させての調整に専念することができた。

HealthKit を使って何ができる/できないの技術検証も ChatGPT を使って10分レベルで終えられた部分もあり、AI様さまだった。

WWDC25:Better together: SwiftUI and RealityKit

SwiftUI と RealityKit の相互連携に関するアップデート。盛りだくさんすぎた。オブジェクト操作を細かくハンドリングできるのは良い。ポップオーバー表示など自前でやっていたことも実装が楽になりそう。update クロージャーについては、無限ループの危険性を含めてかなり尺を使って解説しており、使いこなすのは難しそう。

CESや「モデル」の意味違いなど、アップデート以外の基礎的なテーマも網羅していて、情報量の多さをフォローする優しさを感じた。


0:00 – Introduction

  • SwiftUI と RealityKit の連携強化について紹介
  • 3D モデルと UI を組み合わせた新しい体験を実現

1:24 – Model3D enhancements

  • visionOS 26 で強化された二つの機能
    • Model3D にアニメーション再生
      • Model3D は SwiftUI ビューとして SwiftUIレイアウトシステムに従う
      • Model3DAsset でアニメーションリソースを読み込み、AnimationPlaybackController で制御(再生・停止・シーク)が可能
        • AnimationPlaybackControllerObservable に(例:time の変更監視)
    • ConfigurationCatalog からの読み込み
      • ConfigurationCatalogModel3D を初期化し、複数の外観やボディタイプを切り替えられる(@State で参照)

6:13 – RealityView transition

  • ParticleEmitter などのコンポーネント追加には Model3D が対応していないので RealityView への切り替えが必要
    • Model3D が intrinsic size に基づいてレイアウトされるのに対し、SwiftUI の与えたられたスペースを RealityView がすべて占有し、レイアウト崩れが発生
    • realityViewLayoutBehavior 修飾子:.fixedSize, .flexible, .centered で制御
      • make クロージャ実装後 1度だけ評価される
      • RealityView の原点を再配置するだけ
  • RealityKit の Entity に直接アニメーションやエフェクトを追加可能
    • ParticleEmitter で作成したエフェクトをコンポーネントに適用可能
    • RealityKit がプリセット値を提供し、Reality Composer Pro で調整可能
    • entity-component system
  • RealityView / Model3D の使い分け観点

11:52 – Object manipulation

  • visionOS 26 で Object Manipulation API が追加され、SwiftUI, RealityKit 双方で 3D オブジェクトの移動 回転 拡大縮小が可能
    • SwiftUI では manipulable モディファイア
      • orientation でサポートする操作
      • intertia で慣性(重さ)設定
    • RealityView では ManipulationComponent
      • メモ:hoverEffect.spotolight 指定
      • ManipurationEvents で ユーザー操作の開始終了、ハンドオフ(e.g. 右→左)などに応じた応答を実装可能(サウンド再生)
      • カスタムサウンド再生は、manipulationComponent.audioConfiguration = .none で無効化し、イベントサブクライブ内部で自前実装

15:35 – SwiftUI components

  • SwiftUI を RealityKit エンティティに統合するための3つのコンポーネント
    • ViewAttachmentComponent:SwiftUIビューをエンティティに直接追加
    • GestureComponent:エンティティに通常の SwiftUI ジェスチャをアタッチ、ジェスチャー値はエンティティの座標空間で報告
      • ジェスチャー対象のエンティティに、InputTargetComponent, CollisionComponent 両方を追加
    • PresentationComponent:RealityKit シーン内から SwiftUI ビューを popover のように表示

19:08 – Information flow

  • visionOS 26 で EntityObservable になり、SwiftUI との双方向データ連携が可能
  • Entity の位置、拡大縮小、回転など状態変化を SwiftUI View で監視し、UI に反映できる(withObservationTracking ブロック or SwiftUI 組み込みの監視)
  • SwiftUI と RealityKit の双方向連携
    • 従来:SwiftUI → update クロージャ → RealityKit
    • 逆方向も可能:RealityKit → Observable → SwiftUI
    • update クロージャの無限ループ回避策や、状態管理のベストプラクティス:
      • update クロージャで 監視対象のステートを更新しないこと
      • 更新する必要がある場合は、同値チェックを挟むこと
      • システムの更新関数(SwiftUIビュー本体評価外)から更新すること:e.g. gesture クロージャ
      • などなど
      • そもそも update クロージャを使わなければ避けられる

24:56 – Unified coordinate conversion

  • 新しい CoordinateSpace3D プロトコルで SwiftUI, RealityKit 間の座標変換が容易に(抽象座標空間)
  • GeometryProxy3D, Entity, Scene などが CoordinateSpace3D に準拠し、異なる空間間での距離計算や位置変換が可能
  • これにより 3D UI と 3D オブジェクトの連携がより直感的に

27:01 – Animation

  • SwiftUI のアニメーション API で RealityKit のコンポーネント(Transform, Audio, Model, Light など)を暗黙的にアニメーション可能
  • realityViewContent.animate()Entity.animate() で状態変化に応じたアニメーションを実装
  • Object Manipulation API と組み合わせてカスタムリリース挙動やバウンス効果も実現
    • 例:manipulation.releaseBehavior = .stay で無効化し、ManipulationEvents のイベント捕捉でアニメーションを自前実装

WWDC25:Bring advanced speech-to-text to your app with SpeechAnalyzer

speech-to-text に関するセッション。段階的に音声を追いながら精度を高めているというところが興味深かった。タイムコードをもとに、音声再生とテキストとを表示の上で対応づけられる点も面白い。


0:00 – Introduction

  • 新しい speech-to-text API SpeechAnalyzer を紹介
  • SpeechAnalyzer は Notes, Voice Memos, Journal など多くのシステムアプリで採用
  • Apple Intelligence と組み合わせることで通話要約などの強力な機能を実現
  • iOS 10 でで導入された SFSpeechRecognizer:音声テキスト変換モデルを提供
  • 短い音声入力で高い精度、Apple のサーバー活用
  • 一部ユースケースで期待に満たなかった
  • このセッションでは API の概要、新モデルの機能、実装デモを解説
  • iOS 26 で導入された SpeechAnalyzer
  • 高速かつ柔軟な新しい speech-to-text モデルを採用し
  • 長文や遠距離の音声(会議、会話など)に強い

2:41 – SpeechAnalyzer API

  • SpeechAnalyzer は分析セッションを管理し、SpeechTranscriber などの用途に応じたモジュールを追加して使用
  • 音声バッファは非同期で処理され、入力と結果は AsyncSequence で処理を分離
  • タイムコードを使って音声と結果を正確に関連付け
  • すべての API 操作はタイムコードでスケジュールされ、処理順序が予測可能に
  • モジュールの処理範囲が順番かつ重複せず、オーディオ全体を網羅
  • オプションで 暫定結果を有効にし、段階的な結果表示が可能
    • 発話と同時のリアルタイムで推測結果をおおまかに表示(Volatile results)
    • 音声とコンテクストを追加してあとから精度を上げて更新する(Finalized results)

7:03 – SpeechTranscriber model

  • SpeechTranscriber は Apple が設計した新しいオンデバイスモデルを採用
  • マイクから遠い話者がいる会議など、長文や会話のユースケースをサポート
  • 低遅延、高精度、高い可読性を実現し、ユーザーのプライバシーを保護
  • AssetInventory API を介して必要なモデルアセットをオンデマンドでインストール
  • モデルはシステムストレージに保持され、アプリのダウンロードサイズやメモリ使用量を圧迫しない
  • アップデートは自動的にインストール
  • 多くの言語に対応し、watchOS を除く全プラットフォームで利用可能
  • 未対応の言語やデバイス向けに、従来の SFSpeechRecognizer と同等の機能を持つ DictationTranscriber も提供

9:06 – Build a speech-to-text feature

  • SpeechAnalyzer を使ってライブ文字起こし機能を実装するデモを紹介
  • 音声を再生すると再生中に対応するテキストセグメントが自動でハイライト
  • 3つのステップで実装:SpeechTranscriber の設定、モデルの存在確認、結果のハンドリング
  • SpeechTranscriber を初期化し、volatile results や finalized results などのオプションを設定
  • AssetInventory を使って、文字起こしに必要な言語モデルがダウンロードされているか確認し、なければリクエスト
  • AsyncStream を介して返される結果オブジェクトには、AttributedString 形式のテキストと、isFinal プロパティが含まれる
  • volatileTranscriptfinalizedTranscript を個別に管理し、UIに反映
  • audioTimeRange 属性(CMTimeRange)を使って、音声再生とテキストのハイライトを同期
  • AVAudioEngine を使って音声入力ストリームを処理し、SpeechTranscriber に渡す
  • 録音停止時は、finalize を呼び出して volatile results を確定させることが重要
  • FoundationModels API と連携して、文字起こし結果からタイトルを生成するような応用も可能

WWDC25:Dive deeper into Writing Tools

作文ツールについて。カスタムテキストエンジンでも適用できるらしい。あの独特な編集アニメーションの仕組みに言及されていたのが個人的なハイライト。実装する機会はないと思うけど、、


0:00 – Introduction

  • Writing Tools はテキストのリライト 校正 要約などをテキストビュー内で実現する機能
  • 今年は ChatGPT 連携によるコンテンツ生成や画像生成も可能に
  • visionOS でも利用可能になり iOS, iPadOS, macOS 26 ではリライト後のフォローアップリクエスト(文体や調子の調整)も対応
  • Writing Tools の各機能は Shortcuts からも自動化可能(校正、書き直し、要約など)
  • アプリでサポートするための新しい API でツールバーやメニュー項目

2:21 – Customize native text views

  • システム標準のテキストビューは Writing Tools を自動サポート
  • ライフサイクルメソッドで同期停止や挙動カスタマイズが可能
  • 書き換え禁止範囲やリッチテキスト/リスト/テーブル対応も result options で制御
  • テキストヘビーなアプリはツールバーやメニューに Writing Tools ボタン追加推奨
    • UIBarButtonItem / NSToolbarItem
  • コンテクストメニューには作文ツール項目が自動挿入
    • カスタムメニュー実装時は
      • automaticallyInsertsWritingToolsItems を false
      • WritingToolsItems API で標準項目を取得

4:00 – Rich text formatting

  • テキストビューの種類に応じて .plainText, .richText, .presentationIntent など WritingToolsResultOptions を指定
    • 例: 検索フィールドではリッチテキストをサポートしない
  • RichText では display attributes: 表示属性(太字 斜体等)や presentation intent(見出し/リスト/テーブル等)を使い分け
  • Notes などセマンティックスタイル対応アプリは presentation intent でネイティブな見出しやリストを活用
  • 表示属性 と presentation intent は併用される場合もあり アプリ側で適切に変換が必要
    • TextEdit の場合具体的なフォント情報を含むが、セマンティック情報を含んでいない
    • Memos はセマンティックスタイルをフル活用する → 内部で独自の表示属性に変換する必要がある
    • 表示属性は下線や上下付き文字に使用
  • requestContexts メソッドで文脈情報や presentation intent を提供するとセマンティクスの理解精度が向上

7:41 – Custom text engines

  • カスタムテキストエンジンでも共通プロトコル対応で Writing Tools の基本機能が利用可能
  • さらに WritingToolsCoordinator API でリライトや校正のアニメーションやインライン反映も実現
    • coordinator をビューにアタッチし delegate 実装で文脈取得、変更反映、プレビュー生成、校正マーク描画などを制御
    • delegate メソッドは非同期(@escaping callback)で挙動、大規模テキストにも対応
  • 処理中のテキストアニメーション表示のために、coordinator はテキストのプレビュー画像をリクエスト(透明背景のテキストレンダリング)
    • テキストでなくこの画像にエフェクトを適用する
  • 状態変化時の undo や同期停止、外部変更の通知も coordinator で一元管理

Liquid Glass(物理)を購入した

先日の Recap イベントで、temoki さんによって紹介され界隈をどよめかせた、Liquid Glass もどきのガラスペーパーウェイトをようやく手にすることができた。

Amazon にて購入。実は、このペーパーウェイトが紹介されたLTの間に楽天で注文したのだが、欠品連絡があり、しばらく後に再注文したのだった。

誌面の上にペーパーウェイトを乗せてみた

この写真のとおり、垂直に見下ろすと確かにレンズ効果で湾曲して見えるけれど、それだけだとイマイチ Liquid Glass 感がない。一体何が足りないのかと、ズラしてみたり、敷くもの(コンテンツレイヤー)を文字から写真に替えてみたり、試行錯誤の末ふと仰角を浅く覗いてみたところ、黒い印字が虹のようにスペクトラムに分解されて映ることを発見。これこそが Liquid Glass らしさだと気がついた。

ガラスの境界線付近で、黒文字が虹色に分解されている

このドーム状のペーパーウェイトのように、ガラスが設置面(コンテンツレイヤー)に対し垂直に切立つのでは、こうした視覚効果は生まれない。撥水面に垂らした液体のように断面が湾曲することで、色の分解が生み出されるのではないか、、実物(?)を観察したからこそ得られた発見だった。実際、Liquid Glass のイントロダクションビデオでデザインチームが扱っているガラスオブジェクトも、よく見るとそうした形状をしている。


余談だが、ペーパーウェイトの下敷き(コンテンツレイヤー)になっている雑誌は、Wallpaper 誌が Apple Design team を特集した2022年1月号。WWDC25 の基調講演で Liquid Glass を世に紹介した Alan Dye 氏も、もちろん文章と写真の両方で登場する。

Inside Apple Park: the design team shaping future tech | Wallpaper