Baseflow / flutter_cache_manager

Generic cache manager for flutter
https://baseflow.com
MIT License
739 stars 426 forks source link

Application directory changes Directory name automatically on re-launch #336

Closed zeddyyz closed 2 years ago

zeddyyz commented 2 years ago

💬 Questions and Help

I'm using this to download files from firebase storage, which works perfectly. Code I use for downloading is as follows:

""" var fileInfo = await DefaultCacheManager().getSingleFile(url);

if (fileInfo != null) { await DefaultCacheManager().downloadFile(url);

fileInfo = await DefaultCacheManager() .getSingleFile(url);

print("Episode downloaded: " + fileInfo.uri.path); } """

With fileInfo.uri.path I save it to device local storage using Hive. Then the path is provided to a just_audio player widget which retrieves the file from the file path and plays the audio.

This process works perfectly when I download and play the audio in one go but then when I relaunch the app, the directory name changes. For ex: first it was "D2153E40-EF0A-4130-B717-D76A1B243394" and then relaunch app and it changed to "96767D5D-D425-4804-BBCF-1493BA1D5D31".

I've tried to utilize key with custom name and stalePeriod, but have had no luck.

Can I please get guidance on how to persist the application directly name where the file is stored?

renefloor commented 2 years ago

Yes that's how iOS works. The application directory isn't fixed and can always change, see also this answer: https://developer.apple.com/forums/thread/92693

If you want to save the path you should store the relative path and get the absolute path with path_provider using getTemporaryDirectory(). Or use your key with cachemanager.getFileFromCache(String key, {bool ignoreMemCache = false}); and get the path from the returned file.

BechirAhmed commented 2 years ago

Hi @zeddyyz can you show us how you could get songs from cache and the play them? list all cached songs, play them, add them to Queue. I'm using almost the same idea as yours, cache file and then save the path or the id using hive, then I could get cached file as Fileinfo

zeddyyz commented 2 years ago

@BechirAhmed I used this tutorial: https://suragch.medium.com/steaming-audio-in-flutter-with-just-audio-7435fcf672bf

This is to download/cache the audio file:

var fileInfo =
      await JustAudioCustomCacheManager
          .instance
          .getSingleFile(
              moduleSelected.url);

  print(fileInfo.path);

  var tempObj =
      new DownloadedModuleOffline(
    user.email,
    moduleSelected.id,
    moduleSelected.topicID,
    moduleSelected.url,
    moduleSelected.moduleName,
    moduleSelected.playPosition
        .toString(),
  );

  Hive.box<DownloadedEpisode>(
          "DownloadedEpisode")
      .add(
    DownloadedEpisode(
      user.email,
      moduleSelected.id,
      moduleSelected.topicID,
      fileInfo.path,
      moduleSelected.moduleName,
      '0:00:00.00000',
    ),
  );

Custom cache manager:

class JustAudioCustomCacheManager {
  static const key = 'downloadedEpisodes';

  static CacheManager instance = CacheManager(
    Config(
      key,
      stalePeriod: const Duration(days: 17),
      maxNrOfCacheObjects: 20,
      repo: JsonCacheInfoRepository(databaseName: key),
      fileService: HttpFileService(),
    ),
  );
}

If you follow the tutorial from that link, it's pretty easy. I had to make changes to the code to load the audio file and for background audio to work:

  final file = new File(url);

  await file
      .writeAsBytes((await rootBundle.load(url)).buffer.asUint8List());

  var _audioSourceBackground = AudioSource.uri(
    Uri.file(url),
    tag: MediaItem(
      // Specify a unique ID for each media item:
      id: moduleID,
      // Metadata to display in the notification:
      album: _manualTopicName,
      title: moduleName,
      artUri: Uri.file("/assets/launch.PNG"),
    ),
  );

  await _audioPlayer.setAudioSource(_audioSourceBackground,
      initialPosition: parseDuration(playPosition));
BechirAhmed commented 2 years ago

Hi @zeddyyz thanks for your reply and help, I did what you said but it keeps give me some errors.

[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: (-11828) Cannot Open
#0      AudioPlayer._load (package:just_audio/just_audio.dart:785:9)
<asynchronous suspension>
#1      AudioPlayer._setPlatformActive.setPlatform (package:just_audio/just_audio.dart:1351:28)
<asynchronous suspension>

The same error when tried android emulator, And when I print the _audioSourceBackground.uri it give the exact path to the file, see the example below

file:///var/mobile/Containers/Data/Application/61327A88-3B02-43CC-BCBB-76BC5E29E55F/Library/Caches/libCachedImageData/fa81fb50-3460-11ec-b813-05717f61c9c5.mp3

Just to know, I'm trying all of that using IOS real device, and there is an error I don't know if it's related to this.

NSURLConnection finished with error - code -1002

This error seems to be related to App Transport Security for IOS, when using non https urls