プッシュ通知は従来のマーケティング手法で言えばメールマーケティングに相当します。つまり一度配信してしまうと、後から取り消すのが難しい拡散方法ということです。そのため企業によっては一旦承認フローを経てからプッシュ通知を送りたいという要望も聞かれます。
そこで独自のプッシュ通知管理画面を作成して、承認フローを経るようにしてみたいと思います。今回から複数回に分けて、作成していく過程をステップを踏んで説明していきますので、自社のフローに合わせてカスタマイズしてみてください。
利用するアーキテクチャについて
今回は以下の技術を組み合わせて実装していきます。
- NCMB JavaScript SDK
- Vue2
Vue2は最近流行のバーチャルDOMを実装したビューフレームワークになります。素のHTMLを使って記述するのでReactなどに比べると学習の敷居が低く、使いやすいと思います。
Vue2のコンポーネントについて
Vue2ではコンポーネントという概念によって、UI部品の再利用性を高めたり、機能の独立性を高めてメンテナンス性を向上させられます。拡張子は .vue というファイルで、HTML/JavaScript/CSSがまとめて管理されます。
例えば次のような内容になります。 がHTML、がJavaScript部分になります。後はでスタイルシートの内容を記述できます。
<template> <header id="header" class="reset"> <div class="header-inner"> <div class="logo-site"> <a href="/"><img src="assets/logo.png"></a> </div> <div class=""> <header-menu></header-menu> </div> <div class="status"> <header-status :error="error"></header-status> </div> </div> <div id="app-footpath" class=""> <header-login></header-login> </div> </header> </template> <script> module.exports = { props: ['error'], components: { 'header-menu': require('./header_menu.vue'), 'header-status': require('./header_status.vue'), 'header-login': require('./header_login.vue') }, }; </script>
この中で header-menu/header-status/header-loginというのは独自に定義したタグで、内容はまた別なvueファイルになります。こうやってHTMLをテンプレート化するのと一緒に処理(JavaScript)部分も切り出しておけます。コンポーネントは親子関係になりますので、親から子へはデータを渡せて、子から親はイベントを実行して(親はイベントを購読して)データの送受信を実現します。
.vue というファイルは一般的なJavaScriptではありませんので、vueifyというライブラリを使ってJavaScriptファイルに変換します。処理としては次のように実行します。
browserify -t [ babelify --presets [ es2015] ] -g envify src/app.js > assets/build.js
今回はES2015を使いつつBabelでES5にしています。そして .vue ファイルなども変換しながら build.js にしています。
全体の処理について
では全体を統括する src/app.js を見てみます。#app にVueアプリケーションをデプロイします。また、リンクをクリックした時に画面を切り替える処理が入るので VueRouter というルーティング用ライブラリを追加しています。
const Vue = require('vue'); const VueRouter = require('vue-router'); const routes = require('./routes') const App = require('./app.vue'); Vue.use(VueRouter); const router = new VueRouter({ routes: routes, mode: 'history' }) new Vue({ el: '#app', router: router, render: h => h(App) });
routes.js の内容は次のようになります。必要なコンポーネントを読み込みつつ、指定したURLのパスにアクセスした時にコンポーネントを読み込むように指定します。これだけでルーティング処理が実現できます。
let mainContent = require('./main_content.vue'); let configForm = require('./config_form.vue'); const routes = [ { path: '/', component: mainContent, children: [ { path: '', component: configForm } ] }, : ]; module.exports = routes;
実際にURLを遷移する時には次のように記述します。
<router-link to="/new" active-class="stay"> <span class="icon gnavi-pushinfo"></span> <span class="text">プッシュ作成</span> </router-link>
このように記述することでクリック時にURLが /new に変わりつつ、Vueアプリケーションのコンテンツ読み込みもダイナミックに変わるようになります。
画面構成
今回の画面構成は次のようになります。
content部分は処理に応じて表示される内容が異なります。主に以下の3つです。
- プッシュ通知一覧
- プッシュ通知作成
- 設定
NCMBオブジェクトの取り扱い
このWebアプリケーション全体でNCMBオブジェクトは共通になります。そこで、このデータは一番上のルートオブジェクト上で管理します。アプリケーションキーとクライアントキーはlocalStorageに保存するので、オンライン上に公開されていても利用できます。
const NCMB = require('ncmb'); let ncmb = null; const application_key = localStorage.getItem('application_key'); const client_key = localStorage.getItem('client_key'); if (application_key && client_key) { ncmb = new NCMB(application_key, client_key) } export default { name: 'app', data: function() { return { ncmb: ncmb, error: null }; }, : render: h => h(App) } </script>
そして、このncmbオブジェクトを子のコンポーネントに伝搬していきます。これで親側でncmbオブジェクトを変更すると、子のコンポーネントにも伝搬されるようになります。
<router-view :ncmb="ncmb" :updateKeys="updateKeys"></router-view>
そして子の方ではpropsを使って受け入れる変数を指定します。
<script> module.exports = { props: ['ncmb'], : }
こうすることで、子供のコンポーネント側で this.ncmb としてアクセスできるようになります。
イベントを伝搬させる
逆に子供のコンポーネントが親の変数を変更する場合などはイベントを使います。親の変数は直接変更できません。まず親側で監視するイベントを指定します。以下の例で言うところのupdateKeysがそうです。
<router-view :ncmb="ncmb" :updateKeys="updateKeys"></router-view>
そして子供のコンポーネントでは emit を使ってイベントを実行します。
module.exports = { : methods: { saveKeys: function(e) { if (this.application_key && this.client_key) { this.$emit('updateKeys', this.application_key, this.client_key); } } } }
こうすることで画面上で変更されたアプリケーションキー、クライアントキーを親(App)のイベントまで伝えることができます。
孫や祖父など、一足飛びにデータを渡したり、イベントを呼び出すことは出来ません。階層を意識して伝搬させる必要があります。
今回まででプッシュ通知認証フローアプリの基本形が分かってきたかと思います。次回は設定(アプリケーションキーとクライアントキー)を保存する処理を紹介します。