Secure the user data on iCloud Drive with Flutter

Oz Ben
2 min readNov 29, 2023

Google Drive and iCloud are two of the most popular cloud storage services, and they offer a variety of features that can be useful for Flutter developers. For example, Google Drive offers features like real-time collaboration and file sharing, while iCloud offers features a like device backup and sync.

When using those services the developer would able to save mandatory files for the application such as configuration files and keys, at the application data folder.
The application data folder is a special folder that can be by the app to store specific data.
This folder is only accessible by your application and its contents are hidden from the user and from other Drive apps.

Please note: In this article i will cover the iCloud Drive service usage, the Google Drive service is being covered on the following article.

we would be using the icloud_storage package.

Step 1: Import the relevant packages

icloud_storage: ^2.2.0
path_provider: ^2.1.1

Step 2: Login and authenticate with Apple

final odarauthCredential = OAuthProvider("apple.com").credential(
idToken: appleCredential.identityToken,
rawNonce: rawNonce,
);

Please note:
This article doesn’t discuss the authentication process with Apple .
Therefore, one shall add the necessary implementation for it in order to be authenticated.

Step 3: The iCloud Client

Lets define the private api method

Download a file

Future<String?> _downloadFileToDevice(String fileName) async {
try {
final directory = await getApplicationDocumentsDirectory();
await ICloudStorage.download(
containerId: containerId,
relativePath: '$privateAppFolderName/$fileName',
destinationFilePath: '${directory.path}/$fileName',
onProgress: (stream) {
stream.listen(
(progress) => print('Download Progress: $progress'),
onDone: () => print('Download Completed'),
onError: (err) => print(err),
cancelOnError: true,
);
},
);
var created = io.File("${directory.path}/$fileName");
final contents = await created.readAsString();
return contents;
} catch (e) {
return null;
}
}

Create a file and upload it to iCloud

Future<bool> _uploadFileToIcloud(String fileName, {String? content}) async {
try {
final directory = await getApplicationDocumentsDirectory();
if (content != null) {
final directory = await getApplicationDocumentsDirectory();
var created = io.File("${directory.path}/$fileName");
created.writeAsString(content);
}
await ICloudStorage.upload(
containerId: containerId,
filePath: "${directory.path}/$fileName",
destinationRelativePath: '$privateAppFolderName/$fileName',
onProgress: (stream) {
stream.listen(
(progress) => print('Upload Progress: $progress'),
onDone: () => print('Upload Completed'),
onError: (err) => print(err),
cancelOnError: true,
);
});
return true;
} catch (ex) {
print(ex);
return false;
}
}

And the public methods of the client are:

uploadFile(String fileContent) async {
try {
await _uploadFileToIcloud(fileContentFileName, content: fileContent);
return true;
} catch (e) {
return null;
}
}
Future<String?> downloadFile() async {
try {
return await _downloadFileToDevice(fileContentFileName);
} catch (e) {
return null;
}
}

The full iCloud client code:

Security measures

It is to use encryption for sensitive user data before storing it on the cloud.
You can read more about encryption in flutter at the following post.

Conclusion

iCloud is a great platform to insure that the authenticated user would have his own private data on the cloud.

--

--

Oz Ben

Mobile developer, Mechanical Engineer ,technology obsessed ,DJ and a Surfer . https://www.linkedin.com/in/oz-benoved