0
点赞
收藏
分享

微信扫一扫

【Flutter】三个Channel(Android-java / Ios-swift)

iOS集成Flutter与路由控制

本文的目的是将原生项目通过集成Flutter Module逐步将iOS和Android代码向Flutter代码迁移,从而最终实现iOS和Android的代码统一。
以下以iOS集成Flutter为例。
iOS集成Flutter与路由控制

通过CocoaPods集成

在当前iOS项目路径下,以下以项目名称为complex的iOS项目为例,创建名称为flutter_module的Flutter部分,可以通过VSCode或Android Studio直接创建对应的Module,还可以通过指令创建:

cd complex/
flutter create -t module flutter_module

然后我们通过CocoaPods进行集成,如下:

pod init

然后修改Podfile文件:

platform :ios, '13.0'

flutter_application_path = 'flutter_module/'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'complex' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  install_all_flutter_pods(flutter_application_path)
  # Pods for complex

end

执行pod命令:

pod install

发现还缺少flutter_post_install,补充进Podfile,最终为:

# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'

flutter_application_path = 'flutter_module/'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'complex' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  install_all_flutter_pods(flutter_application_path)
  # Pods for complex

end

post_install do |installer|
  flutter_post_install(installer)
end

然后通过Xcode直接Run,发现报错
Sandbox: bash(13818) deny(1) file-read-data xxx/complex/flutter_module/.ios/Flutter/flutter_export_environment.sh
提示很明显,那么我们进入Build Settings->Build Options->User Script Sandboxing,将Yes修改为No。
重新Run,Build Succeed。

iOS与Flutter的路由

之前可以通过- (void)setInitialRoute:(NSString*)route FLUTTER_DEPRECATED("Use FlutterViewController initializer to specify initial route");设置InitialRoute,可以改用- (instancetype)initWithProject:(nullable FlutterDartProject*)project initialRoute:(nullable NSString*)initialRoute nibName:(nullable NSString*)nibName bundle:(nullable NSBundle*)nibBundle NS_DESIGNATED_INITIALIZER;
但是实际上我切换到main.dart使用window.defaultRouteName区分不同的路由路径,发现window.defaultRouteName已经废弃了,现在使用View.of(context).platformDispatcher.defaultRouteName来区分不同的路由。
iOS部分完整代码为:

        let controller = FlutterViewController(project: nil, initialRoute: "xxxxxx", nibName: nil, bundle: nil)
        GeneratedPluginRegistrant.register(with: controller)
        navigationController?.pushViewController(controller, animated: true)

第二种方式是通过创建FlutterEngine来启动不同的入口,首先我们在AppDelegate创建FlutterEngineGroup,如下:

    lazy var engineGroup: FlutterEngineGroup = {
        return FlutterEngineGroup(name: "ios.flutter", project: nil)
    }()

这是为了应对多个入口,如果只有一个入口直接使用FlutterEngine也可以。
接下来通过FlutterEngineGroup创建FlutterEngine,如下:

        guard let delegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let engine = delegate.engineGroup.makeEngine(withEntrypoint: "firstFlutterController", libraryURI: nil)
        engine.run()
        let controller = FirstFlutterController(engine: engine, nibName: nil, bundle: nil)
        navigationController?.pushViewController(controller, animated: true)

然后在main.dart文件内添加新的入口,如下:

@pragma('vm:entry-point')
void firstFlutterController() {
  runApp(const FirstFlutterController());
}

如果项目内有多个原生页面和Flutter页面交叉切换推荐使用这种方法,因为:

/**
 * Creates a running `FlutterEngine` that shares components with this group.
 *
 * @param entrypoint The name of a top-level function from a Dart library.  If this is
 *   FlutterDefaultDartEntrypoint (or nil); this will default to `main()`.  If it is not the app's
 *   main() function, that function must be decorated with `@pragma(vm:entry-point)` to ensure the
 *   method is not tree-shaken by the Dart compiler.
 * @param libraryURI The URI of the Dart library which contains the entrypoint method.  IF nil,
 *   this will default to the same library as the `main()` function in the Dart program.
 *
 * @see FlutterEngineGroup
 */
- (FlutterEngine*)makeEngineWithEntrypoint:(nullable NSString*)entrypoint
                                libraryURI:(nullable NSString*)libraryURI;

不仅可以指定页面的路径还可以共享运行FlutterEngine,相对而言更灵活且消耗更低。

这里推荐一款路由控制第三方flutter_boost,原有的项目在pub上没有更新,这里需要到github上去下载。

举报

相关推荐

0 条评论