[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-content-flutter-packages-and-plugins-a-quick-primer":3},"\u003Cp>Last year I wanted to implement a new feature in one of our flutter apps, which was the ability to watch videos offline (which was surprisingly hard to do).\u003Cbr>\u003Cbr>Once I found out, that the official video_player plugin does not support offline playback of locally stored m3u8 playlists, I excitedly went down the rabbit hole.\u003C\u002Fp>\u003Cp>So here’s a quick summary of what I learned.\u003C\u002Fp>\u003Ch3 id=\"packageplugin-landscape\">Package\u002FPlugin Landscape\u003C\u002Fh3>\u003Ch4 id=\"packages\">Packages\u003C\u002Fh4>\u003Cp>In the Flutter world we usually refer to packages as dart only units of code that can be imported as so called packages in the pubspec.yaml file.\u003C\u002Fp>\u003Ch4 id=\"plugins\">Plugins\u003C\u002Fh4>\u003Cp>A plugin on the other hand, usually consists of dart code and native code. It’s used to expose native code to your dart UI code, famous examples are the camera plugin or in our case the video_player plugin.\u003C\u002Fp>\u003Cp>However here is where the fun begins.\u003C\u002Fp>\u003Cp>When you decide to write your own plugin, you ultimately have to understand that there are quite some different approaches you can take to do that.\u003C\u002Fp>\u003Cp>If you want to use code of a native library that’s written in C, like sqlite for example, you can use \u003Cstrong>dart:ffi \u003C\u002Fstrong>\u003Ca href=\"https:\u002F\u002Fdart.dev\u002Finterop\u002Fc-interop\" rel=\"nofollow noopener\">https:\u002F\u002Fdart.dev\u002Finterop\u002Fc-interop\u003C\u002Fa>\u003C\u002Fp>\u003Cp>There is also experimental support for objective-c and swift interop through \u003Cstrong>package:ffigen\u003C\u002Fstrong> \u003Ca href=\"https:\u002F\u002Fdart.dev\u002Finterop\u002Fobjective-c-interop\" rel=\"nofollow noopener\">https:\u002F\u002Fdart.dev\u002Finterop\u002Fobjective-c-interop\u003C\u002Fa>\u003C\u002Fp>\u003Cp>You can utilize \u003Cstrong>package:jnigen\u003C\u002Fstrong> to interop with Java and Kotlin, \u003Ca href=\"https:\u002F\u002Fdart.dev\u002Finterop\u002Fjava-interop\" rel=\"nofollow noopener\">https:\u002F\u002Fdart.dev\u002Finterop\u002Fjava-interop\u003C\u002Fa>.\u003C\u002Fp>\u003Cp>To make the list complete there is \u003Cstrong>dart:js_interop\u003C\u002Fstrong> to work with javascript and browser API’s in case you do web development, \u003Ca href=\"https:\u002F\u002Fdart.dev\u002Finterop\u002Fjs-interop\" rel=\"nofollow noopener\">https:\u002F\u002Fdart.dev\u002Finterop\u002Fjs-interop\u003C\u002Fa>.\u003C\u002Fp>\u003Cp>Note that ffigen and jnigen are considered experimental as of this writing.\u003Cbr>So what’s the current approach then?\u003C\u002Fp>\u003Cp>Currently so called \u003Cstrong>PlatformChannels\u003C\u002Fstrong> are used to communicate with native SDKs, wich requires sending\u002Freceiving messages on both sides (the dart and the native side of the plugin).\u003C\u002Fp>\u003Cp>When we speak flutter plugins, there are even more subtypes like:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cstrong>Federated plugins\u003C\u002Fstrong> (Plugins that have one or more platform plugins)\u003C\u002Fli>\u003Cli>\u003Cstrong>Endorsed federated plugins\u003C\u002Fstrong> (Plugins that already import platform plugins)\u003C\u002Fli>\u003Cli>\u003Cstrong>Non-endorsed federated plugins\u003C\u002Fstrong> (Plugins that do not import platform plugins, so you have to do it)\u003C\u002Fli>\u003C\u002Ful>\u003Cp>I don’t want to describe all that in detail, as it is already perfectly available in the official documentation here: \u003Ca href=\"https:\u002F\u002Fdocs.flutter.dev\u002Fpackages-and-plugins\u002Fdeveloping-packages\" rel=\"nofollow noopener\">https:\u002F\u002Fdocs.flutter.dev\u002Fpackages-and-plugins\u002Fdeveloping-packages\u003C\u002Fa>\u003C\u002Fp>\u003Cp>The only thing that’s important:\u003Cbr>If you write a plugin, make it be a federated plugin — it’s the “official” way.\u003C\u002Fp>\u003Cp>As I try to do more regular, but short and concise stories, I'll stop right here.\u003Cbr>In the next story we'll talk about writing or modifying an \u003Cstrong>Endorsed federated plugin \u003C\u002Fstrong>that's using\u003Cstrong> PlatformChannels \u003C\u002Fstrong>like\u003Cstrong> video_player (\u003C\u002Fstrong>\u003Ca href=\"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fvideo_player\" rel=\"nofollow noopener\">https:\u002F\u002Fpub.dev\u002Fpackages\u002Fvideo_player\u003C\u002Fa>).\u003C\u002Fp>\n\u003Chr>\n\u003Cp>\u003Cstrong>Next in this series:\u003C\u002Fstrong> \u003Ca href=\".\u002Fflutter-offline-playback-for-video-player\">Flutter: Offline playback for video_player\u003C\u002Fa> — how we added offline HLS playback to our mobile app.\u003C\u002Fp>"]