I run the WeChat applet in the Flutter App

current doubts

The development of WeChat mini-programs is getting faster and faster. At present, mini-programs have even replaced most of the ecological niches of Apps. The company’s pits have not increased but decreased. It can only allow native application development to take into account or change jobs for the development of mini-programs.

In my actual situation, the Flutter framework used by the company's application inevitably has the same function as the development of both Flutter application development and WeChat applet development. This kind of repetitive work of reinventing the wheel is very inefficient.

Why does this happen?

With the release of Flutter 1.5.4 on Google I/O in May 2019, it was announced that Flutter has really entered the era of all terminals, which means that only one code needs to be written, and it can run on iOS without any additional modification. , Android, Web, PC. Flutter is revolutionizing the mobile development ecosystem. From terminal-oriented development to framework-oriented development, it will not only change the way developers develop, but also more and more companies are paying attention to using Flutter.

As a cross-platform framework, Flutter's development technology stack integrates Native and front-end technologies, not only involves the development knowledge of Native (Android, iOS), but also absorbs many front-end (such as React) technical concepts and frameworks, and in On this basis, it has been improved, forming Flutter's own unique technical thinking.

insert image description here

But currently, Flutter does not support applets. Although Flutter for Web will eventually generate JS code, the JS and CSS generated by Flutter cannot be modified. In Flutter, there is no way to directly call the interface of the applet through Dart, so it is not a good choice to develop applets with Flutter at this stage.

generation of solutions

However, companies and businesses have to bow to the traffic of Internet giants. At the same time, the gradual popularity of small programs has also changed the habit of users to download apps. Whether shopping, ordering meals or doing errands, they will first search for "open and use, use and go". The small program can be used, eliminating the tedious process of downloading the App.

Of course, I also know that many developers have a lot of opinions on small programs, and apps will not die at will. After all, apps still have many advantages compared to small programs. So how to solve the efficiency problem when both App and applet development coexist?

Can the applets developed in the past run directly in the applications developed by Flutter? The same functional business only needs one small program development, and it can be implemented in other apps besides WeChat.

When I searched for related solutions and information on Google, I found that there are almost no such solutions abroad, but there are manufacturers in China that are doing this, and it is indeed reasonable to think about it. Based on the basic reality of the company's Flutter framework, the product called FinClip applet container technology can support Flutter and React Native other than native iOS and Android, and is directly compatible with WeChat applet syntax, so I probably tested this product.

Hands-on process

The principle is actually quite simple. FinClip provides a small program SDK to integrate with Flutter applications, so that the App has a host environment that can run small program business codes.
insert image description here

1. Obtain credentials

To integrate the SDK, you need to create an application on the FinClip platform and bind the applet, obtain the exclusive SDK KEY and SDK SECRET for each application, and then fill in the corresponding parameters when integrating the SDK. When the applet is opened, the SDK will automatically initialize and verify whether the SDK KEY, SDK SECRET and BundleID (Application ID) are correct.

2. Integrated plug-ins

Add dependencies in the project pubspec.yaml file.

mop: latest.version 

If the computer is a mac M1 chip, you also need to add the following 3 lines of code to the Podfile in the iOS folder

config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'

Example:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
      config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'
    end
  end
end

3、Flutter API

After integration, the SDK must be initialized before using the API provided by the SDK. Below I list some official necessary APIs, and you can also refer to the official documents for more specific details .

1) Initialize the sdk interface

  ///
  ///
  /// initialize mop miniprogram engine.
  /// 初始化小程序
  /// [sdkkey] is required. it can be getted from api.finclip.com
  /// [secret] is required. it can be getted from api.finclip.com
  /// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com
  /// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop
  /// [cryptType] is optional. cryptType, should be MD5/SM
  /// [disablePermission] is optional.
  /// [encryptServerData] 是否对服务器数据进行加密,需要服务器支持
  /// [userId] 用户id
  /// [finStoreConfigs] 多服务配置
  /// [uiConfig] UI配置
  /// [debug] 设置debug模式,影响调试和日志
  /// [customWebViewUserAgent] 设置自定义webview ua
  /// [appletIntervalUpdateLimit] 设置小程序批量更新周期
  /// [maxRunningApplet] 设置最大同时运行小程序个数
  ///
  Future<Map> initialize(
    String sdkkey,
    String secret, {
    
    
    String? apiServer,
    String? apiPrefix,
    String? cryptType,
    bool encryptServerData = false,
    bool disablePermission = false,
    String? userId,
    bool debug = false,
    bool bindAppletWithMainProcess = false,
    List<FinStoreConfig>? finStoreConfigs,
    UIConfig? uiConfig,
    String? customWebViewUserAgent,
    int? appletIntervalUpdateLimit,
    int? maxRunningApplet,
  }) 

2) Open the applet

 /// open the miniprogram [appId] from the  mop server.
  /// 打开小程序
  /// [appId] is required.
  /// [path] is miniprogram open path. example /pages/index/index
  /// [query] is miniprogram query parameters. example key1=value1&key2=value2
  /// [sequence] is miniprogram sequence. example 0,1.2.3,4,5...
  /// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com
  /// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop
  /// [fingerprint] is optional. the mop sdk fingerprint. is nullable
  /// [cryptType] is optional. cryptType, should be MD5/SM
  Future<Map> openApplet(
    final String appId, {
    
    
    final String? path,
    final String? query,
    final int? sequence,
    final String? apiServer,
    final String? scene,
  }) 

3) Obtain information about the applet currently in use

The fields included in the current applet information are appId, name, icon, description, version, thumbnail

  ///
  ///  get current using applet
  ///  获取当前正在使用的小程序信息
  ///  {appId,name,icon,description,version,thumbnail}
  ///
  ///
  Future<Map<String, dynamic>> currentApplet()

4) Close all currently open applets

  ///
  /// close all running applets
  /// 关闭当前打开的所有小程序
  ///
  Future closeAllApplets()

4. Official example

The official gave an example, and I will put it up directly, so you can refer to it.

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:mop/mop.dart';

void main() => runApp(MyApp());

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

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

    // Platform messages are asynchronous, so we initialize in an async method.
    Future<void> init() async {
    
    
        if (Platform.isIOS) {
    
    
            //com.finogeeks.mopExample
            final res = await Mop.instance.initialize(
                '22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', // SDK Key
                '1c11d7252c53e0b6', // SDK Secret
                apiServer: 'https://api.finclip.com', // 服务器地址
                apiPrefix: '/api/v1/mop' // 服务器接口请求路由前缀
                );
            print(res);
        } else if (Platform.isAndroid) {
    
    
            //com.finogeeks.mopexample
            final res = await Mop.instance.initialize(
                '22LyZEib0gLTQdU3MUauARjmmp6QmYgjGb3uHueys1oA', // SDK Key
                '98c49f97a031b555', // SDK Secret
                apiServer: 'https://api.finclip.com', // 服务器地址
                apiPrefix: '/api/v1/mop' // 服务器接口请求路由前缀
                );
            print(res);
        }
        if (!mounted) return;
    }

    @override
    Widget build(BuildContext context) {
    
    
        return MaterialApp(
            home: Scaffold(
            appBar: AppBar(
            title: const Text(' FinClip 小程序 Flutter 插件'),
        ),
            body: Center(
            child: Container(
            padding: EdgeInsets.only(
            top: 20,
        ),
            child: Column(
            children: <Widget>[
            Container(
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(5)),
                    gradient: LinearGradient(
                        colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
                        stops: const [0.0, 1.0],
                    begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
            ),
        ),
            child: FlatButton(
            onPressed: () {
    
    
            Mop.instance.openApplet('5e3c147a188211000141e9b1'); // 小程序 AppID
        },
        child: Text(
            '打开示例小程序',
            style: TextStyle(color: Colors.white),
            ),
            ),
            ),
            SizedBox(height: 30),
            Container(
            decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(5)),
            gradient: LinearGradient(
            colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
            stops: const [0.0, 1.0],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            ),
            ),
            child: FlatButton(
            onPressed: () {
    
    
            Mop.instance.openApplet('5e4d123647edd60001055df1', sequence: 1); // 小程序 AppID
            },
            child: Text(
            '打开官方小程序',
            style: TextStyle(color: Colors.white),
            ),
            ),
            ),
            ],
            ),
            ),
            ),
            ),
            );
            }
            }

final words

At present, I have found a solution based on my actual situation. If you have a better solution, please leave a message to discuss and exchange.

Guess you like

Origin blog.csdn.net/POHOU23/article/details/128931761