Messages App Extension
個人的に一番熱かったメッセージのエクステンションのリファレンスを読んで少し触ってみました
※ iMessage Appsは後で追記したいと思います😎👉 追記しました
- Xcode Version 8.0 beta
- iOS Version 10.0 beta
Create an app extension that interacts with the Messages app and lets the user send text, stickers, media files, and interactive messages. Update interactive messages, changing the message’s state as users take turns interacting with it.
Mwssages内でアプリを介してテキストはもちろん、ステッカー、メディアファイル、対話型のメッセージを送れるようになったようです
対話型メッセージ:ターン性の可変型メッセージ(Messagesで遊戯王ができるイメージです)
App Extensionの作成は主にiMessage appかSticker Packsの2種類に分かれます
Sticker Packs
Sticker packs simply provide static sets of stickers. They do not require any code. You add stickers by dragging image files into the Sticker Pack folder inside the Stickers assets catalog.
コードを書く必要がないただ画像をセットしたもの(クリエイターさんもXcodeを開くようになりますね☺️)
ただし以下の仕様を満たす必要があるみたいです
- フォーマットはPNG,APNG,GIF,JPEG
- サイズは500KB未満
- 大きさは100x100[pt]から206x206[pt]
Always provide @3x images (300 x 300 pixels to 618 x 618 pixels). The system generates the @2x and @1x versions by downscaling the @3x images at runtime.
@3xから@2xと@1xが生成されるってことは@3xだけ作ればいいのかな?
作った画像の大きさに合わせてインスペクタのサイズを選ぶ(表示される時の大きさになる)
- Small. 100 x 100 points.
- Medium. 136 x 136 points.
- Large. 206 x 206 points.
ちなみにGIFを使ってみたのですが、もちろんちゃんと動いてました
iMessage Apps
iMessage apps leverage the full framework to interact with the Messages app.
Messagesの対話の中にアプリケーションを組み込めるフレームワークが提供されています
ちなみにサンプルが公開されているので見てみると分かりやすいです
- MSMessagesAppViewController: Messages内の処理を判別しビューの表示をさせるなどするViewControllerの役割
- MSStickerBrowserViewController: 上記のSticker Packsで提供されるステッカーブラウザをカスタマイズする時に使う
- MSConversation: Messagesの入力フィールドに文字やステッカー、添付ファイルの入力が行える
- MSMessage: 会話の中でインタラクティブなメッセージを作成できる(これが遊戯王ができるクラス)
- MSSession: 4で会話の相手も操作対象にする場合はこのセッションを管理しなくてはならない
MSMessagesAppViewController
- 会話の内容やどのメッセージが選択されたかを判別したり画面遷移するメソッドが用意されている
-
MSMessagesAppPresentationStyle
というenumで表示する画面の大きさ(compact
,expanded
)を定義している
サンプルコードではwillBecomeActive:
とwillTransition:
で画面の大きさを判別して遷移先のViewControllerを変えてる
このcompact
とexpanded
はユーザーがいつでも切り替えられるようになっているので、画面設計時にはコンテンツの配置に注意が必要です(StackViewのありがたみが分かります)
画面サイズについて
これらの画面サイズがどのように使い分けられているかと変更の方法を簡単に調べてみました
compact
- Extensionが起動した時(
willBecomeActive:
が呼ばれる時) -
expanded
状態でナビゲーションバー右のボタンをタップした時
expanded
- メッセージ(
MSMessage
)をタップした時 -
compact
状態でツールバー右のボタンをタップした時
requestPresentationStyle
requestPresentationStyle:
を使用すれば画面サイズの変更をリクエストできるようになります
※ ユーザーがもし上記のような画面サイズの変更が行われる操作をしていた場合はそちらが優先されます
MSStickerBrowserViewController
-
MSStickerView
(ステッカー)を簡単に管理できるViewController - デフォルトでドラッグ&ドロップができてステッカーを剥がして貼るようなアニメーションも付いてくる
-
MSStickerBrowserViewDataSource
プロトコルに準拠すること(TableViewみたいな感じ)
MSConversation
- 会話の中で何が選択されたかどこに何を発言するかを管理するクラス
-
selectedMessage
が現在選択されているメッセージ(MSMessage
) -
insert:
やinsertAttachment:
でステッカーや添付ファイルを貼れる
サンプルコードではselectedMessage
から会話のセッションを見て作業しているアイスクリームの判別をしている
会話ユーザーの特定
MSMessagesAppViewController
のactiveConversation
を使用すると、どのユーザーが会話に参加しているのか特定ができます
※ シミュレーターでは下記識別子がメッセージの変更やMSMessagesAppViewController
のwillBecomeActive:
のタイミングで書き換わってしまいます😦バグ?
localParticipantIdentifier
- 自分自身の識別子です。これはデバイスの初期化かExtensionがアンインストールされない限り同じ値を持ち続けます
remoteParticipantIdentifiers
- 会話に参加している他の人の(このデバイスから定義した)識別子です。これも上記と同じで初期化かアンインストールで値が変わります
ユーザー名の表示
上記の識別子を"$\(localParticipantIdentifier.uuidString)"
のように使うとユーザー名を表示できるようになります ※ 現状できないです😐
MSMessage
- インタラクティブなメッセージを作成できる
- 自分だけでなく会話の参加者が皆操作できるがセッション(
MSSession
)の管理が必須になる
MSMessage
の中身はURL
で外観はMSMessageLayout
で構成されている
guard let components = NSURLComponents(string: myBaseURL) else {
fatalError("Invalid base url")
}
let size = NSURLQueryItem(name: "Size", value: "Large")
let count = NSURLQueryItem(name: "Topping_Count", value: "2")
let cheese = NSURLQueryItem(name: "Topping_0", value: "Cheese")
let pepperoni = NSURLQueryItem(name: "Topping_1", value: "Pepperoni")
components.queryItems = [size, count, cheese, pepperoni]
guard let url = components.url else {
fatalError("Invalid URL components.")
}
message.url = url
MSMessageTemplateLayout
大抵MSMessageLayout
は直接サブクラス化することはなくMSMessageTemplateLayout
をインスタンス化して使う
このテンプレートの中のプロパティに値を入れれば良い
captionの非表示
セッションではcaption
に何も入れなければ自動で画像だけのレイアウトになるとありますが、今の所灰色の背景が残ってしまいます😩
MSSession
-
MSMessage
に持たせることができ、特定のメッセージを更新する時はこいつを指定する - セッションを持たせたい場合は
init(session:)
でメッセージを生成する - セッションを指定した場合、セッションが使用されて初めてメッセージは表示される
- 同じセッションのメッセージを更新した場合は会話の一番下に移動して内容が変更される(その場で変更もできるらしい)
特定のセッションのメッセージを更新する例
-
selectedMessage
をKVOで監視してまたはwillTransition:
でタップされたMSMessage
を特定する - 上記の通知が来たら、内容やレイアウトなりを変更した
MSMessage
を生成する(この時init(session:)
でセッションを指定すること) - 送信する時に
insert:localizedChangeDescription:
メソッドを使えばchangeDescription
に元あった場所に変更の説明を残せる