想尝试Flutter? 重新开发成本高? 教你Flutter和iOS原生混合开发,Flutter制作成pod导入(一)探索篇

一、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项目代码的方法,如果大家有更换好方法或建议欢迎留言
项目有些大就不传了,有不明白的可以留言或私信
晚安~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容