Using iCloud containers in a React Native application
iOS allows our applications to use iCloud directly in our mobile application. Among the ways to communicate with the cloud we can distinguish:
- iCloud containers — allowing to write and read files on iCloud,
- Key-value storage — that is, a simple key-value database, allowing text data to be stored under a selected key.
In both cases, in order to use this type of functionality in a React Native application, it is necessary to configure the project accordingly. In this article, I would like to show this process for iCloud containers using the great react-native-cloud-store library by XHMM (you can find it here).
Installation
In order to add the library to the project, you will need to run the following commands:
yarn add react-native-cloud-store
cd ios
npx pod-install
As we can see in the code of the library, the native module was written in Swift, hence it is necessary to add the so-called Bridging header to our project. To do this in the easiest way, just add a new file with the swift extension in the project in xCode:
Click New File, and then select the Swift file:
After pressing next, selecting the standard location and creating the file, Xcode will ask us to create the Bridging Header:
The next step will be to add a new Capability. To do this, we need to select the project and go to the “Signing & Capabilities” tab. Then we select the button to add a new Capability:
Select iCloud from the list. When a new item appears in the list, select iCloud Documents and add a new container (using the plus icon in this section.
NOTES. Remember that in order to use iCloud functionality, you need to have an Apple developer account!
Type the name of the container and click OK.
If the container after the addition will have a name in red, it is necessary to use the refresh button, to synchronize containers with Apple.
Example of use
By default, we can use multiple containers in the application, but the default will be the first one selected in the Capabilities / iCloud section.
Downloading a list of files
To get the list of files located in the container let’s use the function:
import {
defaultICloudContainerPath,
isICloudAvailable,
readDir,
} from 'react-native-cloud-store';
const getFiles = async () => {
if (await isICloudAvailable() && defaultICloudContainerPath) {
return await readDir(defaultICloudContainerPath);
} else {
throw 'Your error';
}
}
The above function gets the list of files in the default container, then when the user has access to an iCloud account (this is provided by the isICloudAvailable function). If, for example, the user does not have an Apple account configured on his device, or has denied the app access to it, the use of containers will become impossible.
Creating a file
To save a file in a container, we need to give it a name (the fileName variable) and add content (the fileContent variable).
import {
writeFile,
defaultICloudContainerPath,
} from 'react-native-cloud-store';
const fileName = "test.txt";
const fileContent = "Test";
await writeFile(
defaultICloudContainerPath + fileName
fileContent,
);
Downloading the file
In case the file is not on our device, we need to download it before reading it. To do this, let’s use the function:
import { download } from 'react-native-cloud-store';
const getFileFromICloud = async (fileName: string) => {
return new Promise(resolve => {
download(fileName, {
onProgress: data => {
if (data.progress === 100) {
resolve(true);
}
},
});
});
}
await getFileFromICloud(fileName);
The download function, although it returns Promise, does so before downloading the file. Hence, it is necessary to use the onProgress parameter. In this case, in order to wait for the file to be fully downloaded, I created a new Promise that enters the resolve state after the file is fully downloaded.
Reading the file
To read the contents of a file, simply use the readFile function:
import { readFile } from 'react-native-cloud-store';
const content = await readFile(fileName);
Deleting a file
To delete a file (or dictionary), perform the unlink function:
import { unlink } from 'react-native-cloud-store';
await unlink(filename);
Other operations
More operations available on containers can be found in the official documentation of the library.
Summary
Managing iCloud containers from within a React Native application thanks to the use of an external library is not a particularly difficult task. However, it should be noted that this functionality is only available for iOS. For Android solutions, it is necessary to implement other solutions to support the cloud.