从文件系统加载照片
我们已经实现了拍照并保存到文件系统。还有一个功能缺失:照片存储在文件系统中,但我们需要一种方法来保存指向每个文件的指针,以便它们可以在照片库中再次显示。
幸运的是,这很容易:我们将利用 Capacitor 的 Preferences API 来将我们的照片数组存储在键值存储中。
Preferences API
首先,在 src/hooks/usePhotoGallery.ts
中的 usePhotoGallery
函数定义之前,定义一个作为存储键的常量变量
const PHOTO_STORAGE = 'photos';
export function usePhotoGallery() {}
然后,使用 Storage
类访问用于读写设备存储的 get 和 set 方法
在 takePhoto
函数的末尾,添加对 Preferences.set()
的调用以保存 Photos 数组。通过在这里添加它,每次拍摄新照片时都会存储 Photos 数组。这样,无论应用程序用户何时关闭应用程序或切换到其他应用程序,所有照片数据都会保存。
Preferences.set({ key: PHOTO_STORAGE, value: JSON.stringify(newPhotos) });
保存了照片数组数据后,我们将创建一个方法,在钩子加载时检索数据。我们将使用 React 的 useEffect
钩子来做到这一点。将此插入 takePhoto
声明的上方。这是代码,我们将对其进行分解
useEffect(() => {
const loadSaved = async () => {
const { value } = await Preferences.get({ key: PHOTO_STORAGE });
const photosInPreferences = (value ? JSON.parse(value) : []) as UserPhoto[];
for (let photo of photosInPreferences) {
const file = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data,
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
}
setPhotos(photosInPreferences);
};
loadSaved();
}, []);
乍一看这似乎有点吓人,所以让我们逐步了解它,首先看看我们传递给钩子的第二个参数:依赖数组 []
。
默认情况下,useEffect
钩子会在组件每次渲染时被调用,除非我们传入依赖数组。在这种情况下,它只会运行在依赖项更新时。在我们的例子中,我们只希望它被调用一次。通过传入一个不会改变的空数组,我们可以防止钩子被多次调用。
useEffect
的第一个参数是将由效果调用的函数。我们传入一个匿名箭头函数,并在其中定义另一个异步方法,然后立即调用它。我们必须从钩子中调用异步函数,因为钩子回调本身不能是异步的。
在移动端(接下来会介绍!),我们可以直接将图像标签的源代码 - <img src=”x” />
- 设置为文件系统上的每个照片文件,从而自动显示它们。然而,在 Web 上,我们必须将每个图像从文件系统读取到 base64 格式,因为文件系统 API 将它们存储在 IndexedDB 的 base64 格式中。
就是这样!我们在 Ionic 应用程序中构建了一个完整的照片库功能,该功能可以在 Web 上运行。接下来,我们将将其转换为适用于 iOS 和 Android 的移动应用程序!