LINEのようなメッセージをやりとりするアプリを作ります。
講義の目標
- mBaas(Nifty Cloud Mobile Backend)を使ったサーバ連携を利用を理解すること
- プッシュ通知を使ったアプリ開発ができるようになること
NCMB(Nifty Cloud Mobile Backend)の利用
NCMBとは
NCMB(Nifty Cloud Mobile Backend)はスマートフォンアプリでよく利用される汎用的な機能をクラウドから提供するサービスです。
クラウド上に用意された機能をアプリ側でAPIで呼び出すだけで利用できるので、サーバー開発・運用不要でよりリッチなバックエンド機能をアプリに実装することができます。
このようなモバイルアプリ開発のサーバ連携をサポートするサービスの事と mBaas といいます。
NCMBでできること
NCMBはモバイルアプリ開発でよく使われる下記機能を利用することができます。
iOSはもちろn、AndroidやUnity、Javascriptにて利用できるようになっています。
- プッシュ機能
- 会員管理・認証
- SNS連携(Facebook、Twitter、Googleなど)
- データストア
- ファイルストア
- 位置情報検索
アカウント作成
NCMBを利用するにはniftyのアカウント登録が必要です。
下記ページよりアカウント登録してください。
@nifty会員の登録(無料)をクリックします。

ユーザ名、パスワード、メールアドレスを入力して登録ボタンをクリックします。

登録内容を確認して登録するボタンをクリックします。

ログインボタンをクリックします。

先程登録したユーザ名とパスワードを入力してログインボタンをクリックします。

利用規約の画面が表示されます。規約内容を確認して同意のチャックをして、アカウント登録をクリックします。

アプリ新規作成になりますのでmessengerと入力して新規作成ボタンをクリックします。

次の画面でAPIキーが表示されます。アプリケーションキーとクライアントキーをコピーしてメモしておいてください。

これでNCMBのアカウント登録は完了です。
プロジェクト新規作成
MessengerでXcodeプロジェクトを新規作成してください。
使用するテンプレートはSingle View Applicationとなります。


| 入力項目 | 入力値 |
|---|---|
| Product Name | Messenger |
| Team | None |
| Oganization Name | 任意(”ALJ”など自分が所属している組織の名前を入れる) |
| Oganization Identifier | jp.co.al-j |
| Language | Swift |
| Devices | iPhone |
| Use Core Data | チェックを外す |
| include Unit Tests | チェックを外す |
| include UI Tests | チェックを外す |
Cocoapods設定
プロジェクトフォルダをターミナルにドラッグします。

ターミナルの画面でpod initを実行します。
pod init |
これでPodfileがプロジェクト内に作成されますので、openコマンドで開きましょう。
open Podfile |
テキストエディタが開いてPodfileを編集できますので、下記内容になるように修正し、保存してください。
Podfile
platform :ios, '9.0' |
ターミナルに戻り下記コマンドでNCMBのライブラリをダウンロードします。
pod install |
このように表示されればOKです。

一度Xcodeプロジェクトを閉じて、下図のとおりxcworkspaceからXcodeを開き直してください。

NCMB初期設定
次に、NCMBの初期設定をおこないます。
NCMBはObjective-Cという言語で作られており、Swiftで利用する為には、Objective-CからSwiftへ橋渡しする為のファイル(Bridging-Header.h)を作成し、Swiftで扱えるように設定する必要があります。
まずは橋渡しする為のファイル(Bridging-Header.h)を作成しましょう。
プロジェクトの「Messenger」フォルダーで右クリックをし、「New Files..」を選択します。
「Header File」を選択し、「Next」を押します。
Save Asに「Messenger-Bridging-Header.h」と入力して「Create」ボタンを押します。
「Messenger-Bridging-Header.h」を以下へ編集します。
Messenger-Bridging-Header.h#import <NCMB/NCMB.h>

Xcodeへ「Messenger-Bridging-Header.h」を読み込ませる為の設定をします。
「Messenger」プロジェクトの「Build Settings」の「Objective-C Bridging Header」に「Messenger/Messenger-Bridging-Header.h」を指定します。

続いて、下記のようにAppDelegate.swiftにimport NCMBを追加し、NCMB.setApplicationKeyメソッドの引数に、NCMBのアプリ作成で生成されたアプリケーションキーとクライアントキーを設定します。
AppDelegate.swiftimport UIKit
//////////////// ▼▼ 追加 ▼▼ ////////////////
import NCMB
//////////////// ▲▲ 追加 ▲▲ ////////////////
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//////////////// ▼▼ 追加 ▼▼ ////////////////
NCMB.setApplicationKey("【アプリケーションキー】", clientKey: "【クライアントキー】")
//////////////// ▲▲ 追加 ▲▲ ////////////////
return true
}
これでNCMBと連携する準備は完了です。
ログイン・会員登録機能実装
画面デザイン
Main.storyboardを開いて、下図のとおりViewControllerを選択してEditor -> Embed In -> Navigation Controllerを選択してください。

そうすると下図のとおりViewControllerの前にNavigation Controllerが追加されます。

下図を参考にログイン画面・会員登録画面を作ってください。
ViewControllerを追加したので、下表のとおりにViewControllerのswiftファイルを作成して関連付けてください。
| 画面名 | swiftファイル名 |
|---|---|
| ログイン画面 | LoginViewController.swift |
| ユーザ登録画面 | UserRegisterViewController.swift |





ユーザID、パスワード入力用のTextField、ログイン、新規ユーザ登録、新規登録のアクションができるようにButtonを配置してください。

ViewControllerからログイン画面にSegue(Show)を追加します。

ナビゲーション部分にタイトルを入れます。下図のようにNavigation Itemをナビゲーションバーの部分にドラッグすればタイトルを設定できるようになります。

SegueのidentifierをtoLoginにします。

次にログイン画面の新規ユーザ登録ボタンからユーザ登録画面でSegue(Show)を追加し、identifierはtoRegisterにしてください。

IBAutlet、IBActionも下図のとおりに設定してください。


ログインチェック
最初にViewControllerにてログイン状況を判断し、まだログインしていなければLoginViewControllerに遷移するようにします。
ViewController.swift
import UIKit |
この状態でRunしてシュミレータで確認してみましょう。まだログインしていませんので、起動後すぐにログイン画面へ遷移すればOKです。

会員登録機能実装
次にユーザ登録画面にてユーザ登録する処理を追加します。UserRegisterViewControllerにNCMBモジュールをimportします。
UserRegisterViewController.swift
import UIKit |
そしてIBActionのuserRegisterButtonTappedメソッドの箇所にNCMBにユーザ登録する処理を追加します。
UserRegisterViewController.swift
@IBAction func userRegisterButtonTapped(_ sender: AnyObject) { |
NCMBにユーザを作成する場合にはNCMBUserインスタンスを生成します。NCMBUserインスタンスにユーザID(userName)とパスワード(password)をセットし、
さらにACL(アクセス権限)設定をセットし、signUpInBackgroundWithBlockメソッドでユーザ登録を行います。
これですでにNCMBにてユーザ登録できるようになっています。
パスワード入力欄は「●」と表示されるように設定しましょう。以下の処理を追加します。
UserRegisterViewController.swiftoverride func viewDidLoad() {
super.viewDidLoad()
//////////////// ▼▼ 追加 ▼▼ ////////////////
//passwordの入力文字を「●」で表示する
passwordTextField.isSecureTextEntry = true
//////////////// ▲▲ 追加 ▲▲ ////////////////
}
Runを実行してユーザ登録してみましょう。ユーザID、パスワードはとりあえずともにuser1でユーザを作成してください。

ユーザ作成完了すると下図のようにアラート画面が表示されるはずです。

NCMBの管理画面でユーザ登録しているか確認してみましょう。
NCMBにログインしてください。
アプリをMessengerにして会員管理の箇所をクリックします。
すると下図のようにuser1のレコードが1行追加されていると思います。

このようにNCMBを使えば会員機能を簡単に実装する事ができます。
ログアウト機能実装
ユーザ作成が完了するとアプリはログイン状態になっています。
今回は擬似的に複数のユーザを作成したり、切り替えたりしたいので、まずログアウト機能を実装しておきます。
Main.storyboardを開き、ViewControllerにBar Button Itemを追加し、IBActionでlogoutButtonTappedメソッドを追加します。



追加したlogoutButtonTappedボタンにログアウト機能を追加します。
ViewController.swift
func loginCheck(){ |
NCMBUser.logOutでログアウトします。
ログアウトしたらまた自動的にログイン画面を表示するようにloginCheckメソッドを実行しています。
それではRunしてログアウトできるか確認しましょう。

ログイン機能実装
ユーザ登録できるようになりましたので、続いてログイン機能を実装していきましょう。
次はLoginViewControllerのIBActionのloginButtonTappedメソッドにログイン部分のコードを追加します。
LoginViewController.swift
|
画面にあるユーザIDとパスワードを入力するテキストフィールド(userIdTextField、passwordTextField)の値をNCMBUser.logInWithUsernameInBackground の引数にセットして実行する事によりNCMBに対してログインを実行します。
ユーザIDとパスワードが正しければ、userの中にユーザ情報が格納されます。ログイン失敗時はerrorに値が入っていますので、if (error != nil)で条件分岐して判断する事ができます。
それでは先ほど作成したuser1でログインできるか確認してみましょう。
下記のようにデバッグエリアにログイン成功と表示されればOKです。

パスワード入力欄は「●」と表示されるように設定しましょう。以下の処理を追加します。
LoginViewController.swiftoverride func viewDidLoad() {
super.viewDidLoad()
//////////////// ▼▼ 追加 ▼▼ ////////////////
//passwordの入力文字を「●」で表示する
passwordTextField.secureTextEntry = true
//////////////// ▲▲ 追加 ▲▲ ////////////////
}
ユーザを追加
今回のアプリは複数ユーザを想定したものですので、複数ユーザを予め作成しておきます。
会員登録、ログアウトを繰り返し、user2、user3でユーザID、パスワードでユーザを作成してください。
このようにNCMB管理画面の会員管理でユーザが作成されているか確認しておきましょう。

ユーザ一覧画面
ユーザ一覧を確認できる画面を作っていきます。今回はその機能をViewController.swiftで実装していきます。
まずはMain.storyboardでViewControllerにTableViewを配置し、Prototype Cellを1にし、IBOutletでtableViewとして関連付けます。


TableCellのidentifierをCellに設定します。

続いて下記コードを実装します。
ViewController.swift
//////////////// ▼▼ プロトコル追加 ▼▼ //////////////// |
続いて、ユーザリストをNCMBから取得します。fetchUserListメソッドを作って実装します。
//////////////// ▼▼ 追加 ▼▼ //////////////// |
NCMBのデータストアのデータを取得する場合にはNCMBQueryを使います。NCMBQueryを初期化するときにclassNameを指定して取得するデータストアのテーブルを指定します。今回は会員のテーブルなのでuserを指定します。
NCMBQuery.whereKeyにて取得する条件を追加する事ができます。今回はログインしているユーザは対象外にする条件を追加しています。
そしてNCMBQuery.findObjectsInBackgroundWithBlockにてデータ取得を行っています。
この処理も処理完了時の処理を記述できるようになっていますので、errorの有無で処理成功有無を確認し、成功している場合にはusersのメンバ変数にセットし、tableViewの更新処理をしています。
fetchUserListメソッドをloginCheckメソッドで呼び出し、画面が表示する度にユーザリストを取得するようにします。
func loginCheck(){ |
この状態でRunしてみましょう。ログアウトしている場合はログインすれば、下記のようにユーザIDがTableViewに表示されます。

これでユーザ一覧機能は完了です。
ユーザ選択時にメッセージルームを作成
ユーザ一覧のセルをタップしたら、ユーザ双方でメッセージを交換できるようにルーム(部屋)を作成します。
まずNCMBにどのようなテーブル構成にすべきか考えましょう。
今回は、メッセージをやりとりするために下記のテーブルをデータストア作成します。
| テーブル名 | 説明 |
|---|---|
| Room | メッセージをやりとりするルーム(部屋)を管理するテーブル、メッセージをやりとりするユーザを管理 |
| Message | メッセージ内容を管理するテーブル。RoomのIDを保持 |
ユーザ一覧からユーザを選択すると、自ユーザ(ログインユーザ)と選択ユーザを含めたルームを作り、そのルーム単位でメッセージを送信できるようにします。
Roomデータ保存
それではまず、ユーザを選択したときにRoomテーブルに保存する処理を追加します。
//////////////// ▼▼ 追加 ▼▼ //////////////// |
Roomを作成完了時にどのユーザがルーム登録するのかを管理するためにRoomUserデータも登録します。
これで一度Runしてユーザ一覧画面でユーザを選択してください。
下図のようにRoomのデータが保存されれば成功です。

既にRoomデータ作成済みかチェック
一度選択したユーザをまた選択した場合にはルームを作らないようにします。
//////////////// ▼▼ 追加 ▼▼ //////////////// |
checkRoomExistメソッドを作り、TableViewのセルタップ時にそのメソッドで確認してからRoomテーブルを作成するようにします。
// MARK: - TableView Delegate |
この状態でRunして動作確認しておきましょう。
下図のように同じユーザを選択した場合にはRoom作成済が出力され、Room、RoomUserのテーブルが追加されない事を確認してください。

メッセージ画面
それでは選択したユーザ通しでメッセージをやりとりできるようにします。
画面デザイン
Main.storyboardを開き、1つViewControllerを追加し、ユーザ選択画面からSegue(Show)でSegueを追加して接続してください。

SegueのidentifierはtoMessageにします。

ユーザ一覧画面と同様にTableViewを配置し、TableViewCellのidentifierもCellにしておきます。

また、TextFieldとButtonを下図のように配置してください。

AutoLayoutの設定をしておきます。



これで画面デザインは完了です。新しくViewControllerを追加しましたのでMessageViewController.swiftを新規作成し、画面の関連付けをしておいてください。

IBOutlet、IBActionをしておきます。


メッセージ受信
まずはメッセージ受信の処理を追加していきます。
MessageViewController.swift
import UIKit |
基本的にはユーザ一覧画面と同じように、NCMBQueryでMessageテーブルの内容を取得しています。取得条件は前の画面(ユーザ一覧画面)から渡されるRoom情報をもとに取得しています。
取得した内容をTableViewに更新して表示させる処理を実装しています。
また前の画面(ユーザ一覧画面)から画面遷移するようにしておきます。
ViewController.swift
// すでにルーム作成されているかチェック |
ViewController.swift
//////////////// ▼▼ 追加 ▼▼ //////////////// |
prepareForSegueメソッドを追加して画面遷移のタイミングでroomデータを次の画面に送るようにしています。
ViewController.swift
//////////////// ▼▼ 追加 ▼▼ //////////////// |
メッセージ送信処理
メッセージを取得して表示する機能は実装しましたが、送信して保存する処理を実装していませんので実装します。IBActionのsendMessageButtonTappedに送信処理を記述していきます。
MessageViewController.swift
// MARK: - IBAction |
この状態でメッセージを保存する事ができましたが、この状態では、テキストフィールドのキーボードが表示しっぱなしになりますので、エンターキーを入力したらキーボードを閉じるようにします。
MessageViewController.swift
//////////////// ▼▼ 追加 ▼▼ //////////////// |
この状態で実行してみましょう。送信ボタンをクリックしたらメッセージが保存され、TableViewに保存されればOKです。

NCMB管理画面にもMessageテーブルが作成され、送信内容が登録されている事を確認しましょう。

これでメッセージ画面の基本的な処理は完了です。
プッシュ通知設定
LINEアプリのようにユーザがメッセージを送信したら、Push通知送信し、相手のユーザに通知してあげる機能を実装してみましょう。
プッシュ通知の流れ
プッシュ通知についての概要はApple公式ドキュメント「Local および Push Notification プログラミングガイド」で解説されていますが、単純化すると下記の流れとなります。
- iPhone・iPadのアプリでプッシュ通知を許可し、APNSからデバイストークンを取得
- デバイストークンを何らかの方法でプロバイダに送信
- プロバイダよりプッシュ許可したデバイスを対象にAPNS通知を依頼
- APNSからデバイスへ通知し、デバイスでサウンド・バッジ・アラート等を出す

プッシュ通知の前提
プッシュ通知を実装するには下記の前提条件があります。
- iOS Developer Programの登録が必要
- iOS実機を持っている
プッシュ通知事前設定
プッシュ通知を利用するには下記の作業が必要です。
- App IDの登録
- プッシュ通知の有効化と証明書のダウンロード
- 証明書を所定の形式(*.pem)に変換
App IDの登録
iOS Dev Centerにアクセスし、開発者登録されているIDでログインします。
https://developer.apple.com/membercenter/
開発者登録しているアカウントでログインします。

Certificates,Identifiers & Profilesを開きます。

App IDsを選択してから+ボタンをクリックします。

| 項目 | 概要 |
|---|---|
| App ID Description | AppIDsの一覧で表示される名称です。アプリの概要を表す名称を入力します。 |
| App ID Suffix | Explicit App IDを選択し、アプリのBundle Identifierと同様の名称を入力します。例)com.terakoya.Messenger |
| App Services | アプリで使用するサービスです。プッシュ通知を利用するため「Push Notification」をチェックします。 |




プッシュ通知の有効化と証明書のダウンロード
App IDで「Configurable」となっているプッシュ通知を有効にするため、認証局より証明書を取得します。
MACでキーチェーンアクセスを開き、証明書アシスタント⇒認証局に証明書を要求を開きます。

証明書アシスタントで証明書情報を入力し、「続ける」を押下します。
| 項目 | 概要 |
|---|---|
| ユーザのメールアドレス | デベロッパ登録したメールアドレス |
| 通称 | デベロッパの名前(デベロッパ登録したものと同じでなくてもOK) |
| 要求の処理 | ディスクに保存を選択 |

CertificateSigningRequest.certSigningRequestの保存画面となるため、任意の場所に保存します。

iOS Developer Centerに戻り、登録したApp IDを選択し、Editより編集画面を開きます。


編集画面のPush Notificationsより、証明書を作成します。
証明書は開発用と製品用をそれぞれ必要に応じて作成する必要がありますが、手順は同じです。Create Certificateを押下します。

Continueを押下します。

Choose Fileを押下するとファイル選択画面となるため、保存しておいたCertificateSigningRequest.certSigningRequestを指定します。

CertificateSigningRequest.certSigningRequestが選択されたらGernerateボタンを押下します。

証明書の作成に成功すると証明書がダウンロード可能になるため、Downloadボタンよりダウンロードします。

ダウンロードした証明書をダブルクリックすると、キーチェーンに登録されます。
今回は開発用(Development)の証明書のため、Apple Development IOS Push Servicesとなっています。

iOS Dev CenterのApp IDsより該当App IDを確認すると、Push NotificationsがEnabledになっています。
※製品用(Distribution)の証明書も同様の手順で作成するとEnabledになります。

証明書を所定の形式(*.pem)に変換
キーチェーンアクセスの左ペインより「証明書」を開き、該当証明書を選択した状態で、Apple Development IOS Push Services:アプリID”を書き出すを選択します。

任意の場所へ、「個人情報交換(.p12)」の形式で保存します。
便宜上、今回はデスクトップに下記の名前で保存します。push_develop.p12で保存しましょう。

書き出した証明書のパスワード入力画面となるため、何も入力せずそのままOKを押下します。

キーチェーンにアクセスするためのパスワードを聞かれた場合、入力します。
(通常Macのログインパスワードです。)

デスクトップにファイルが保存されたことを確認します。

NCMBにプッシュ通知設定

アプリ側プッシュ通知設定


AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { |
この状態でRunしてみましょう。下図のようにプッシュ通知の許可を求めるアラートが出ます。OKを押す事によりデバイストークンがNCMBに登録されます。
※シュミレータではプッシュ通知のデバイストークンは作成されませんので、実機で確認してください。

実機でプッシュ通知の許可をするとNCMB管理画面のデータストア -> installationのテーブルに端末の情報が保存されます。

NCMB管理画面からプッシュ通知を送る
プッシュ通知の準備が整いましたので、NCMB画面からプッシュ通知をしてみたいと思います。
NCMB管理画面でプッシュ通知をクリックし新しいプッシュ通知ボタンをクリックします。

タイトル、メッセージ欄に任意に文字を入力して、配信日時は今すぐ配信をエランでください。

iOS端末に配信するのチェックボックスを有効にしてプッシュ通知を作成するをクリックしてください。

しばらくすると、アプリ端末にプッシュ通知が届きます。
実機でないと確認できません。

メッセージ送信時にルームメンバーにプッシュ通知
それではメッセージ送信時にメンバーにプッシュ通知をするようにしたいと思います。
下記のとおりpushChannelSetと、pushNotificationメソッドを追加します。
MessageViewController.swift
//////////////// ▼▼ 追加 ▼▼ //////////////// |
pushChannelSetメソッドでは、ログインユーザのinstallation(プッシュ通知配信端末)に対してチャネルの登録をしています。チャネルとはプッシュ通知を配信する端末をグルーピングするものです。今回はメッセージをやりとりするルーム単位でチャネルを作りたいため、ログインユーザがこの画面にアクセスしたときにRoomのIDをチャネルとしてinstallationに追加しています。
pushNotificationメソッドでは、そのチャネルに対してプッシュ通知を送信する処理を記述しています。
つぎに、viewDidLoadでチャネル登録処理が実行されるようにします。
MessageViewController.swift
override func viewDidLoad() { |
メッセージ送信後にプッシュ通知されるようにします。
MessageViewController.swift
@IBAction func sendMessageButtonTapped(sender: AnyObject) { |
プッシュ通知受信を検知
この画面でメッセージをやりとりしているときに、相手側がメッセージを送信したのを検知するための仕組みを追加します。画面が表示されるタイミングで呼ばれるviewDidAppearメソッドにNSNotificationCenter.defaultCenter().addObserverメソッドを使ってプッシュ通知を検知するようにしています。また画面が非表示になったときにはその検知を解除するようにもしています。
MessageViewController.swift
override func viewDidAppear(animated: Bool) { |
NSNotificationCenter.defaultCenter().addObserverでremotePushの名前のイベント(AppDelegateでプッシュ通知受信時に通知されるよう定義しています)が発生したら、updateメソッドを呼びさす設定をし、updateメソッドではfetchMessagesメソッドを実行してメッセージの再取得をしています。これを実装することによりこの画面でメッセージをやりとりがほぼリアルタイムに画面の再表示をせずにメッセージのやりとりができるようになります。
これでメッセンジャーアプリは完成です。
是非、複数端末にこのアプリをインストールして、メッセージのやりとりができる事を確認してみてください。
また、メッセージをやり取りする画面MessageViewControllerのUIもLineアプリのように吹き出しのイメージにするなどして改善していくといいでしょう。
メッセンジャーのUIを手軽に構築するにはJSQMessagesViewControllerというライブラリが有名ですので、そのライブラリを取り込んでみるといいでしょう。