flutter_downloader icon indicating copy to clipboard operation
flutter_downloader copied to clipboard

Swift Conversion Discussion

Open Hackmodford opened this issue 3 years ago • 15 comments

I am in the process of converting the iOS plugin to Swift.

As part of this process there's a couple proposals I would like to make.

  1. Move the database implementation to Dart. Potentially using Hive instead of sql. So far this is significantly simplifying the codebase. One side-effect of this is removing the raw query method. Instead we could just provide the Hive box of download tasks. At a later date the Android side could be converted to use the same Hive database. In the end there is less code to maintain.

  2. Remove taskId from the Hive DownloadTask object model. Instead use id and rely on the platform's identifier. Side effect of this is that I don't believe you can "update" the id of an existing object model. Instead the model must be deleted and a new model created. I'm not sure if this will cause problems. At the very least I can provide the new id.

  3. Watching for task updates becomes simpler because we simply need to watch the Hive box for events. It looks like we could expose a stream of data for a single task or even the list of tasks.

Hackmodford avatar Jul 31 '22 02:07 Hackmodford

Thank you very much for contributing @Hackmodford!

I think all the points you made are very good. I'd love to simplify the codebase. That said, I think that first, we should just convert ObjC to Swift, and once we have this done & working & released to users, we can think of next steps.

I'm worried that if we try to do all at once, we could introduce many bugs, especially that we have no tests :(

bartekpacia avatar Jul 31 '22 11:07 bartekpacia

@bartekpacia What if I first focused on replacing SQL in both libraries to Hive in Dart? That removes an entire objective-c class.

Then I could focus on updating the rest of the Objective-C code to Swift?

I'd rather not convert something that will end up being deleted in the end.

Hackmodford avatar Jul 31 '22 19:07 Hackmodford

@Hackmodford If you think this is better, then sure, go on :)

What concerns me though (regarding going full-Dart) are notifications. When the download ends, we'll want to show a notification, and often times we'll have to do this in the background. For notifications, there's a great flutter_local_notifications plugin, but I'm just not sure if we can use it from the background. But I haven't thought a lot about it. I wish you good luck :)

bartekpacia avatar Jul 31 '22 19:07 bartekpacia

BTW, I'd prefer to have 1 issue for moving to Hive from SQLite, and then another issue for Swift. If you agree with me, you can change the title.

bartekpacia avatar Jul 31 '22 19:07 bartekpacia

@Hackmodford Hi again, how's it going? Were you able to find some time to work on this? Just asking out of curiosity :)

bartekpacia avatar Aug 14 '22 15:08 bartekpacia

It’s on my mind but is low priority. Last I was experimenting with getting the the iOS side to make requests to the flutter side. Ran into some issues with trying to use Hive…

Hackmodford avatar Aug 14 '22 21:08 Hackmodford

Thanks for update :)

bartekpacia avatar Aug 14 '22 21:08 bartekpacia

Does anyone know if it's possible for a callback invoked from native code to use flutter plugins?

I'm starting to suspect that the reason the database portion of this library was created separately for each platform was because you can't use a flutter plugin in the callback from a method invoked on the native side. If this is true, the problem ends up being that I cannot get the path for a hive (or SQL) database. Could anyone confirm this?

Hackmodford avatar Aug 20 '22 22:08 Hackmodford

I think that you have to get the reference to the static Dart function and then pass it over to the native side, from where you should be able to call it (like it's already done by this plugin). What's the exact problem you're getting?

bartekpacia avatar Aug 21 '22 18:08 bartekpacia

I'm still trying to wrap my head around how plugins work 😅

In any case, I realized that the Swift side can call a "initDatabase" function and pass the directory to flutter.

At this point I have Swift calling Dart code updating a Hive database. The problem now is that it doesn't seem like I am able to watch the box. (I suspect this is because the box is being updated in an ?isolate? but I'm trying to watch it elsewhere)

Hackmodford avatar Aug 21 '22 18:08 Hackmodford

You can see the progress here. https://github.com/Hackmodford/flutter_downloader/tree/hive

Hackmodford avatar Aug 21 '22 18:08 Hackmodford

Could you create a draft PR from the hive branch on your forked repository to this repository? This way it'd be easier to see all the changes :)

bartekpacia avatar Aug 21 '22 19:08 bartekpacia

Done https://github.com/fluttercommunity/flutter_downloader/pull/709

Hackmodford avatar Aug 21 '22 19:08 Hackmodford

I'm curious why a database is used at all. I mean out of the user perspective there is no need to persist those data, it could be memory only. When I kill the app I would be fine that the download is canceled.

To be honest I did not check the code yet. It's just my first impression before using this library.

rekire avatar Sep 10 '22 15:09 rekire

A database is needed to persist metadata such as ids, destination directories, final filenames, current progress, etc.

Hackmodford avatar Sep 10 '22 16:09 Hackmodford

I tried mixing Swift/Objective-c in the plugin and couldn't get anywhere. Was hoping I could slowly introduce Swift by replacing that database class. It looks like it's an all or nothing endeavor.

Hackmodford avatar Oct 25 '22 18:10 Hackmodford

Part of my effort was trying to migrate all the db code to Flutter. I was using Hive and having issues with the separate isolates trying to access the data. I just learned about an alternative called Isar that claims to work with multiple isolates. This might be exactly what we need. https://isar.dev/recipes/multi_isolate.html

Hackmodford avatar Oct 29 '22 22:10 Hackmodford

isar works much better! The download callback is finally hitting the UI 😌 Now to just get the id of the download...

Hackmodford avatar Oct 30 '22 14:10 Hackmodford