The Flutter hybrid development family includes the following:

  • Embed native View-Android
  • Embed native View-ios
  • Communicate with native -MethodChannel
  • Communicate with native -BasicMessageChannel
  • Communicate with native -EventChannel
  • Add Flutter to Android Activity
  • Add Flutter to Android Fragment
  • Add Flutter to iOS

Share one article every weekday, welcome to follow, like and forward.

A Flutter can be added to iOS projects as frameworks. To introduce a Flutter Module, you need to install Xcode, and Flutter supports iOS8 and above.

Create a Flutter module

Since Xcode cannot install the Flutter Module as Android Studio does, you can only create the Flutter Module by using the following command:

CD ios project root directory flutter create --template module my_flutterCopy the code

After the Flutter module is executed, it will be created in the ios project /my_flutter directory.

Ios is a hidden directory. You can run the Flutter Module separately to test its functionality. Ios code is added to existing application projects or plug-ins, not to the module’s.ios/directory.

Because the. Ios/directory is automatically generated, do not source control it. Before building modules on a new machine, run the flutter pub get in the my_flutter directory to regenerate the.ios/directory, and then use the Flutter module to build ios projects.

Embed the Flutter module into an existing application

There are two ways to embed the Flutter module into an existing iOS application:

  • Use CocoaPods and the installed Flutter SDK (recommended).
  • Create Frameworks for the Flutter engine, compiled Dart code, and all Flutter plug-ins. Embed frameworks manually and update the build Settings for the existing application in Xcode.

Applications cannot run on emulators in Release mode because Flutter does not yet support pre-output x86 / x86_64 binaries (AOT) for Dart code. Run in debug mode on emulator or real device, and in Release mode on real device.

The following two ways are to add Release Frameworks to the iOS application, so the device cannot select the emulator when compiling, or the build will fail.

Compiled successfully:

Failed to select emulator compilation:

Use CocoaPods and the installed Flutter SDK

This method requires all relevant developers to install the Flutter environment.

Assume that the existing application and the Flutter module are in the same directory. If you are using a different directory structure, you may need to adjust the relative paths as follows:

Modify the Podfile file in the iOS app, or create it manually if not:

flutter_application_path = '.. /my_flutter' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') target 'My App' do install_all_flutter_pods(flutter_application_path) endCopy the code

Please refer to CocoaPods’ official website.

Run the pod install command:

When changing the dependencies of a Flutter plugin in my_flutter/pubspec.yaml or running it for the first time, run the Flutter pub get in the Flutter module directory to refresh the list of plug-ins read by the Podhelper.rb script. Then, run pod Install again from the application directory.

The PodHelper.rb script emashes the plug-ins Flutter. Framework and App. Framework into the project.

Open My app.xcworkspace with Xcode, close and reopen if open, use ⌘B to compile the project.

Embed the Flutter Frameworks in Xcode

Generate the necessary Frameworks by command and embed them into the application by manually editing the existing Xcode project. You can use this method if your team members cannot install the Flutter SDK and CocoaPods locally, or if you do not want To use CocoaPods as a dependency manager in existing applications. Flutter Build ios must be run every time a code change is made in the Flutter module.

Run the following command to generate Frameworks:

flutter build ios-framework --output=./Flutter/
Copy the code

After execution, generate relevant compilation products in the corresponding directory:

Frameworks have been generated. There are many ways to link frameworks to an iOS application. Here is one.

willApp.frameworkFlutter.frameworkintoBuild Settings > Build Phases > Link Binary With Libraries:

Add the Frameworks directory to the left of the project:

Add ${PODS_ROOT}/.. in Build Settings -> Search Paths -> Framework Search Paths. /my_flutter/Flutter/Release

⌘B was used to compile the project, and the compilation was successful.

Create FlutterEngine and FlutterViewController

Embedding a Flutter page into an iOS application requires creating a FlutterEngine (the Flutter engine) and a FlutterViewController. The FlutterEngine is the host of the Dart VM and the Flutter runtime. The FlutterViewController is attached to the FlutterEngine to communicate and display the Flutter UI.

Create FlutterEngine:

import UIKit
import Flutter

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
  lazy var flutterEngine = FlutterEngine(name: "my flutter engine")

  override func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    flutterEngine.run();
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions); }}Copy the code

Add a button to jump to the Flutter page:

import UIKit
import Flutter

class ViewController: UIViewController {

    override func viewDidLoad(a) {
        super.viewDidLoad()
        let button = UIButton(type:UIButton.ButtonType.custom)
        button.addTarget(self, action: #selector(showFlutter), for: .touchUpInside)
        button.setTitle("According to Flutter." ", for: UIControl.State.normal)
        button.frame = CGRect(x: 80.0, y: 210.0, width: 160.0, height: 40.0)
        button.backgroundColor = UIColor.blue
        self.view.addSubview(button)
    }
    
    @objc func showFlutter(a) {
      let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
      let flutterViewController =
          FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
      present(flutterViewController, animated: true, completion: nil)}}Copy the code

The above code uses caching FlutterEngine, which is also recommended.

Another option is to use the implicit FlutterEngine. Using the implicit FlutterEngine will significantly increase the display time of the Flutter UI. This is usually not recommended. This can be useful if there is no good way to determine when to start the Dart VM and when the Flutter does not need to maintain state between view controllers.

func showFlutter(a) {
  let flutterViewController = FlutterViewController(project: nil, nibName: nil, bundle: nil)
  present(flutterViewController, animated: true, completion: nil)}Copy the code

Designated entry point

By default, FlutterEngine loads the main() method in the lib/main.dart file, and can also specify methods in other files:

flutterEngine.run(withEntrypoint: "newEntrypoint", libraryURI: "main.dart")
Copy the code

Initializing a Route

Starting with Flutter version 1.22, routes can be specified

let flutterEngine = FlutterEngine()
flutterEngine.run(
  withEntrypoint: FlutterDefaultDartEntrypoint, initialRoute: "/one_page")

Copy the code

communication

Lao Meng Flutter blog (330 controls usage + practical primer series) : laomengit.com