Skip to content

Commit 8cbe764

Browse files
committed
docs(angular): update adding mobile page
1 parent d954a3d commit 8cbe764

File tree

1 file changed

+62
-68
lines changed

1 file changed

+62
-68
lines changed

docs/angular/your-first-app/5-adding-mobile.md

Lines changed: 62 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
title: Adding Mobile
23
strip_number_prefixes: false
34
---
45

@@ -10,11 +11,11 @@ Our photo gallery app won’t be complete until it runs on iOS, Android, and the
1011

1112
Let’s start with making some small code changes - then our app will “just work” when we deploy it to a device.
1213

13-
Import the Ionic [Platform API](https://ionicframework.com/docs/angular/platform) 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).
14+
Import the Ionic [Platform API](../platform.md) 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).
1415

15-
Add `Platform` to the imports at the top of the file and a new property `platform` to the `PhotoService` class. We'll also need to update the constructor to set the user's platform:
16+
Add `Platform` to the imports at the top of the file and a new property `platform` to the `PhotoService` class. We'll also need to update the constructor to set the user's platform.
1617

17-
```tsx
18+
```ts
1819
import { Injectable } from '@angular/core';
1920
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
2021
import { Filesystem, Directory } from '@capacitor/filesystem';
@@ -24,6 +25,7 @@ import { Platform } from '@ionic/angular';
2425

2526
export class PhotoService {
2627
public photos: UserPhoto[] = [];
28+
2729
private PHOTO_STORAGE: string = 'photos';
2830

2931
// CHANGE: Add a property to track the app's running platform.
@@ -34,18 +36,19 @@ export class PhotoService {
3436
this.platform = platform;
3537
}
3638

37-
// other code
39+
// Same old code from before.
3840
}
3941
```
4042

4143
## Platform-specific Logic
4244

43-
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.
45+
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`'s' `readFile()` method. Otherwise, use the same logic as before when running the app on the web.
4446

4547
Update `readAsBase64()` to look like the following:
4648

47-
```tsx
49+
```ts
4850
private async readAsBase64(photo: Photo) {
51+
// CHANGE: Add platform check.
4952
// "hybrid" will detect Cordova or Capacitor
5053
if (this.platform.is('hybrid')) {
5154
// Read the file into base64 format
@@ -54,8 +57,7 @@ private async readAsBase64(photo: Photo) {
5457
});
5558

5659
return file.data;
57-
}
58-
else {
60+
} else {
5961
// Fetch the photo, read as a blob, then convert to base64 format
6062
const response = await fetch(photo.webPath!);
6163
const blob = await response.blob();
@@ -65,50 +67,43 @@ private async readAsBase64(photo: Photo) {
6567
}
6668
```
6769

68-
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 on the File Protocol](https://ionicframework.com/docs/core-concepts/webview#file-protocol)). To use this method, we'll need to import Capacitor into `photo.service.ts`.
70+
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 on the File Protocol](../../core-concepts/webview.md#file-protocol)). To use this method, we'll need to import Capacitor into `photo.service.ts`.
6971

7072
```tsx
7173
import { Capacitor } from '@capacitor/core';
7274
```
7375

7476
Then update `savePicture()` to look like the following:
7577

76-
```tsx
77-
// Save picture to file on device
78-
private async savePicture(photo: Photo) {
79-
// Convert photo to base64 format, required by Filesystem API to save
80-
const base64Data = await this.readAsBase64(photo);
81-
82-
// Write the file to the data directory
83-
const fileName = Date.now() + '.jpeg';
84-
const savedFile = await Filesystem.writeFile({
85-
path: fileName,
86-
data: base64Data,
87-
directory: Directory.Data
88-
});
78+
```ts
79+
// CHANGE: Update `loadSaved` method.
80+
public async loadSaved() {
81+
// Retrieve cached photo array data
82+
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
83+
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];
8984

90-
if (this.platform.is('hybrid')) {
91-
// Display the new image by rewriting the 'file://' path to HTTP
92-
// Details: https://ionicframework.com/docs/building/webview#file-protocol
93-
return {
94-
filepath: savedFile.uri,
95-
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
96-
};
97-
}
98-
else {
99-
// Use webPath to display the new image instead of base64 since it's
100-
// already loaded into memory
101-
return {
102-
filepath: fileName,
103-
webviewPath: photo.webPath
104-
};
85+
// Easiest way to detect when running on the web:
86+
// “when the platform is NOT hybrid, do this”
87+
if (!this.platform.is('hybrid')) {
88+
// Display the photo by reading into base64 format
89+
for (let photo of this.photos) {
90+
// Read each saved photo's data from the Filesystem
91+
const readFile = await Filesystem.readFile({
92+
path: photo.filepath,
93+
directory: Directory.Data
94+
});
95+
96+
// Web platform only: Load the photo as base64 data
97+
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
98+
}
10599
}
106100
}
107101
```
108102

109-
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:
103+
Next, head back over to the `loadSaved()` method 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 method to add an _if statement_ around the `Filesystem` code:
110104

111-
```tsx
105+
```ts
106+
// CHANGE: Update `loadSaved` method.
112107
public async loadSaved() {
113108
// Retrieve cached photo array data
114109
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
@@ -136,7 +131,7 @@ Our Photo Gallery now consists of one codebase that runs on the web, Android, an
136131

137132
`photos.service.ts` should now look like this:
138133

139-
```tsx
134+
```ts
140135
import { Injectable } from '@angular/core';
141136
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
142137
import { Filesystem, Directory } from '@capacitor/filesystem';
@@ -149,7 +144,9 @@ import { Capacitor } from '@capacitor/core';
149144
})
150145
export class PhotoService {
151146
public photos: UserPhoto[] = [];
147+
152148
private PHOTO_STORAGE: string = 'photos';
149+
153150
private platform: Platform;
154151

155152
constructor(platform: Platform) {
@@ -164,41 +161,16 @@ export class PhotoService {
164161
quality: 100,
165162
});
166163

167-
// Save the picture and add it to photo collection
168164
const savedImageFile = await this.savePicture(capturedPhoto);
169165

170166
this.photos.unshift(savedImageFile);
171167

172-
// Method to cache all photo data for future retrieval.
173168
Preferences.set({
174169
key: this.PHOTO_STORAGE,
175170
value: JSON.stringify(this.photos),
176171
});
177172
}
178173

179-
public async loadSaved() {
180-
// Retrieve cached photo array data
181-
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
182-
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];
183-
184-
// Easiest way to detect when running on the web:
185-
// “when the platform is NOT hybrid, do this”
186-
if (!this.platform.is('hybrid')) {
187-
// Display the photo by reading into base64 format
188-
for (let photo of this.photos) {
189-
// Read each saved photo's data from the Filesystem
190-
const readFile = await Filesystem.readFile({
191-
path: photo.filepath,
192-
directory: Directory.Data,
193-
});
194-
195-
// Web platform only: Load the photo as base64 data
196-
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
197-
}
198-
}
199-
}
200-
201-
// Save picture to file on device
202174
private async savePicture(photo: Photo) {
203175
// Convert photo to base64 format, required by Filesystem API to save
204176
const base64Data = await this.readAsBase64(photo);
@@ -213,7 +185,6 @@ export class PhotoService {
213185

214186
if (this.platform.is('hybrid')) {
215187
// Display the new image by rewriting the 'file://' path to HTTP
216-
// Details: https://ionicframework.com/docs/building/webview#file-protocol
217188
return {
218189
filepath: savedFile.uri,
219190
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
@@ -246,15 +217,38 @@ export class PhotoService {
246217
}
247218
}
248219

249-
private convertBlobToBase64 = (blob: Blob) =>
250-
new Promise((resolve, reject) => {
220+
private convertBlobToBase64(blob: Blob) {
221+
return new Promise((resolve, reject) => {
251222
const reader = new FileReader();
252223
reader.onerror = reject;
253224
reader.onload = () => {
254225
resolve(reader.result);
255226
};
256227
reader.readAsDataURL(blob);
257228
});
229+
}
230+
231+
public async loadSaved() {
232+
// Retrieve cached photo array data
233+
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
234+
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];
235+
236+
// Easiest way to detect when running on the web:
237+
// “when the platform is NOT hybrid, do this”
238+
if (!this.platform.is('hybrid')) {
239+
// Display the photo by reading into base64 format
240+
for (let photo of this.photos) {
241+
// Read each saved photo's data from the Filesystem
242+
const readFile = await Filesystem.readFile({
243+
path: photo.filepath,
244+
directory: Directory.Data,
245+
});
246+
247+
// Web platform only: Load the photo as base64 data
248+
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
249+
}
250+
}
251+
}
258252
}
259253

260254
export interface UserPhoto {

0 commit comments

Comments
 (0)