Using iCloud containers in a React Native application

Lukasz Kurant
5 min readJan 25, 2023

--

Photo added by Magda Ehlers: Source

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:

Adding a new file to a project in Xcode.

Click New File, and then select the Swift file:

File type selection.

After pressing next, selecting the standard location and creating the file, Xcode will ask us to create the Bridging Header:

Adding a 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:

Adding 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!

Adding a new container.

Type the name of the container and click OK.

The iCloud section of the Capabilities tab.

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.

Sources

--

--

Lukasz Kurant

Fullstack Developer interested in solving difficult problems.