Part 5: iOS specific instructions

FRB Template App: Applying the modified Workflow.

iOS steps

Generate the Dart Interface

Our next task is to create the generated code. This will also copy the C header file bridge_generated.h into the folder ios/Runner/. Use this command (you need to be in the root of your project):

flutter_rust_bridge_codegen \
--rust-input rust/src/ \
--dart-output ./lib/bridge_generated.dart \
--dart-decl-output ./lib/bridge_definitions.dart \
--c-output ios/Runner/bridge_generated.h

Create the subproject

How is a subproject created in Xcode?

Simply open the ios/Runner.xcodeproj in Xcode, open the rust/ directory in Finder and drag the rust.xcodeproj into the Runner folder. The next images will illustrate the steps.

Open Runner.xcodeproj

Drag the file rust.xcodeproj into the Runner Project

The new subproject

Adjust the Runner Target's Build Phases

For iOS, FRB recommends to include the static library.

a) In Runner Target's Build Phase -> Target Dependencies:

Click on "+" and select rust-staticlib.

b) In Runner Target's Build Phase -> Link Binary with Libraries:

Click on "+" and select librust_static.a.

Adjusted Build Phase

Adjust the Runner-Bridging-Header.h file

Switch to Visual Studio Code and open the file ios/Runner/Runner-Bridging-Header.h to add our generated header file bridge_generated.h.

Add the line:

#import "bridge_generated.h"

The content should look like:

#import "GeneratedPluginRegistrant.h"
#import "bridge_generated.h"

Adjust the AppDelegate.swift file

In Visual Studio Code, open the file ios/Runner/AppDelegate.swift. We need to call the function dummy_method_to_enforce_bundling() (from FRB) somewhere to avoid that Xcode handles our library as dead code.


let dummy = dummy_method_to_enforce_bundling()

Your file should look like:

import UIKit
import Flutter

@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let dummy = dummy_method_to_enforce_bundling()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)