モバイルの追加
フォトギャラリーアプリは、iOS、Android、Webのすべてで、1つのコードベースを使用して動作するまで完成しません。モバイルプラットフォームをサポートするための小さなロジックの変更、いくつかのネイティブツーリングのインストール、デバイスでのアプリの実行だけで、すべてが完了します。さあ、始めましょう!
プラットフォームAPIのインポート
まずは小さなコード変更から始めましょう。そうすれば、デバイスにデプロイしたときにアプリは「そのまま動作」します。
IonicのプラットフォームAPIをphoto.service.ts
にインポートします。これは、現在のデバイスに関する情報を取得するために使用されます。この場合、アプリが実行されているプラットフォーム(Webまたはモバイル)に基づいて、実行するコードを選択するのに役立ちます。
import { Platform } from '@ionic/angular';
export class PhotoService {
public photos: UserPhoto[] = [];
private PHOTO_STORAGE: string = 'photos';
private platform: Platform;
constructor(platform: Platform) {
this.platform = platform;
}
// other code
}
プラットフォーム固有のロジック
まず、モバイルをサポートするように写真の保存機能を更新します。 readAsBase64()
関数で、アプリが実行されているプラットフォームを確認します。「ハイブリッド」(2つのネイティブランタイムであるCapacitorまたはCordova)の場合は、FilesystemのreadFile()
メソッドを使用して、写真ファイルをbase64形式で読み取ります。それ以外の場合は、Webでアプリを実行する場合と同じロジックを使用します。
private async readAsBase64(photo: Photo) {
// "hybrid" will detect Cordova or Capacitor
if (this.platform.is('hybrid')) {
// Read the file into base64 format
const file = await Filesystem.readFile({
path: photo.path!
});
return file.data;
}
else {
// Fetch the photo, read as a blob, then convert to base64 format
const response = await fetch(photo.webPath!);
const blob = await response.blob();
return await this.convertBlobToBase64(blob) as string;
}
}
次に、savePicture()
メソッドを更新します。モバイルで実行している場合は、filepath
をwriteFile()
操作の結果であるsavedFile.uri
に設定します。 webviewPath
を設定するときは、特別なCapacitor.convertFileSrc()
メソッドを使用します(詳細はこちら)。
// Save picture to file on device
private async savePicture(photo: Photo) {
// Convert photo to base64 format, required by Filesystem API to save
const base64Data = await this.readAsBase64(photo);
// Write the file to the data directory
const fileName = Date.now() + '.jpeg';
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data
});
if (this.platform.is('hybrid')) {
// Display the new image by rewriting the 'file://' path to HTTP
// Details: https://ionic.dokyumento.jp/docs/building/webview#file-protocol
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
};
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath
};
}
}
次に、以前にWeb用に実装したloadSaved()
関数に戻ります。モバイルでは、画像タグのソース(<img src="x" />
)をFilesystemの各写真ファイルに直接設定して、自動的に表示できます。そのため、Filesystemから各画像をbase64形式で読み取る必要があるのはWebだけです。この関数を更新して、Filesystemコードの周りに* if文*を追加します。
public async loadSaved() {
// Retrieve cached photo array data
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];
// Easiest way to detect when running on the web:
// “when the platform is NOT hybrid, do this”
if (!this.platform.is('hybrid')) {
// Display the photo by reading into base64 format
for (let photo of this.photos) {
// Read each saved photo's data from the Filesystem
const readFile = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
}
}
}
これで、フォトギャラリーは、Web、Android、iOSで実行される1つのコードベースで構成されるようになりました。次は、待ちに待った部分、デバイスへのアプリのデプロイです。