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
というライブラリが有名ですので、そのライブラリを取り込んでみるといいでしょう。