Jump native iOS works to achieve the specified page Flutter

Overview

In the previous article when we mentioned, iOS jump to a specific page Flutter project (multiple), Flutter only a single case, set setInitialRouter invalid, as follows

  let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)!
        flutterViewController.setInitialRoute("test1")

Based on not very willing, always I wanted to achieve the perfect solution, so the last few days looked at to address all aspects of the solution ultimately have viable options, as follows

1, the code set delegate

 Here the code more ' FlutterBasicMessageChannel ' is provided, wherein _kReloadChannelName to and consistent with the code on the flutter

let _kReloadChannelName = "reload"

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate ,FlutterAppLifeCycleProvider{
   
    
    static var shared: AppDelegate?
        
    var window: UIWindow?
 
    var _lifeCycleDelegate = FlutterPluginAppLifeCycleDelegate()
    var flutterEngine : FlutterEngine!
    var  flutterViewController : RKFlutterViewController!
    var  reloadMessageChannel : FlutterBasicMessageChannel!
    
    func addApplicationLifeCycleDelegate(_ delegate: FlutterPlugin) {
        _lifeCycleDelegate.add(delegate)
    }
    
    func flutterSetup(){
        flutterEngineFlutterEngine = (name: "rokid.flutter", Project: nil) 
        flutterEngine . RUN (withEntrypoint: nil) 
        // global engine (to solve the boot loader when m, and can not handle the native interaction issues) 
        flutterViewController = RKFlutterViewController (Engine: flutterEngine, nibName : nil, bundle: nil) ! 
        GeneratedPluginRegistrant .register (with: flutterEngine) 
        // achieve App routing Jump 
        reloadMessageChannel = FlutterBasicMessageChannel (name: _kReloadChannelName, binaryMessenger: flutterEngine, CODEC: FlutterStringCodec.sharedInstance ()) 
    } 
    
    FUNC the Application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        ...
        flutterSetup()
       ...
}    

 

2, iOS App jump specified route 

 

   @objc func handleButtonAction() {
         self.engine().navigationChannel.invokeMethod("setInitialRoute", arguments: "test")
        self.reloadMessageChannel().sendMessage("test")
        let flutterViewController = FlutterViewController(engine: self.engine(), nibName: nil, bundle: nil)!
        self.navigationController?.pushViewController(flutterViewController, animated: true)
    }


 func engine() -> FlutterEngine {
        return (UIApplication.shared.delegate! as! AppDelegate).flutterEngine
    }
    
    func reloadMessageChannel() -> FlutterBasicMessageChannel {
        return (UIApplication.shared.delegate! as! AppDelegate).reloadMessageChannel
    }

 

3, flutter routing code is as follows

 

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:ui' as ui;
import 'src/pages/playground/PlaygroundPage.dart';

/// Channel used to let the Flutter app know to reset the app to a specific
/// route.  See the [run] method.
///
/// Note that we shouldn't use the `setInitialRoute` method on the system
/// navigation channel, as that never gets propagated back to Flutter after the
/// initial call.
const String _kReloadChannelName = 'reload';
const BasicMessageChannel<String> _kReloadChannel =
BasicMessageChannel<String>(_kReloadChannelName, StringCodec());


void main(){
  // Start listening immediately for messages from the iOS side. ObjC calls
  // will be made to let us know when we should be changing the app state.
  _kReloadChannel.setMessageHandler(run);
  // Start off with whatever the initial route is supposed to be.
  run(ui.window.defaultRouteName);
}


Future<String> run(String name) async{
  // The platform-specific component will call [setInitialRoute] on the Flutter
  // view (or view controller for iOS) to set [ui.window.defaultRouteName].
  // We then dispatch based on the route names to show different Flutter
  // widgets.
  // Since we don't really care about Flutter-side navigation in this app, we're
  // not using a regular routes map.
  switch (name) {
    case "test":
      runApp(appRouter(title: "我是路由测试test00",));
      break;
    case "test1":
      runApp(appRouter(title: "我是路由测试test01",));
      break;
    case "test2":
      runApp(appRouter(title: "我是路由测试test02",));
      break;
    default:
      runApp(MyApp());
      break;
  }
  return '';
}

class  appRouter extends StatelessWidget {
  appRouter({this.title});

  final String title;
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter rokid',
      debugShowCheckedModeBanner: false,// 显示和隐藏
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PlaygroundPage(title: '$title'),
    );
  }
}


class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter rokid',
      debugShowCheckedModeBanner: false,// 显示和隐藏
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        //Press the Run or> A Flutter Flutter Hot Reload in the IDE) The Notice that.
         // counter RESET DID Not Back to ZERO; IS Not RESTARTED The file application. 
        primarySwatch: Colors.blue, 
      ), 
      Home: PlaygroundPage (title: ' Ruoqi laboratory ' ), 
      routes: <String, WidgetBuilder> {
         " router1 " : (_) => new new PlaygroundPage (title: " I am the internal routing test test00 " ,),
         " router2 " : (_) => new new PlaygroundPage ( title: " I am the internal routing test test01 ",) 
    }, 
    ); 
  } 
}

Reflections and summary

 The above code can achieve: native -> any flutter, flutter Engine is but a single example, can achieve native-> flutter -> native-> flutter it?

Interactive features and how to choose? ? ?

Reference material

https://github.com/flutter/flutter/issues/27882

https://github.com/flutter/flutter/blob/master/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.m

https://github.com/flutter/flutter/blob/master/dev/integration_tests/ios_add2app/flutterapp/lib/main.dart

 

Guess you like

Origin www.cnblogs.com/kingbo/p/11269026.html