[iOS 10] メッセージ拡張の作成方法

2016.09.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

iOS 10から、拡張機能(Extension)を作成することで、メッセージアプリで、ステッカー(LINEのスタンプみたいな感じ)、メディアファイル、及び、対話型のメッセージなどを送信することができるようになりました。

この拡張機能は、Messagesフレームワークを使用しますが、その作成方法には、「ステッカーパック」と「IMessageアプリ」の2種類があります。 今回は、このうちの「IMessageアプリ」を作成してみました。

なお、その他のメッセージ拡張については、下記をご参照下さい。
[iOS 10] メッセージ拡張 MSStickerBrowserViewControllerを使用したビューの作成
[iOS 10] メッセージ拡張 MSMessageTemplateLayoutによるテキストや画像(映像)の配置
[iOS 10] メッセージ拡張 MSSessionで「まるばつゲーム」を作ってみた
[iOS 10] メッセージ拡張 ノンプログラミングによるスタンプ作成
[iOS 10] メッセージ拡張 ノンプログラミングによるアニメーションスタンプ作成

2 プロジェクト作成

メニューから、File - New - Projectと辿って、iOSタブのiMessageからメッセージ拡張のプロジェクトが作成できます。

001

プロジェクト名をiMessageSampleとして作成されたプロジェクトは次のような感じです。

002

通常のアプリiMessageSampleに拡張MessageExtensionを追加したような形になっていますが、スキームはMessageExtensionの分しかありません。

003

ストーリーボードは、次のようになっており、起動時のコントローラーは、MSMessagesAppViewControllerを継承したMessagesViewControllerになっています。

004

3 MessagesViewController

MSMessagesAppViewControllerには、見慣れた、viewDidLoaddidReceiveMemoryWarningの他に次のようなコールバックメソッドが有ります。

下記は、テンプレートで生成されたコードのコメントを日本語にしたものです。

事後、このコールバックメソッドを実装することで、メッセージ拡張を完成させて行きます。

<br />import UIKit
import Messages

class MessagesViewController: MSMessagesAppViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Conversation Handling
    override func willBecomeActive(with conversation: MSConversation) {
        // アクティブ状態に移行した際に呼ばれます。
        // UIの構築はここで行います。
        // 前回の設定を復元する作業は、ここで行います。
    }
    override func didResignActive(with conversation: MSConversation) {
        // 非アクティブ状態に移行した際に呼ばれます。
        // ユーザがエクステンションを閉じたり、別のメッセージに移行した際に、呼びだされます。
        // リソース開放・ユーザデータの保存・タイマー開放などを行い、次回起動時に必要に処理をここで行います。
    }
    override func didReceive(_ message: MSMessage, conversation: MSConversation) {
        // リモートデバイス上でこのエクステンションのインスタンスが起動された時、呼びだされます。
        // メッセージに応答してUIを更新するトリガーに使用できます。
    }    
    override func didStartSending(_ message: MSMessage, conversation: MSConversation) {
        // ユーザが送信ボタンをタップした時に呼ばれます。
    }
    override func didCancelSending(_ message: MSMessage, conversation: MSConversation) {
        // ユーザがメッセージを送信せずに削除した時呼ばれます。
        // 削除されたメッセージに関連するクリーンアップを行います。
    }
    override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
        // コンパクトモードとフルスクリーンモードの変化の前に呼ばれます
        // 変更モードを知ることができます。
    }
    override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
        // コンパクトモードとフルスクリーンモードの変化の後に呼ばれます
       // モード変更に関する処理をここで完成させます。
    }
}

4 コンパクトモードとフルスクリーンモード

メッセージ拡張のUIは、コンパクトモードとフルスクリーンモードの2種類があります。

005 006

ボタンで切り替えが可能です。なお、拡大縮小はプログラムからも可能ですが、ユーザがいつ切り替えるか分からないので、常に両方に対応しておく必要があります。

5 ボタンの追加

ストーリーボードで、最初に置かれていたHello Worldのラベルを削除し、代わりにUIButtonを置きました。 制約で中央にしておかないと、コンパクトモードでボタンが見えなくなってしまいます。

007

また、このボタンをタップした際のアクションを追加しました。

// MARK: - Action
@IBAction func tapButton(_ sender: AnyObject) {

}

6 メッセージ送信

ボタンをタップした際の処理に、メッセージの追加と、メッセージ拡張のウインドウを閉じる処理を書いてみました。

@IBAction func tapButton(_ sender: AnyObject) {
    // テキスト挿入
    self.activeConversation?.insertText("こんにちは。", completionHandler: { (error) in
        print("insearted! error:\(error)")
    })
    // 拡張を閉じる
    dismiss()
}

実行している様子です。

008 009 009-2

7 MSConversation

MSConversationクラスは、メッセージアプリでの会話を表現するクラスです。 このクラスを利用すると、現在選択中のメッセージや会話についての各種オブジェクトにアクセスできます。
参考: API Reference MSConversation

先のメッセージ追加では、activeConversationで、選択中のメッセージに関するMSConversationクラスを取得して、interTextメソッドでテキストを挿入していました。

今度は、MSConversationクラスのinsert(MSmessage)を使用して、画像やメッセージを含めたものを送信対象にしてみます。MSMessageのレイアウトには、MSMessageTemplateLayoutを使用しました。

// MARK: - Action
@IBAction func tapButton(_ sender: AnyObject) {
    let message = MSMessage()
    let template = MSMessageTemplateLayout()
    template.image = UIImage(named: "sample")
    template.caption = "勉強がばってね!"
    template.subcaption = "応援してます"
    message.layout = template
    self.activeConversation?.insert(message, completionHandler: { (error) in
        print("insearted! error:\(error)")

    })
    dismiss()
}

使用する画像は、リソースとして、Assets.xcassetsに、ドロップします。

010

上記を実行している様子は、次のとおりです。

012 014 013

8 アイコン

メッセージ拡張にアイコンを設定する場合は、MessageExtensionAssets.xcassetsに追加します。サイズは、正方形でなく4対3の横長です。 下図では、60✕45ptの2xに120✕90のpngをセットしています。

015

実行すると、次のように見えます。

016

9 最後に

今回は、最も基本的なメッセージ拡張の作成方法を試してみました。

WWDC2016のセッションでも話があったように、このメッセージ拡張は、Apple Storeで公開できたり、アプリ内課金も利用できるようですので、今後、色々なアプリが登場するのでしょうね。

10 参考にさせて頂いたリンク


iMessage + Apps
API Reference Messages Framework
iMessage Apps and Stickers, Part 1
iMessage Apps and Stickers, Part 2
SampleCode Ice Cream Builder: A simple Messages app extension