LoginSignup
0
1

More than 1 year has passed since last update.

NCMBとFramework7を使ったお知らせコンポーネントの紹介と使い方

Last updated at Posted at 2022-02-16

NCMBはモバイルアプリ開発におけるバックエンド機能(認証、データストア、ファイルストア、プッシュ通知など)を提供しています。バックエンドなのでAPIベースで利用するのが基本で、UI(アプリ側)は各自で開発する仕組みになっています。

現在、数多くのアプリが存在し、その中には定番とも言える機能があります。そうした定番機能を各フレームワークごとに実装しておくことで、再利用性高くNCMBが利用できるかと思います。

今回はFramework7で作ったお知らせ用コンポーネントを紹介します。Monacaアプリでも利用可能です。

コンポーネントについて

コンポーネントは1つのHTMLだけで実装されているのが特徴です。そのため、基本的には以下の方法で導入・利用ができます。

  1. 必要なSDKの読み込み
  2. 必要なキーの取得
  3. NCMBの初期化
  4. 関数の呼び出し

用意されている画面(機能)は次の通りです。

お知らせ画面

localhost 016 2022-02-10-17-39-54.jpg

お知らせメッセージを通知するモーダル画面が表示されます。一度表示されたモーダルは記録され、次の機会には表示されません。

お知らせの仕様

  • お知らせは配信日時(開始、終了)を指定できます
  • 画像を表示できます(オプション)
  • お知らせをタップした際には、In App Browser、またはFramework7のルーティングで画面遷移できます

必要なライブラリ・SDKの読み込み

今回利用しているライブラリ・SDKは次の通りです。

  • NCMB JavaScript SDK

これらを www/index.html で読み込みます。

<script src="js/ncmb.min.js"></script>

必要なキー・トークンの取得

NCMBのアプリケーションキーとクライアントキーを取得します。

NCMBの初期化

www/js/app.js にてNCMBを初期化します。今回は www/js/config.json というファイルにキーを記述しているので、以下のように読み込みを行っています。

const $ = Dom7;
(async () => {
  const device = Framework7.getDevice();
    // 設定ファイルの読み込み
  const config = await (await fetch('./js/config.json')).json();
    // NCMBの初期化
  window.ncmb = new NCMB(config.applicationKey, config.clientKey);

  // Framework7の初期化
  window.app = new Framework7({
    name: 'NCMB Notice',
    theme: 'auto',
    el: '#app',
    id: 'com.nifcloud.mbaas.map',
    store: store,
    routes: routes,
    input: {
      scrollIntoViewOnFocus: device.cordova && !device.electron,
      scrollIntoViewCentered: device.cordova && !device.electron,
    },
    statusbar: {
      iosOverlaysWebView: true,
      androidOverlaysWebView: false,
    },
    on: {
      init: function () {
        if (this.device.cordova) {
          cordovaApp.init(this);
        }
      },
    },
  });
})();

関数の設定

app.jsにて、以下の関数を追加します。

// お知らせを表示する関数
const showNotice = async () => {
  // localStorageから配信済みのお知らせ情報を取得
  const noticeString = localStorage.getItem('notices');
  // localStorageには文字列しか保存できないので、JSONでパースする。[1]はダミーデータ
  const notices = noticeString ? JSON.parse(noticeString) : [1];
  // NCMBのデータストアを呼び出し
  let Notice = ncmb.DataStore('Notice');
  // お知らせがあるか検索
  const notice = await Notice
    .greaterThanOrEqualTo('endDate', new Date) // 配信可能な日時になっているデータの条件指定
    .lessThanOrEqualTo('startDate', new Date)
    .notIn('objectId', notices)
    .fetch();
  // お知らせがなければ終了
  if (!notice.objectId) return;
  // 画像の指定があれば取得
  const file = notice.image ? await ncmb.File.download(notice.image, 'blob') : null;
  // 画像を表示するための関数
  const showImage = (file) => {
    if (!file) return '';
    const url = URL.createObjectURL(file);
    return `<img src="${url}" width="100%" />`;
  }
  const showContent = (html) => {
    if (!html) return'';
    return `<p>${html}</p>`;
  }
  const showButton = (label ) => {
    return `<p><a class="button button-fill detail">${label}</a></p>`;
  };

  const openUrl = () => {
    if (notice.url.match(/^https?:\/\//)) {
      window.open(notice.url, '_blank', {
        location: false,
      })
    } else {
      app.views.current.router.navigate(notice.url);
    }
    popup.close();
  }

  // ポップアップを作成
  const popup = app.popup.create({
    content: `
    <div class="popup notice">
      <div class="row no-gap" style="padding-top: 0.5em;">
        <div class="col-90"></div>
        <div class="col-10" style="text-align:right;padding-right: 0.5em">
          <a href="#" class="link popup-close"><i class="f7-icons">xmark_circle</i></a>
        </div>
      </div>
      <div class="block">
      <div class="block-title">${notice.title}</div>
        ${showContent(notice.content)}
        ${showImage(file)}
        ${showButton(notice.label)}
      </div>
    </div>
    `,
    animate: true,
    // Events
    on: {
      opened: function (popup) {
        // 詳細表示用ボタンのトラッキング
        popup.$el.find('.detail').on('click', openUrl)
        // 表示したお知らせのobjectIdを記録する
        notices.push(notice.objectId);
        if (notices.length === 6) {
          notices.splice(1, 5); // 最後の5つを記録
        }
        // localStorageに書き込み
        localStorage.setItem('notices', JSON.stringify(notices));
      },
    }
  });
  // ポップアップを表示
  popup.open('body', true);
}

お知らせの呼び出し

後は任意の画面にて、 showNotice 関数を呼び出せば良いだけです。たとえば次のようになります。

<template>
  <div class="page">
    <!-- Top Navbar -->
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner">
        <div class="title sliding">メイン画面</div>
      </div>
    </div>
    <div class="page-content">
    </div>
  </div>
</template>
<script>
  export default function (props, {$f7, $on, $onMounted, $update}) {
    $onMounted(() => {
      // お知らせを表示
      showNotice();
    });
    return $render;
  }
</script>

データストアの設定

NCMBのデータストアでは Notice クラスを作成します。フィールドは次の通りです。

フィールド 意味
title 文字列 お知らせのタイトルです。
content 文字列 お知らせの内容。HTMLが使えます。
image 文字列 表示する画像です。ファイルストアのファイル名を記述します。
startDate 日時 お知らせを配信する日時です。
endDate 日時 お知らせを配信停止する日時です。
url 文字列 お知らせをタップした際の飛び先URLです。
label 文字列 お知らせをタップする際のボタンのラベルです。

image.png

まとめ

アプリでのお知らせ機能はよく利用されるかと思います。イチから開発するのは面倒ですが、これを使うことで実装は関数を呼び出すだけになります。ぜひ試してください。

mBaaSでサーバー開発不要! | ニフクラ mobile backend

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1