見出し画像

PWAでPodcastクライアント実現可能か作ってみた

これは、祭り化 Advent Calendar 2019の10日目の記事です。

昨日は、9日目はマツリカのハイパーオペレーションエンジニアののりへい氏(@hikey2310)の3つの「3つのWhy」の記事でした。

こんにちは、ナオ @1wa46です。

株式会社マツリカでは、モバイルチームに所属しています。オフシーズンのプロ野球で補強情報に一喜一憂している毎日を送っています。

さて、今回は、弊社へ入社するきっかけとなったMazrica.fmを再生するPWAを作ってみたのでそのTipsの紹介です。

TL;DR

Podcast PWA を作ってみた。

PWAとして動作する最低限の実装のみ。今回は、開発で苦労した点をTipsでまとめてみました。詳細は実装は要望があればまとめます。

※PWAは個人的な興味がある分野で、マツリカでは、ネイティブでアプリケーションを開発しています。

※デザインはこだわれていないです🙏

PWAとは

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

iPhoneやAndroidでは、ホーム画面へ追加で、Macの場合は、Chromeでアドレスバーの ”➕”ボタンよりダウンロードすることができます。

構成

今回は、ローカルで開発、ビルドしたコードをheroku上で公開しています。

画像1

Tips 1: 開発する技術選定

ionic 4 + stancil.js組み合わせたToolkitを利用して開発をしました。npmのインストール後、startコマンドを実行するだけで、localhost:3333でアプリケーションを起動されます。

$ git clone https://github.com/ionic-team/ionic-pwa-toolkit.git sample_pwa
$ cd sample_pwa
$ npm install
$ npm run start

Tips 2: RSSを取得して表示する

RSSで取得したエピソードの表示には、vanilla-rssというPackageを利用しました。rss-parser等の有名なRSSをパースするライブラリは、Toolkitで相性が悪く動作させることに時間がかかった為、シンプルに表示してくれるpackageを仕様しました。

Tips 3: 音声の再生を実装する

Mazrica.fmのホスティングにSound Cloudが使われています。今回は、soundcloud-audioというPackageを利用しました。簡単に実装は可能ですが、Sound Cloudの API KEYを申請する必要があるため、登録が必要です。

Tips 4: 前回の再生位置を保持する

クライアントで前回の再生位置を保持する機能を実装しました。PWAの場合は、localStorageで管理しています。最低限、取得登録削除を実装すると以下のようになります。

const storage = window.localStorage;

class AppStorageServiceController {

 constructor() {
 }

 set(key: string, value: any): Promise<void> {
   return new Promise((resolve, reject) => {
     try {
       storage && storage.setItem(key, JSON.stringify(value));
       resolve();
     } catch (error) {
       reject(`Couldnt store object ${error}`);
     }
   });
 }

 get(key: string): Promise<any> {
   return new Promise((resolve, reject) => {
     try {
       if (storage) {
         const item = storage.getItem(key);
         resolve(JSON.parse(item));
       }
       resolve(undefined);
     } catch (error) {
       reject(`Couldnt get object: ${error}`);
     }
   });
 }

 remove(key: string): Promise<void> {
   return new Promise((resolve, reject) => {
     try {
       storage && storage.removeItem(key);
       resolve();
     } catch (error) {
       reject(`Couldnt remove object ${error}`);
     }
   });
 }
}

export const AppStorageService = new AppStorageServiceController();

Tips 5:  ServiceWorkerを実装する

PWAのきもとなる ServiceWorkerの実装には、Googleが提供しているWorkboxを使用することで手軽に行うことができます。最低限以下の2つで動作するようでした。

// sw.js
importScripts('workbox-v4.3.1/workbox-sw.js')


self.addEventListener('install', event => {
 console.debug('install');
});

self.addEventListener('activate', event => {
 console.debug('activate');
});

self.workbox.precaching.precacheAndRoute([]);

stansil.config.tsへ追加することで、ビルドの際、www/へ出力されるようになります。

...
export const config: Config = {
 outputTargets: [{
   type: 'www',
   serviceWorker: {
     swSrc: 'src/sw.js'
   }
 }],
...

Tips 6: heroku へ 簡単にウェブページを公開する

Build後、www/配下のみherokuへpushするだけでは、弾かれてしまいます。対策として、buildpacksへPHPを設定することで、簡単にウェブページを公開することが可能です。

直下でindex.phpを作成する。

// index.php
<?php

include_once('index.html');

?>

ビルドする際に、index.phpを出力先へ移動してくれます。

// stancil.config.ts
...
  copy :[
   {
     src: 'index.php',
     dest: 'index.php'
   }
 ]
};

herokuコマンドでアプリを作成後、buildpacksを設定、ビルド後生成された、www/のみをpushする。以上で公開できます。

// アプリを作成
$ heroku create
// ビルドパックを設定
$ heroku buildpacks:set heroku/php
// www/をpushする
$ git subtree push --prefix www/ heroku master

わかったこと

iOSの場合、ユーザー操作でのみ音声を再生することが許可されます。その為、連続で次のエピソードを再生することができません。又、バッググラウンド再生が許可されていません。この結果から、完全なクライアントをPWAで作成することは、現状ではできないことがわかりました。

ネイティブアプリのような動作には未対応な要素が多い現状ですが、Googleが推進している未来のある技術だと捉えています。引き続き追っていきたいです。

終わりに

かなりTechな内容となりましたが、マツリカの3つのValueの中に、Createvityというものがあります。

”仕事とは今ある価値の提供と新たな価値の創出である。
自分の仕事に創造性があるか常に問いかけよう。そして私たちが持つ創造性を最大限追求しよう”

エンジニアとして、提案出来る技術(価値)の引出しを増やす為に、新しい技術も積極的にキャッチアップしていきます。またトライを支援してくれる環境と仲間がマツリカにはあります。そんな仲間を募集中です。

以上です

明日は、バックエンドエンジニア BigO氏の記事です!


この記事が気に入ったらサポートをしてみませんか?