ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Writing Toolsの導入
アプリにおいてユーザーによるテキストの校正、書き直し、変換をサポートするWriting Tools(作文ツール)の機能をご紹介します。いずれかのテキストビューで記述したテキストをユーザーがブラッシュアップできるようにするため、Writing Toolsとアプリがどのように連携するかについて詳しく解説します。テキストの取得および処理の仕組みや、カスタムのテキストビューでWriting Toolsをサポートする方法を習得できます。
関連する章
- 0:00 - Introduction
- 3:42 - Native text views
- 7:03 - Controlling behavior
- 8:23 - Protecting ranges
- 9:03 - Custom text views
- 11:44 - Next steps
リソース
関連ビデオ
WWDC23
WWDC22
WWDC21
WWDC19
-
ダウンロード
「Get started with Writing Tools」 へようこそ Liu Dongyuanです テキスト入力や国際化を担当しています Writing Tools(作文ツール)は あらゆる種類のアプリの テキストビューで利用できる 新しい機能スイートです Writing Toolsは記述したテキストを ブラッシュアップするのに役立ちます 本セッションではまず Writing Toolsの概要をご紹介します 次に Writing Toolsとネイティブの テキストビューとの連携について また アプリに合わせて Writing Toolsの動作を制御する方法 引用文やコードブロックなどの 特定の範囲のテキストを保護する方法 Writing Toolsをカスタムテキストビューで サポートする方法について説明します まず Writing Toolsの概要をご紹介します Writing Toolsは iOS iPadOS macOSのテキストビューで テキストの校正 書き直し 変換を サポートします 提案がインラインで表示されるため 変更をすばやくシームレスに確認して 反映できます ネイティブテキストビューでは テキストを選択すると Writing Toolsが キーボードの上側に表示されます また コールアウトバーの の隣にも表示されます
macOSでは コンテキストメニューや メニューでも利用可能です
ネイティブテキストビューで 選択したテキストにカーソルを合わせると アフォーダンスに従って パネルを開けます このようにテキストから簡単に Writing Toolsを起動できます Writing Toolsでできることについて 詳しく見ていきましょう
テキストを校正し スペルや文法上のエラーなどの 間違いを表示できます Writing Toolsの提案を 1つずつレビューすることができます
Writing Toolsではテキストを書き直したり より親しみやすく プロフェッショナルで 簡潔なスタイルに編集できます また テキストを要約したり 重要なポイントにまとめたり リストや表に変換したりもできます Writing Toolsは 編集不可のテキストにも使えます 結果はパネルに表示され その結果を コピーまたは共有することができます では 実際の例を紹介しましょう 例えば Writing Toolsの リリースパーティーを開くために 招待状を作成したとします 送信する前に間違いがないことを 確認したいと思います
Writing Toolsを コールアウトバーから起動します 次に を選択します
すごいですね 校正が終わると すべての提案がインラインで表示されます それぞれの変更をタップして確認できます
すべて問題なさそうなので をタップして変更を受け入れます 次に パーティーについて友人に ショートメッセージを送りたいと思います Writing Toolsを使えば テキストを要約して短くすることができます
要約をコピーまたは共有することもできます
最後に リリースパーティーに向けて 準備をしたいと思います 友人に 必要なものを 持ってくるようにお願いしました きれいに整った表にしたいと思います テキストを選択してWriting Toolsを起動し を選択します
どうでしょう
太字のテキストやリンクは すべてそのままになっています 素晴らしいと思いませんか ご覧のように Writing Toolsは テキストビューに さらなる機能をもたらす 強力なツールです サポートされている環境で アプリを実行すると Writing Toolsが自動的に表示されます 次に Writing Toolsとテキストビューが どのように連携するかについて説明し アプリへの統合方法をご紹介します 嬉しいことに UITextView NSTextView WKWebViewを使用している場合は 特に作業をすることなくそのまま動作します
ただ UITextViewまたはNSTextViewで Writing Toolsのフル機能を利用するには TextKit 2を使う必要があります TextKit 1を使っている場合は 書き直された結果をパネルに表示するという 限定的な機能しか利用できません
TextKit 2の詳細については こちらの関連セッションをご確認ください
Writing Toolsを呼び出したときに 内部では何が起きているのでしょうか
まず より良い結果をツールから得るために ユーザーによる選択範囲を 全文まで拡張します また モデルがテキストの文脈を 把握できるように 選択範囲の周囲にあるテキストも使用します
Writing Toolsは属性付き文字列による リッチテキストをフルサポートしています モデルは 関連するテキストが 書き直されたテキストに含まれている限り スタイル リンク 添付ファイルなどの 属性を保持します
最後に リストと表への 変換についてですが テキストビューでリストや表が サポートされている場合 NSTextListとNSTextTableを テキストストレージに送信します WritingToolsAllowedInputOptionsを使って テキストビューが表を処理するかどうかを 制御できます これについては後で説明します デモでお見せしたように モデルがテキストを処理している間 Writing Toolsセッションの実行中は アニメーションが表示されます セッションの実行中は アプリの同期を一時停止したり 誤編集を回避したりする必要があります そこで Writing Tools用にテキストビュー デリゲートメソッドを新たに導入しました
textViewWritingToolsWillBeginでは アプリの状態を Writing Tools用に 準備することができます 例えば 同期を一時停止したり テキストストレージに対する すべての直接操作を停止できます
textViewWritingToolsDidEndでは 同期を再開するなど アプリを元の状態に戻すことができます
またUITextViewに 新しいプロパティとして isWritingToolsActiveを追加しました これにより テキスト操作を行う際に Writing Toolsがテキストビューに操作を 実行していないかどうか確認できます
新しいデリゲートメソッドとプロパティは UITextViewとNSTextViewの両方で 利用できます
テキストが長い場合は 書き直されたテキストは 別々のチャンクで テキストビューに配信される場合があります モデルが実行中であることを示すために 処理されているテキストに アニメーションを適用します モデルが処理を終えた後 をタップすると 元のテキストと 書き直されたテキストを切り替えられます
校正の場合 提案された変更は 自動的に テキストビューに適用されます それぞれの提案を確認して 拒否することができます
Writing Toolsの実行中 基盤となるテキストストレージは どうなっているのでしょうか 実際には Writing Toolsは毎回 テキストストレージの変更を行います つまり Writing Toolsの実行中は テキストストレージの永続化はできません ユーザーが後で変更を元に戻せるように Writing Toolsの変更は 取り消しスタックにもプッシュされます アプリに合わせて Writing Toolsの動作を カスタマイズしたい場合もあるでしょう そのために テキスト入力特性に関する 各種のAPIを用意しました
デフォルトでは システムは可能な限り インラインでWriting Toolsを機能させます その場合は何もする必要はありません この方法がアプリに適さない場合は writingToolsBehaviorを.limitedに設定し Writing Toolsをパネル表示にするか .noneに設定して テキストビューの Writing Toolsを完全にオプトアウトできます
また writingToolsAllowedInputOptions を使用して テキストビューで リッチテキストや表を サポートするかどうか指定できます この設定をしない場合 テキストビューは プレーンテキストとリッチテキストを レンダリングできますが 表はレンダリングできないと想定します デキストビューがプレーンテキストのみを 受け付ける場合や 表を扱える場合は 該当するオプションを明示的に指定できます
最後に WKWebView向けに 同様のAPIも用意されています WKWebViewConfiguration経由で 同じ列挙型を指定できます WKWebViewsのデフォルトの動作は .limitedであることに注意してください フルに動作させたい場合は それを明示的に設定する必要があります
Writing Toolsセッションが 実行中であるかどうかを知るために isWritingToolsActiveプロパティを 確認または監視できます 次に Writing Toolsが無視する範囲を 指定する方法について説明します
例えば 特定の範囲を コードブロックとしてマークできる メモアプリを実装している場合や 引用文を含めることができる メールアプリがある場合などは それらの範囲をWriting Toolsで 書き直したくないかもしれません そこで UITextViewDelegateと NSTextViewDelegateの両方に 新しいデリゲートメソッドを追加しました これは 単に無視する範囲を返すだけで Writing Toolsはその範囲内の変更を 提案しません
WKWebViewの場合 「blockquote」や「pre」のようなタグは Writing Toolsによって 自動的に無視されます 最後に アプリがUITextViewとNSTextView以外の カスタムテキストビューを 持っている場合はどうでしょうか? 嬉しいことに 基本的な機能を 無料で簡単に入手できます 書き直されたテキストはパネルに表示され ユーザーはそのテキストをコピー 共有 またはテキストビューに適用できます
iOSとiPadOSでは カスタムテキストビューが UITextInteractionに対応している限り コールアウトバーやコンテキストメニューに Writing Toolsを無料で取り込めます UITextInteractionを使用できない場合 UIEditMenuInteractionとともに UITextSelectionDisplayInteractionを 導入することもできます 内部では Writing Toolsは UITextInputプロトコルに依存して テキストを読み書きし ポップオーバーをアンカーしています テキストインタラクションについての詳細は 過去のWWDCセッションをご確認ください
テキストインタラクションを使用しない テキストビュー用に 新たに UITextInputプロトコルにオプションの isEditableプロパティを追加しました これを使用して、テキストビューが 編集に対応しているかどうかを示します
Macでは カスタムテキストビューの コンテキストメニューとメニューに Writing Toolsが自動的に表示されます
テキストビューが NSServicesMenuRequestorを 使用していることを確認してください これはシステムがビューから内容を読み取り 内容をビューに書き戻すことを可能にする プロトコルです
NSResponderで validRequestor(forSendType:returnType:) をオーバーライドします すると コンテキストメニューが ビューに追加されている限りは Writing Toolsのメニュー項目が 無料で表示されるようになります こうした設定を行うことで あらゆるサービスやショートカットで アプリを利用できるようになります 詳しくは WWDC21の 「What's new in AppKit」をご覧ください
これらすべてをコードで見てみましょう テキストを表示するシンプルなビューと コピー機能を提供するメニューを用意しました Writing Toolsを導入するには validRequestor(forSendType:returnType:)を オーバーライドし NSServicesMenuRequestorで少なくとも writeSelectionメソッドを実装するだけです 編集可能なテキストビューの場合は Writing Toolsが書き直したテキストを テキストビューに送信できるように readSelectionメソッドも実装します validRequestorメソッドで sendTypeを確認することで テキストビューがリッチテキストを 処理するかどうかを判断できます これらすべてを行うと との両方が コンテキストメニューに表示されます 本セッションの内容は以上です 次のステップとして
アプリでWriting Toolsをぜひ試してください ほとんどの場合なにもする必要はありません そのまま動作します
新しいデリゲートメソッドを導入して Writing Toolsセッション中の アプリの状態を制御できます アプリに特別なニーズや機能がある場合は Writing Toolsの動作と 使用可能な 入力オプションを確認しましょう
カスタムテキストビューを使用する場合 ほんの少しの手順で Writing Toolsの機能を 導入できます では Writing Toolsでの文書作成を お楽しみください ご視聴ありがとうございました
-
-
5:28 - Text view delegate methods for Writing Tools
func textViewWritingToolsWillBegin(_ textView: UITextView) { // Take necessary steps to prepare. For example, disable iCloud sync. } func textViewWritingToolsDidEnd(_ textView: UITextView) { // Take necessary steps to recover. For example, reenable iCloud sync. } if !textView.isWritingToolsActive { // Do work that needs to be avoided when Writing Tools is interacting with text view // For example, in the textViewDidChange callback, app may want to avoid certain things when Writing Tools is active }
-
7:11 - Opt-out of the full experience
textView.writingToolsBehavior = .limited textView.writingToolsBehavior = .none
-
7:31 - Specify accepted text formats
textView.writingToolsAllowedInputOptions = [.plainText] textView.writingToolsAllowedInputOptions = [.plainText, .richText, .table]
-
7:55 - WKWebView
// For `WKWebView`, the `default` behavior is equivalent to `.limited` extension WKWebViewConfiguration { @available(iOS 18.0, *) open var writingToolsBehavior: UIWritingToolsBehavior { get set } } extension WKWebViewConfiguration { @available(macOS 15.0, *) open var writingToolsBehavior: NSWritingToolsBehavior { get set } } extension WKWebView { /// @discussion If the Writing Tools behavior on the configuration is `.limited`, this will always be `false`. @available(iOS 18.0, macOS 15.0, *) open var isWritingToolsActive: Bool { get } }
-
8:48 - Protecting ranges
// Returned `NSRange`s are relative to the substring of the textView’s textStorage from `enclosingRange` func textView(_ textView: UITextView, writingToolsIgnoredRangesIn enclosingRange: NSRange) -> [NSRange] { let text = textView.textStorage.attributedSubstring(from: enclosingRange) return rangesInappropriateForWritingTools(in: text) }
-
9:58 - Indicate your text view supports editing
protocol UITextInput { @available(iOS 18.0, macOS 15.0, *) optional var isEditable: Bool { get } }
-
10:58 - Simple view that supports Copy
class CustomTextView: NSView, NSServicesMenuRequestor { required init?(coder: NSCoder) { super.init(coder: coder) self.menu = NSMenu() self.menu?.addItem(NSMenuItem(title: "Custom Text View", action: nil, keyEquivalent: "")) self.menu?.addItem(NSMenuItem(title: "Copy", action: #selector(copy(_:)), keyEquivalent: "")) } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) // Custom text drawing code... } }
-
11:05 - View extension to support Writing Tools
class CustomTextView: NSView, NSServicesMenuRequestor { override func validRequestor(forSendType sendType: NSPasteboard.PasteboardType?, returnType: NSPasteboard.PasteboardType?) -> Any? { if sendType == .string || sendType == .rtf { return self } return super.validRequestor(forSendType: sendType, returnType: returnType) } nonisolated func writeSelection(to pboard: NSPasteboard, types: [NSPasteboard.PasteboardType]) -> Bool { // Write plain text and/or rich text to pasteboard return true } // Implement readSelection(from pboard: NSPasteboard) as well for editable view }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。