iOS项目(Swift),使用Flutter进行混合开发

2,264 阅读2分钟

当前Flutter版本1.17

使用的FlutterBoost版本1.12.13

先创建flutter module项目,参考官方文档,先cd至目标文件夹,执行命令为flutter create --template module flutter_module

创建成功后,打开flutter_module项目,打开pubspec.yaml文件,添加所需依赖

  flutter_boost: ^1.12.13
  flui: ^0.9.1
  dio: ^3.0.9

执行命令,更新依赖(VSCode保存后,会自动更新)

执行 flutter run 命令,生成pod

创建Swift项目,打开Swift项目中的 Podfile添加相关pod命令

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

platform :ios, '11.0'
use_frameworks!

target 'demo' do
  
  # flutter
  flutter_application_path = '../flutter_module'
  load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  install_all_flutter_pods(flutter_application_path)
end

执行pod install命令(每次 flutter_module 中的 pubspec.yaml 更改后,都需要再次执行 pod install 命令)

添加桥接文件Bridging-header.h,并参考FlutterBoost Demo,添加头文件

#import "GeneratedPluginRegistrant.h"
#import <flutter_boost/FlutterBoost.h>

打开 Appdelegate.swift 文件

import Flutter

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
    
    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // 注册flutter路由
        let router = PlatformRouterImp.init();
        FlutterBoostPlugin.sharedInstance().startFlutter(with: router, onStart: { (engine) in
            
        });
        
        return true
    }
    
}

在Swift项目中建立文件 PlatformRouterImp.swift

import UIKit

class LYGHFlutterContainer: FLBFlutterViewContainer {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.navigationBar.isHidden = true
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navigationController?.navigationBar.isHidden = false
    }
}

class PlatformRouterImp: NSObject, FLBPlatform {
    
    func open(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        var animated = false
        if exts["animated"] != nil {
            animated = exts["animated"] as! Bool
        }
        let vc = LYGHFlutterContainer.init()
        vc.setName(url, params: urlParams)
        vc.hidesBottomBarWhenPushed = true
        self.navigationController().pushViewController(vc, animated: animated)
        completion(true)
    }
    
    func present(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        var animated = false
        if exts["animated"] != nil {
            animated = exts["animated"] as! Bool
        }
        let vc = LYGHFlutterContainer.init()
        vc.setName(url, params: urlParams)
        navigationController().present(vc, animated: animated) {
            completion(true)
        }
    }
    
    func close(_ uid: String, result: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        var animated = false
        if exts["animated"] != nil {
            animated = exts["animated"] as! Bool
        }
        let presentedVC = self.navigationController().presentedViewController
        let vc = presentedVC as? FLBFlutterViewContainer
        if vc?.uniqueIDString() == uid {
            vc?.dismiss(animated: animated, completion: {
                completion(true)
            })
        } else {
            self.navigationController().popViewController(animated: animated)
        }
    }
    
    func navigationController() -> LYGHNavigationController {
        let navi = LYGHMainTabBarViewController.currentSelectedNavigationController()
        return navi!
    }
}

Swift跳转flutter_module项目

FlutterBoostPlugin.open("orderLogotics", urlParams:["orderNumber": model.streamNo ?? "", "type": model.streamName ?? ""], exts: ["animated": true], onPageFinished: { (_ result:Any?) in
                print(String(format:"call me when page finished, and your result is:%@", result as! CVarArg));
            }) { (f:Bool) in
                print(String(format:"page is opened"));
            }

flutter_module项目中的 main.dart 相关代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'modules/logistics_module/logistics.dart';
import 'package:flutter/services.dart';

void main() {
  if (Platform.isAndroid) {
    SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
    );
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  } else {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
  }

  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{
      'orderLogotics':
          (String pageName, Map<dynamic, dynamic> params, String _) {
        return OrderLogistics(params: params);
      },
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '',
      builder: FlutterBoost.init(postPush: _onRoutePushed),
      home: Container(),
    );
  }

  void _onRoutePushed(
    String pageName,
    String uniqueId,
    Map<dynamic, dynamic> params,
    Route<dynamic> route,
    Future<dynamic> _,
  ) {}
}