8
4

More than 3 years have passed since last update.

PWAとは、railsにPWA導入、vuejsにPWA導入

Posted at
1 / 13

PWAとは

  • Progressive Web Apps
  • モバイル端末でウェブサイトを表示するときに、まるでネイティブアプリのような動作を可能にする仕組み

PWAとネイティブアプリとウェブサイトの違い

ウェブサイト

  • ブラウザーでURLアクセス出来る
  • HTML/CSS/WEB Frameworkで開発する
  • どの端末でもブラウザーがあれば、アクセス出来る
  • OSの深い機能触れません

 アプリ

  • OSにサポートしているSDKを使って、アプリを開発する
  • OSによって、アプリが違う(Android, IOS, Mac Os, Windows)
  • アプリ使えるため、アプリをダウンロードして、インストールして、開けます。 (OSのデフォルトアプリがあります、そのアプリはインストール不要です)
  • OSの深い機能触れます
    • オフラインモード
    • I/Oアクセス
    • Push Notification
    • セキュリティー

PWA

  • ウェブサイトとアプリの真ん中
  • HTML/CSS/WEB Frameworkで開発する(ウェブサイト)
  • ブラウザーでURLアクセス出来る (ウェブサイト)
  • アプリをインストールして、開けます。(アプリ)
  • どの端末でもブラウザーがあれば、アクセス出来る(ウェブサイト)
  • OSの深い機能は少しさわれます
    • オフラインモード
    • Push Notification

image.png


PWAとネイティブアプリとウェブサイト

image.png


PWAのインストール

qiitaページはPWA入っています。


image.png

ChromeでPWA導入確認出来ます

image.png

image.png


ウェブサイトにPWA導入準備

  • manifest.json : アプリアイコン、アプリ名など設定するファイル
  • service_worker.js : JSキャッシュ、Push Notificationなど設定ファイル

PWA導入例

RAILS

manifest.json ファイル作成

  • routers.rb に追加
...
resources :manifest, only: [:index]
...
  • manifest_controller.rb ファイル作成
class ManifestController < ApplicationController
    protect_from_forgery except: :index
    def index
    end
end
  • app/views/manifest/index.json.erb ファイル作成
{
  "name": "PWAテスト",
  "short_name": "PWAテスト",
  "start_url": "/",
  "icons": [
    {
      "src": "icon/android-chrome-192x192.png,
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ],
  "theme_color": "#000000",
  "background_color": "#FFFFFF",
  "display": "standalone",
  "orientation": "portrait"
}

  • app/views/layouts/application.html.erb に追加

    <%# PWA %>
    <link rel="manifest" href="/manifest.json&nocache=<%= (0...50).map { ('a'..'z').to_a[rand(26)] }.join %>" />
    <link rel="apple-touch-icon" href="icon/android-chrome-192x192.png">
    <meta name="theme-color" content="rgb(125, 212, 32)"/>
    <meta name="apple-mobile-web-app-capable" content="yes">


serviceworker.js ファイル作成

  • routers.rb に追加
...
resources :serviceworker, only: [:index]
...
  • serviceworker_controller.rb ファイル作成
class ServiceworkerController < ApplicationController
    protect_from_forgery except: :index
    def index
    end
end

  • app/views/serviceworker/index.js.erb ファイル追加
var CACHE_VERSION = 'v1';
var CACHE_NAME = CACHE_VERSION + ':sw-cache-';

function onInstall(event) {
  console.log('[Serviceworker]', "Installing!", event);
  event.waitUntil(
    caches.open(CACHE_NAME).then(function prefill(cache) {
      return cache.addAll([

        // make sure serviceworker.js is not required by application.js
        // if you want to reference application.js from here

        '/offline.html',

      ]);
    })
  );
}

function onActivate(event) {
  console.log('[Serviceworker]', "Activating!", event);
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          // Return true if you want to remove this cache,
          // but remember that caches are shared across
          // the whole origin
          return cacheName.indexOf(CACHE_VERSION) !== 0;
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
}

// Borrowed from https://github.com/TalAter/UpUp
function onFetch(event) {
  event.respondWith(
    // try to return untouched request from network first
    fetch(event.request).catch(function() {
      // if it fails, try to return request from the cache
      return caches.match(event.request).then(function(response) {
        if (response) {
          return response;
        }
        // if not found in cache, return default offline content for navigate requests
        if (event.request.mode === 'navigate' ||
          (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
          console.log('[Serviceworker]', "Fetching offline content", event);
          return caches.match('/offline.html');
        }
      })
    })
  );
}

self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);

  • app/views/layouts/application.html.erb に追加

    <script>
      if (navigator.serviceWorker) {
        navigator.serviceWorker.register('/serviceworker.js', { scope: './' })
          .then(function(reg) {
            console.log('[Companion]', 'Service worker registered!');
          });
      }
    </script>


VUEJSに追加

PWAの問題

  • Storeにアップロード出来ません
  • OSの深い機能に関して、IOSとAndroidは違います。

https://medium.com/@firt/progressive-web-apps-on-ios-are-here-d00430dee3a7#:~:text=With%20iOS%2011.3%2C%20Apple%20has,Web%20Apps%20%E2%80%9D%20(PWAs).&text=This%20App%20is%20a%20PWA,app%20from%20the%20App%20Store.


以上です。

8
4
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
8
4