美文网首页Flutter跨平台移动开发FlutterFlutter
想尝试Flutter? 重新开发成本高? 教你Flutte

想尝试Flutter? 重新开发成本高? 教你Flutte

作者: NewSongs | 来源:发表于2019-01-02 00:55 被阅读191次

    一、Flutter简单介绍

    Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。

    在这里不对Flutter过多介绍。
    如果你想安装Flutter或想了解更多Flutter相关信息可关注以下网址:
    Flutter官方 https://flutter.io/
    Flutter中文网 https://flutterchina.club/


    二、分析Flutter Xcode项目

    1、创建Flutter项目

    当安装完成Flutter环境后,我们在终端下使用"flutter create flutter_app"命令来创建一个名为"flutter_app"的项目来一起分析一下flutter的目录

    2、分析iOS运行所需内容

    1.我们首先运行一下看看项目有没有问题。首先打开iOS模拟器,终端进入flutter_app目录下,我们执行"flutter run"命令运行项目,可以看到一个计数器的项目启动起来了。我们直接打开flutter_app目录下的ios文件夹里面是一个xcode项目,直接打开Runner.xcworkspace项目结构如下:

    xcode目录

    2.Flutter目录
    Flutter目录中主要用到的是flutter_assets、App.framework、Flutter.framework这三个文件。

    目录 说明
    flutter_assets 项目资源文件(图片、字体等)都会存放在这个目录下
    App.framework 所有Flutter代码都会编译进这个库文件
    Flutter.framework Flutter运行所需库文件

    注:App.framework和Flutter.framework在debug、release模式下会有所不同,后面我们需要在debug和release下分别取出相应的库文件

    3.分析AppDelegate

    1.AppDelegate.h 引入 #import <Flutter/Flutter.h> 并继承 FlutterAppDelegate
    2.AppDelegate.m 引入 #include "GeneratedPluginRegistrant.h" 文件并在didFinishLaunchingWithOptions方法中调用了
    [GeneratedPluginRegistrant registerWithRegistry:self];
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
    3.GeneratedPluginRegistrant文件, 这个文件是用来注册用到的Flutter插件的,因为这里是新建项目并没有引入任何插件,所以registerWithRegistry方法为空。如果Flutter项目引入其他插件会在flutter_app目录下生成一个.flutter-plugins的隐藏文件里面会包括插件名称和对应路径,GeneratedPluginRegistrant.m文件也会有所变化。如下图

    flutter-plugins GeneratedPluginRegistrant.m

    4.rootViewController

    我们打开Main.storyboard文件发现是有一个叫做FlutterViewController的viewController。通过查阅文档,可以通过以下代码跳转

    FlutterViewController *flutterViewController = [[FlutterViewController alloc] init];
    //设置路由页面
    //[flutterViewController setInitialRoute:@"route1"];
    [self presentViewController:flutterViewController animated:false completion:nil];
    

    三、总结步骤

    通过步骤二,我们需要flutter_assets、App.framework、Flutter.framework还要将插件引入并继承FlutterAppDelegate然后使用FlutterViewController跳转


    四、编写shell编译并获取iOS运行所需文件

    1、在flutter_app目录下执行"flutter build ios debug"、"flutter build ios release"可以编译并得到debug/release相对应的App.framework、Flutter.framework,然后我们利用.flutter-plugins引入所有插件,导入flutter_assets文件,最后制作一个Flutter.podspec文件以便引入pod中

    2、实现代码

    1.将Flutter.podspec、flutter-ios.sh放入flutter_app目录下,运行flutter-ios.sh脚本便会flutter_app/build/flutter-ios/下生成debug和release对应的文件,使用pod。
    2.将flutter-ios目录拷贝到项目目录下使用Podfile引入

    flutter_app/flutter-ios
    xcode/flutter-ios

    3.1AppDelegate继承FlutterAppDelegate
    3.2导入GeneratedPluginRegistrant并注册插件
    3.3使用FlutterViewController显示Flutter

    flutter

    Flutter.podspec

    #将代码保存到flutter_app目录下命名为Flutter.podspec
    #
    # NOTE: This podspec is NOT to be published. It is only used as a local source!
    #
    
    Pod::Spec.new do |s|
      s.name             = 'Flutter'
      s.version          = '1.0.0'
      s.summary          = 'High-performance, high-fidelity mobile apps.'
      s.description      = <<-DESC
    Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
                           DESC
      s.homepage         = 'https://flutter.io'
      s.license          = { :type => 'MIT' }
      s.author           = { 'Flutter Dev Team' => 'meng1711@sina.com' }
      s.source           = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
      s.ios.deployment_target = '7.0'
      s.vendored_frameworks = 'Flutter.framework', 'App.framework'
      s.resources = 'flutter_assets'
      s.source_files = '*.{h,m}'
      s.public_header_files = '*.h'
    end
    
    

    flutter-ios.sh

    #!/bin/sh
    #将代码保存到flutter_app目录下命名为flutter-ios.sh
    
    function echoError() {
        echo '\033[31mError:'$1'\033[0m'
    }
    
    function echoGreen() {
    echo '\033[32m'$1'\033[0m'
    }
    
    #debug/release
    function buildFlutter() {
    
        mode='release'
        if [ $# = 1 ] ; then
            mode=$1
        fi
    
        buildRoot='build/flutter-ios/'
        buildPath=$buildRoot$mode'-iphoneos/'
        buildRootPlugins=$buildRoot'plugins/'
    
        rm -rf $buildPath
        mkdir -p $buildPath
    
        #编译flutter
        echoGreen 'flutter build ios --'$mode
        flutter build ios --$mode
    
        #加载Flutter.framework
        flutterFramework='ios/Flutter/Flutter.framework'
        if [ ! -d $flutterFramework ]; then
            echoError 'Flutter.framework不存在'
            exit 0
        else
            echoGreen '加载Flutter.framework'
            cp -r $flutterFramework $buildPath
        fi
    
        #加载App.framework
        appFramework='ios/Flutter/App.framework'
        if [ ! -d $appFramework ]; then
            echoError 'App.framework不存在'
            exit 0
        else
            echoGreen '加载App.framework'
            cp -r $appFramework $buildPath
        fi
    
    ########################################
    
        #加载plugins
        if [ ! -d $buildRootPlugins ]; then
            mkdir -p $buildRootPlugins
            flutterPlugins='.flutter-plugins'
            if [ -f $flutterPlugins ]; then
                while read line 
                do
                    array=(${line//=/ }) 
                    pluginPath=$buildRootPlugins${array[0]} 
                    mkdir -p $pluginPath
                    cp -r ${array[1]}'/ios/.' $pluginPath
                done < $flutterPlugins
            fi
        fi
        echoGreen '加载plugins'
        ln -fs '../plugins' $buildPath'plugins'
        #注册文件
        if [ ! -f $buildRoot'GeneratedPluginRegistrant.h' ]; then
            flutterPluginsRegistrant='ios/Runner/GeneratedPluginRegistrant'
            if [ -f $flutterPluginsRegistrant'.h' ]; then
                cp -r $flutterPluginsRegistrant'.h' $buildRoot
                cp -r $flutterPluginsRegistrant'.m' $buildRoot
            fi
        fi
        ln -fs '../GeneratedPluginRegistrant.h' $buildPath'GeneratedPluginRegistrant.h'
        ln -fs '../GeneratedPluginRegistrant.m' $buildPath'GeneratedPluginRegistrant.m'
    
        #加载flutter_assets
        if [ ! -d $buildRoot'flutter_assets' ]; then
            flutterAssets='ios/Flutter/flutter_assets'
            if [ -d $flutterAssets ]; then
                cp -r $flutterAssets $buildRoot
            fi
        fi
        echoGreen '加载flutter_assets'
        ln -fs '../flutter_assets' $buildPath'flutter_assets'
        
    
        #复制Flutter.podspec
        if [ ! -f $buildRoot'Flutter.podspec' ]; then
            flutterPodspec='Flutter.podspec'
            if [ -f $flutterPodspec ]; then
                cp -r $flutterPodspec $buildRoot
            fi
        fi
        echoGreen '加载Flutter.podspec'
        ln -fs '../Flutter.podspec' $buildPath'Flutter.podspec'
    }
    
    start=$(date +%s)
    
    #编译
    rm -rf 'build/flutter-ios/'
    mkdir -p 'build/flutter-ios/'
    buildFlutter debug
    buildFlutter release
    
    end=$(date +%s)
    echo '^v^制作完成,耗时:'$(( $end - $start ))'s'
    

    Podfile

    # Uncomment the next line to define a global platform for your project
    # platform :ios, ‘9.0’
    
    # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
    
    #Flutter model: debug/release
    def podFlutter(mode)
        
        flutterPath = 'flutter-ios/' + mode + '-iphoneos/'
        pod 'Flutter', :path => flutterPath
        
        pluginsPath = 'flutter-ios/' + mode + '-iphoneos/plugins/'
        if File.directory?(pluginsPath)
            Dir.foreach(pluginsPath) do |fileName|
                if fileName != '.' and fileName != '..' and fileName != '.DS_Store'
                    pod fileName, :path => pluginsPath + fileName
                end
            end
        end
    end
    
    target 'demo' do
        podFlutter('debug')
    end
    
    post_install do |installer|
        installer.pods_project.targets.each do |target|
            target.build_configurations.each do |config|
                config.build_settings['ENABLE_BITCODE'] = 'NO'
            end
        end
    end
    
    

    本文只是探索了一种使用pod库来导入Flutter项目代码的方法,如果大家有更换好方法或建议欢迎留言
    项目有些大就不传了,有不明白的可以留言或私信
    晚安~

    相关文章

      网友评论

        本文标题:想尝试Flutter? 重新开发成本高? 教你Flutte

        本文链接:https://www.haomeiwen.com/subject/yorolqtx.html