Intro to Platform Channels: Building an Image Picker in Flutter

Andrea Bizzotto
Apr 26, 2018 · 4 min read

Platform channels are the gateway to accessing platform-specific code in Flutter.

What do I mean by platform-specific? Here are some examples:

  • Access to device inputs (camera, microphone, location, bluetooth, motion sensors)
  • Secure storage (a.k.a. Keychain on iOS)

Platform channels are also the basic building block for creating plugins in Flutter.

And while the Dart Packages repository already has a lot of plugins ready to use, you may find yourself in this situation:

  • Need to fix a bug on an existing plugin and don’t have time to wait for the author to do it?
  • Need a specific platform feature for which there is no plugin yet?

Understanding platform channels will make your life easier.

Today I’ll show you how to use them to build an image picker, and hook it up to your Flutter app.

Before we dive in, let’s look at the anatomy of an app using platform channels:

Image for post
Image for post
Platform Channels diagram. Source: Flutter Docs

If we setup a MethodChannel to talk to the host application, we can access platform and 3rd party native APIs.

Sounds great! Time for an example:

Photos and Camera Image Picker

Image for post
Image for post

Let’s start by creating an ImagePickerChannel that we will use to interface with the native host:

This works as follows:

  1. We create a MethodChannel and give it a name.
  2. Inside the pickImage() method, we call platform.invokeMethod(), passing pickImage as a name, and camera or photos as the image source.
  3. We then parse the result, which will be either a String representing a file path, or a FlutterError if something went wrong.
  4. Finally, we return a File with our image path (this can be rendered with Image.file), or throw an error if anything went wrong.

Note that the result could be anything. In fact, the invokeMethod() call returns Future<dynamic>. In creating the channel for our image picker, we define a contract that requires the host app to return either String or FlutterError.

Time to jump over to the native code. Let’s take a look at how this works on iOS.

Implementing the image picker on iOS

The first is a simple wrapper for UIImagePickerController, which specifies a sourceType and a completion handler:

Then, we’re going to create a FlutterChannelManager class. I’ll show you the code first, then explain it:

This works as follows:

  • We pass in a FlutterViewController. When building Flutter apps, the root view controller of the iOS app is always an instance of this class.
  • We register a FlutterMethodChannel, using our flutterViewControlleras a binaryMessenger. This is needed to communicate across the channel.
  • In the setup() method, we add our method call handler. We can use the call.method and call.arguments strings as inputs to determine what action the Flutter app wants to take.
  • In this case we recognize the pickImage method, and determine the sourceType to be either camera or photos.
  • We then build and present our image picker, which either shows the photo gallery or the camera capture screen. This includes a check for isSourceTypeAvailable(.camera) as camera capture is not supported on the iOS Simulator.
  • If an image is retrieved, it is saved to the temporary directory and a path to its file is returned.
  • On completion, we pass back the file path or any error to the channel.

Note how the image is saved to a file, and its file path is passed back as a result. As we have seen in the Flutter code, this is then used to retrieve the file and render it as an Image.

An alternative approach would be to decode the image into a byte array, and pass this along with the width, height and scale across the channel. In this configuration, the Flutter app can then reconstruct the image via Image.memory.


Finally, our AppDelegate:

Phew. That was quite a bit of code setup — most of it is boilerplate code to hook up the native image picker and saving to file.

Using platform channels is actually quite simple and boils down to this:

One final note for iOS: As our app accesses the camera, it is required to add a NSCameraUsageDescription key to the Info.plist file, as described on the Apple Docs.

What about Android?

Flutter already ships with an official image picker plugin. You can inspect the code and see how it’s done.

Here is the GitHub repo for this project. Enjoy!

Conclusion

You can use them:

  • to hook up your Flutter apps to platform-specific APIs
  • as a stepping stone to build your own plugins

And before you roll your own, make sure to check for existing plugins on pub.dartlang.org first.

Happy coding!

For more articles and video tutorials, check out Code With Andrea.

Image for post
Image for post

About me: I’m an iOS & Flutter developer, juggling between contract work, open source, side projects and blogging.

I’m @biz84 on Twitter. You can also see my GitHub page. Feedback, tweets, funny gifs, all welcome! My favourite? Lots of 👏👏👏.

Code With Andrea

Learn to build iOS and Android apps with Dart and Flutter

Andrea Bizzotto

Written by

iOS, Flutter Developer & Instructor ❖ https://codewithandrea.com ❖ Open Source https://github.com/bizz84 ❖ Watching #ClimateChange

Code With Andrea

Learn to build iOS and Android apps with Dart and Flutter

Andrea Bizzotto

Written by

iOS, Flutter Developer & Instructor ❖ https://codewithandrea.com ❖ Open Source https://github.com/bizz84 ❖ Watching #ClimateChange

Code With Andrea

Learn to build iOS and Android apps with Dart and Flutter

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store