While Flutter developers, in the eyes of many, enjoy superior tooling and a more predictable programming environment, there is one feature of web development that we often wish we had. This article will explore this coveted feature, focusing on how it can improve our Flutter development services.
Table of Contents
- From Web to Mobile: Navigating the Challenges of Bug Fixes and Releases with Flutter
- Flutter_eval: The Open-Source CodePush Alternative for Fast, Secure Flutter Apps
- Building Remote Code Delivery in Flutter with the Magical Trio
- Step-by-Step Guide: Setting Up flutter_eval for Remote Code Swaps in Your Flutter App
- Ensuring Security in Remote Code Updates for Flutter Apps
- Flutter_eval: Best Practices and App Store Compliance Tips
- Stay Agile and Streamline Review Processes with Flutter_eval
Our mobile-exclusive DX parts include stateful hot-reload, a tool that mobile Flutter development companies frequently use but is missed in non-Flutter projects. The absence of this feature can lead to significant time loss daily as Flutter companies struggle to regain the state of the app section they are currently working on. Moreover, the stability and robustness of our platforms are commendable, freeing us from concerns about ad blockers interfering with network requests or add-ons disrupting our application layout, which can lead to unexpected bugs. However, there is one aspect of the web developer's experience that I, and perhaps many of you, cannot help but envy – the capability to update Flutter apps faster and push code updates without re-publishing through app stores. This article will delve into this feature, exploring its potential to revolutionize the Flutter development process.
From Web to Mobile: Navigating the Challenges of Bug Fixes and Releases with Flutter
In the realm of web development, addressing bugs and deploying fixes is a seamless procedure. When a bug is encountered, a developer can promptly address it, deploy the solution, and instruct the user to refresh the page to resolve the issue simply. The deployment process can even be automated after a commit to the main branch. This capability also extends to rollbacks; if a previous version was more stable, developers could easily revert to it, offering a high degree of flexibility and control.
In contrast, the mobile development journey is a more complex and unpredictable one. When a broken feature is reported, it is promptly fixed, but the process becomes uncertain when the release is sent for review. The procedure can be a gamble, with approval times ranging from under an hour to several days, depending on the reviewer's findings. If a compliance issue is discovered, negotiations for a later fix can become political, with the primary concern being the user's smooth experience with the app.
Even after approval, the rollout process is still uncertain. Not all users may receive the fix, as updates depend on device usage and charging patterns. Some users may never update to the newest version, leaving unresolved issues in the error tracking system. While there are mitigation options like feature flags and forced updates, one aspect remains elusive: store reviews. Automating and enhancing the reliability of this process would be a welcome solution in the mobile development journey.
Flutter_eval: The Open-Source CodePush Alternative for Fast, Secure Flutter Apps
I would like to introduce you to a fascinating tool called flutter_eval, an open-source app release tool. It is part of a larger open-source app release tool project known as dart_eval, a portable virtual machine designed for executing Dart code. Think of it as an alternative to CodePush, specifically, a CodePush for Flutter apps, much like Firefox's "Spidermonkey" JavaScript engine is to Chrome's V8. However, flutter_eval stands out with its unique capability to run inside your native Dart code. It uses the analyzer package to parse the code, ensuring full compatibility with standard Dart tooling.
The most intriguing aspect of flutter_eval is its potential to allow developers to remotely switch their app's implementation, including logic and UI, bypassing the entire review process. This makes flutter_eval a compelling CodePush alternative for those looking to update Flutter apps faster and push code updates without re-publishing. Written in Dart, can be used in any environment where Dart is supported, including Android, iOS, desktop, and even the web, which adds an exciting twist to the context of this article. This functionality can significantly simplify the Flutter app release process, providing an edge for Flutter agencies and companies working on tight timelines.
When it comes to code safety, dart_eval prioritizes it with a robust and built-in security layer to protect your projects. By default, remote code can only interact with the compiled Dart code and its memory. However, the mechanism enables you to define which resources are accessible by the code running in the virtual machine. We will get into the details later in the discussion.
Building Remote Code Delivery in Flutter with the Magical Trio
Let's explore the architecture needed for remote code delivery and Flutter dynamic code execution.
To enable the ability to switch widgets at runtime, we require three key components:
dart_eval: This component plays dual roles in the process. It acts as the virtual machine that runs our remote code, and it also serves as a command-line interface on the development machine for compiling the code into an .evc file.
eval_annotation: This annotation marks the parts of the code that we intend to switch at runtime.
flutter_eval: This component provides specific features for the Flutter framework. It includes a widget that downloads and configures the remote code package. Flutter_eval also includes helper widgets that switch the implementation at the appropriate time.
It's important to note that dart_eval does not replace your existing app implementation. Instead, it works with your current code to provide remote updates. However, these updates should be applied to specific parts of the app. We will discuss this in more detail later.
Step-by-Step Guide: Setting Up flutter_eval for Remote Code Swaps in Your Flutter App
To begin the setup, open any existing Flutter project and add flutter_eval as a dependency. This will give you access to HotSwapLoader and HowSwap widgets. HotSwapLoader is a widget that loads and caches your remote code on the target device. Simply point to the HTTPS endpoint containing your .evc file (which we’ll generate in a bit), and HotSwapLoader will handle the rest.
Once loaded, HotSwap widgets will ensure that the remote code replaces sections of the Dart code shipped with the application based on the hot-swap id. This setup can help Flutter companies streamline and simplify Flutter app release processes. In the basic setup, we’ll use raw strings, but enums are recommended to avoid typos. For now, take note of the id selected here: #myHomePage. The childBuilder function ensures there’s something meaningful to render for the app. If the .evc code cannot be accessed, childBuilder will simply render the code provided with the original app’s release.
Use the args array if you have additional arguments for the remote widget. It must always be populated with at least the current widget context, as it’s necessary for Flutter to render the widgets correctly, but it will accept any number of arguments. As you can see, the BuildContext uses flutter_eval’s $BuildContext helper class, which wraps the context generated via shipped code to work with the runtime dart_eval VM. More details can be found in the documentation, but we’ll skip this complexity for brevity.
Next up is the cool part: preparing the hot swap package. Runtime code replacements are shipped independently from the app. Therefore, we store the remote code in a separate package in the recommended setup.
Start by creating the package, just like you would create any other package project. Then, get the flutter_eval.json file from the flutter_eval GitHub release matching the version number of your current flutter_eval version. The flutter_eval.json file contains bindings for many Flutter widgets that are shipped with the Flutter framework, so you can use them in the remotely delivered code.
Then, create a .dart_eval/bindings directory in your new project and store the file there. It’ll be used in the compilation step.
While still in the new package project, make sure to add the eval_annotation dependency. It’ll give you access to the @RuntimeOverride annotation, allowing you to later replace the tag during runtime. Each RuntimeOverride annotation should decorate a function that returns a Widget. The args list you provide for the matching HotSwap widget will be converted to arguments of the function declared here.
Once your implementation is ready, compile the code with the dart_eval CLI. If you haven’t already, activate it first, then call dart_eval compile with the desired output filename.
Now, the grand finale – publishing your code. My only recommendation is to pick a reliable hosting for your .evc files. Once live, the new .evc contents will replace the current implementation in the target apps. It’s also a good idea to include the application version number with the .evc file request. At some point, as you might have multiple app versions using .evc files, it’s advisable to be able to swap contents per app version to avoid interlocks.
Ensuring Security in Remote Code Updates for Flutter Apps
As promised, let's discuss the tool's security aspect. If the .evc hosting is compromised, an attacker could potentially cause significant harm to the end-users' devices. Although limiting the number of widgets that can be remotely updated may help reduce the risk, it does not eliminate the possibility of turning your app into ransomware or a cryptocurrency miner. Thus, Flutter development services should ensure only specific parts of the app can be updated and maintain strict control over which resources the remote code can access.
This potential security risk was identified early on in the development process, and as a result, your remote code does not have access to any resources on the disk or the network by default. However, suppose your use case requires granting access to potentially risky resources. In that case, you can still specify which directories on the disk and which domains on the web can be accessed, providing a more granular level of control over the security of your application.
Flutter_eval: Best Practices and App Store Compliance Tips
Before integrating flutter_eval into your app, there are several considerations to keep in mind. Some of these have been mentioned earlier, but here is a condensed set of guidelines to follow:
Do's:
Ensure that you provide some basic functionality with the code shipped with the app, in case of poor network conditions or your hosting is inaccessible. Having loading indicators everywhere will not provide a good user experience.
Identify overrides using consts instead of raw strings to avoid typos or name conflicts.
Send version information with the .evc request to stay agile with matching .evc files to app versions, should some native dependency cause conflicts.
Don'ts:
Avoid building your entire app with flutter_eval. While technically possible, it is not recommended, as network access is not guaranteed on mobile devices. If your user has no network access on the first launch, your app will be useless.
Do not perform major overhauls via remote updates. Store policies are vague but state that unreviewed functionality can result in a ban. While there are different levels to this, switching your app from a music player to a crypto exchange will get you banned. Unsupervised rebranding might get you nexted, while fixing the existing functionality and offering user-customized content is fine. Exploring the store policies’ boundaries at your own risk is advisable, but sticking to bug fixes and feature enhancements is recommended.
A peek at store regulations
Please note that this summary is for clarification purposes only and should not be considered legal advice. It is important to thoroughly read your agreements.
An app distributed via Google Play may not modify, replace, or update itself using any method other than Google Play's update mechanism. Likewise, an app may not download executable code (such as dex, JAR, .so files) from a source other than Google Play. This restriction does not apply to code that runs in a virtual machine or an interpreter that either that provides indirect access to Android APIs (such as JavaScript in a webview or browser)
[...] interpreted code may be downloaded to an Application but only if the code:
a) does not change the primary purpose of the Application by providing
features or functionality that are inconsistent with the intended and
advertised purpose of the Application as submitted to the App Store,
b) does not create a store or storefront for other code or applications, and
c) does not bypass signing, sandbox, or other security features of the OS.
~ Apple Developer Program License Agreement
Both app stores generally allow the downloading and running of interpreted code, provided it does not directly access system APIs or bypass OS security measures. Additionally, the app cannot change its purpose through these updates, and it cannot offer an internal app gallery that is updated without allowing store reviewers to examine it before it is made available to users.
Stay Agile and Streamline Review Processes with Flutter_eval
Remember, flutter_eval is all about helping you with the review process while your production environment is in crisis. If you need support implementing flutter_eval or other Flutter development services, contact Monterail for expert assistance. We would be more than happy to help.