Как я могу создать и сохранить файл используя expo?

Как в expo можно создать и сохранить файл в нужной мне директории?

UPD: я пытался использовать такой код:

const Save = async () => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    if (status === "granted") {
        let fileUri = FileSystem.documentDirectory + "text.txt";
        await FileSystem.writeAsStringAsync(fileUri, "Hello World", { encoding: FileSystem.EncodingType.UTF8 });
        const asset = await MediaLibrary.createAssetAsync(fileUri)
        await MediaLibrary.createAlbumAsync("Download", asset, false)
    }
}
expo-permissions is now deprecated — the functionality has been moved to other expo packages that directly use these permissions (e.g. expo-location, expo-camera). The package will be removed in the upcoming releases. 

следующее, что я попытался предпринять - использовать StorageAccessFramework

import { StorageAccessFramework } from 'expo-file-system';

const Save = async () => {
    try {
      const status = await StorageAccessFramework.requestDirectoryPermissionsAsync();

      if (status.granted) {
        console.log('granted');

        await StorageAccessFramework.createFileAsync(status, "test", ".txt");
      } 
    } catch (err) {
        console.warn(err);
    }
}

Но получал ошибку

Argument of an incompatible class: class java.util.HashMap cannot be passed as an argument to parameter expecting class java.lang.String.   

Ответы (2 шт):

Автор решения: Ulan4eg

Есть очень простой способ, НО (ВНИМАНИЕ) КОЛХОЗНЫЙ и КОСТЫЛЬНЫЙ. До безобразия. И работает он только с прямыми ссылками, типа "https://www.abc.ru/123.jpg"

Суть такова: взять урл, и вставить его в сорс WebView: Сам компонент:

export default function Downloader(props: { url: string}) {
    const html = `<!DOCTYPE html><html><script>window.location.href = '${props.url}'</script></html>`;

    return (
        <WebView source={{html}} />
    );
}

затем этот компонент вставить в ... куда надо:

export default function App() {
    const [startDownload, setStartDownload] = useState<boolean>(false);

    const download = () => {
        setStartDownload(true);
        setTimeout(()=> setStartDownload(false), 2000);
    }

    return (
        <View>
          <TouchableHighlight
                onPress={() => download()}
            >
                <MaterialCommunityIcons
                    name={'download'}
                />
            </TouchableHighlight>
          {startDownload && <Downloader url={URL}/>}
       </View>
    );
}

Фишка в том, что скачается любой файл, в директорию Downloads, выйдет уведомление в верхней строке с ссылкой на скаченный файл, и выйдет тоаст с уведомлением о начале загрузки. В других реализациях, ВСЁ ЭТО придётся самим реализовывать руками (!!!) и там трабл, что картинки скачиваются в папку с картинками, а видео с видео, а остальные форматы не идут никуда и не качаются. но это колхоз-колхоз.

→ Ссылка
Автор решения: Gafum

Вот у меня работает Код брал от сюда: https://stackoverflow.com/questions/63460167/how-to-save-imported-json-file-with-expo-filesystem?

import * as FileSystem from "expo-file-system"
const { StorageAccessFramework } = FileSystem

const saveFile = async () => {
  try {
    const permissions =
      await StorageAccessFramework.requestDirectoryPermissionsAsync()

    if (permissions.granted) {
      // Get the directory uri that was approved
      let directoryUri = permissions.directoryUri
      let data = "Bye World"
      // Create file and pass it's SAF URI
      await StorageAccessFramework.createFileAsync(
        directoryUri,
        "test",
        "text/plain"
      )
        .then(async (fileUri) => {
          // Save data to newly created file
          await FileSystem.writeAsStringAsync(fileUri, data, {
            encoding: FileSystem.EncodingType.UTF8
          })
        })
        .catch((e) => {
          console.log(e)
        })
    } else {
      alert("You must allow permission to save.")
    }
  } catch (err) {
    console.warn(err)
  }
}
→ Ссылка