添加手机
¥Adding Mobile
我们的照片库应用只有在 iOS、Android 和 Web 上运行后才算完整 - 全部使用一个代码库。只需进行一些小的逻辑更改即可支持移动平台,安装一些原生工具,然后在设备上运行应用。我们走吧!
¥Our photo gallery app won’t be complete until it runs on iOS, Android, and the web - all using one codebase. All it takes is some small logic changes to support mobile platforms, installing some native tooling, then running the app on a device. Let’s go!
导入平台 API
¥Import Platform API
让我们从一些小的代码更改开始 - 那么当我们将应用部 署到设备上时,它就会“正常工作”。
¥Let’s start with making some small code changes - then our app will “just work” when we deploy it to a device.
将 Ionic 平台 API 导入 photo.service.ts
,用于检索当前设备的信息。在这种情况下,根据应用运行的平台(网络或移动设备)选择要执行的代码非常有用:
¥Import the Ionic Platform API into photo.service.ts
, which is used to retrieve information about the current device. In this case, it’s useful for selecting which code to execute based on the platform the app is running on (web or mobile):
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
}
特定于平台的逻辑
¥Platform-specific Logic
首先,我们将更新照片保存功能以支持移动设备。在 readAsBase64()
函数中,检查应用运行在哪个平台上。如果它是“混合”(Capacitor 或 Cordova,两个原生运行时),则使用文件系统 readFile()
方法将照片文件读取为 Base64 格式。否则,在网络上运行应用时使用与之前相同的逻辑:
¥First, we’ll update the photo saving functionality to support mobile. In the readAsBase64()
function, check which platform the app is running on. If it’s “hybrid” (Capacitor or Cordova, two native runtimes), then read the photo file into base64 format using the Filesystem readFile()
method. Otherwise, use the same logic as before when running the app on the 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()
方法(详细信息在这里)。
¥Next, update the savePicture()
method. When running on mobile, set filepath
to the result of the writeFile()
operation - savedFile.uri
. When setting the webviewPath
, use the special Capacitor.convertFileSrc()
method (details here).
// 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.nodejs.cn/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
};
}
}
接下来,回到我们之前为网络实现的 loadSaved()
功能。在手机上,我们可以直接设置图片标签的来源 - <img src="x" />
- 文件系统上的每个照片文件,自动显示它们。因此,只有 Web 需要将文件系统中的每个图片读取为 base64 格式。更新此函数以在文件系统代码周围添加 if 语句:
¥Next, head back over to the loadSaved()
function we implemented for the web earlier. On mobile, we can directly set the source of an image tag - <img src="x" />
- to each photo file on the Filesystem, displaying them automatically. Thus, only the web requires reading each image from the Filesystem into base64 format. Update this function to add an if statement around the Filesystem code:
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 上运行的代码库组成。接下来是你一直在等待的部分 - 将应用部署到设备。
¥Our Photo Gallery now consists of one codebase that runs on the web, Android, and iOS. Next up, the part you’ve been waiting for - deploying the app to a device.