Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems publishing a Flutter app with a binded Rust binary to the AppStore

Context

We have a Flutter application that is fully functional and it's already published to both the PlayStore and the AppStore.

We're trying to add a Rust binary to the app so that we can use some SDKs that are written in that language.

In order to achive this, we're using Flutter's FFI system with which we can execute native calls to the compiled binary and consume the results from those executions.

In Android we haven't had any problems, it works both in development mode and in production, the binary is added to the bundle when compiling and published with the app to the PlayStore.

The problem

The problem we are having is with iOS. When we run the app locally in development mode, the app works just fine, it compiles seamlessly and we can execute native calls to Rust both from an iOS emulator and from a physical device. Now, when we try compiling the app for deployment to the AppStore is when the problems arise.

The compiling process is divided in 2 steps, first we build the Runner.app package:

flutter build ios

This generates the Runner.app that is then used as input for the Xcode to generate the Archive that will be uploaded to the AppStore:

Xcode Archive

The problem we are facing is that when we archive the Runner.app, the binary gets stripped away by the compiler and the Rust functions are not packaged. This means that when the app reaches the AppStore (both TestFlight and Production) the binary is not there.

Our setup

Our app is built using:

  • Flutter 2.8.1-stable
  • Rust 1.58.1

The binary we're trying to bundle is a Compiled static libary: library.a. This binary was built using cargo-lipo as a universal library. (We know cargo-lipo is in maintainance status, but we've also tried bundling binaries built directly with cargo build and the results are the same).

This is our Podfile:

# Uncomment this line to define a global platform for your project

platform :ios, '10.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.

ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {

  'Debug' => :debug,

  'Profile' => :release,

  'Release' => :release,

}

def flutter_root

  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)

  unless File.exist?(generated_xcode_build_settings_path)

    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"

  end

  File.foreach(generated_xcode_build_settings_path) do |line|

    matches = line.match(/FLUTTER_ROOT\=(.*)/)

    return matches[1].strip if matches

  end

  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"

end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do

  use_frameworks!

  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

end

post_install do |installer|

  installer.pods_project.targets.each do |target|

    flutter_additional_ios_build_settings(target)

  end

end

This is the podspec of the Dart plugin that has the Rust binary:

#

# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.

# Run `pod lib lint defiant_core.podspec` to validate before publishing.

#

Pod::Spec.new do |s|

  s.name             = 'defiant_core'

  s.version          = '0.0.1'

  s.summary          = 'A new flutter plugin project.'

  s.description      = <<-DESC

A new flutter plugin project.

                       DESC

  s.homepage         = 'http://example.com'

  s.license          = { :file => '../LICENSE' }

  s.author           = { 'Your Company' => '[email protected]' }

  s.source           = { :path => '.' }

  s.source_files = 'Classes/**/*'

  s.public_header_files = 'Classes**/*.h'

  s.vendored_libraries = "**/*.a"

  s.static_framework = true

  s.dependency 'Flutter'

  s.platform = :ios, '9.0'

  # Flutter.framework does not contain a i386 slice.

  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }

  s.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-force_load $(PODS_TARGET_SRCROOT)/**/*.a" }

  s.swift_version = '5.0'

end

What we've tried so far and got the same result (or worse)

  • Compiling the binary using cargo build instead of cargo-lipo
  • Playing with the iOS version in the Podfile and the podspec
  • Removing the use_frameworks! line
  • Changing this 2 lines following different Github issues suggestions:
# ...
  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
  s.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-force_load $(PODS_TARGET_SRCROOT)/**/*.a" }
# ...
  • Removing this line s.static_framework = true
  • Setting the exact location of the .a file in the line s.vendored_libraries = "**/*.a"
  • Changing the code striping configs in Build Settings in the Runner Target in Xcode:

Xcode Runner Target Build Settings

  • Compiling the headers file (.h) and linking the binary (.a) in the Build Phase in the Runner Target in Xcode:

Headers and Binary Build Phase

  • Changing the target architecture in the Runner Build Settings in Xcode:

Changing architecture Runner Build Settings

Conclusion

So far, nothing has worked... We're running out of ideas, so we'd be more than grateful if anyone could point us in the right direction.

Cheers!

like image 445
Ivan Eidel Avatar asked Jun 01 '26 04:06

Ivan Eidel


1 Answers

I met the same problem, and fixed by following:

  • https://github.com/fzyzcjy/flutter_rust_bridge/issues/496
  • http://cjycode.com/flutter_rust_bridge/integrate/ios_headers.html

I think the reason is the release build will strip the symbols which aren't used, and the symbols generated by Rust are directly used by Dart not the App. So you need to use them directly in the App.

like image 104
Wang Hui Avatar answered Jun 02 '26 17:06

Wang Hui



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!