從檔案系統載入照片
我們已經實作了拍照並儲存至檔案系統的功能。還缺少最後一項功能:照片已儲存在檔案系統中,但我們需要一種方式來儲存每個檔案的指標,以便它們可以再次顯示在相片庫中。
幸運的是,這很容易:我們將利用 Capacitor 的 偏好設定 API 將我們的照片陣列儲存在鍵值儲存區中。
偏好設定 API
首先,在 src/hooks/usePhotoGallery.ts
中的 usePhotoGallery
函式定義之前,定義一個常數變數,作為儲存區的鍵。
const PHOTO_STORAGE = 'photos';
export function usePhotoGallery() {}
然後,使用 Storage
類別來取得讀取和寫入裝置儲存體的 get 和 set 方法。
在 takePhoto
函式的結尾,新增對 Preferences.set()
的呼叫以儲存照片陣列。透過在此處新增,每次拍攝新照片時都會儲存照片陣列。這樣,應用程式使用者何時關閉或切換到不同的應用程式都沒關係,所有照片資料都會儲存。
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" />
的來源直接設定為檔案系統上的每個照片檔案,自動顯示它們。但是,在網頁上,我們必須從檔案系統中將每個影像讀取為 base64 格式,因為檔案系統 API 將它們以 base64 格式儲存在 IndexedDB 中。
就是這樣!我們已在我們的 Ionic 應用程式中建置了一個完整相片庫功能,可在網頁上運作。接下來,我們將把它轉換為適用於 iOS 和 Android 的行動應用程式!