首先声明一点,flutter的插件已经有不少了,官方的插件,去这里找https://github.com/flutter/plugins
第三方的插件,去这里找https://pub.dev/, (这个网站有时候打不开,感觉应该是服务器的问题,请耐心多刷新几次喽),
但是难免有时候还是要自己去写插件,俗称自定义插件,才能满足自己项目的需要.
比方说,在原生工程里面是用 合作公司的SDK开发了一个视频模块 (SDK是封装好的头文件和一些.a静态库), 假如现在flutter工程里面也想要这个视频模块,那怎么办,这个时候就需要写插件了,写视频的插件了. 当然各位有更好的办法解决此需求,麻烦请告知我喽~~
言归正传,我们还是回到怎么写自定义插件.我决定从简单到复杂来一一介绍
简单的--->插件里面只调用到原生自带的api,
当我们新建一个插件工程的时候,官方就给我们提供了一个示例, 获取手机的版本号.这个示例就是属于此类. 只用原生自带的一些api,就可以完成.
点击Android Studio 新建一个插件工程,
image.png
然后就是下一步,下一步的事情了,建完以后发现有问题,打不开原生工程 翻车了~~
image.png
注意观察哦,没有android,也没有iOS相关的东西;还有一点就是 右键没法用xcode打开了;
image.png
来来来,现在我们来看一下flutter 1.20 版本之前的版本建完以后是这样的
image.png
右键是可以用xocode打开原生工程的
image.png
现在我们来填坑
我们还是按官方文档来解决此坑吧,
官方地址:https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms
其中这个地方有提到怎么创建插件工程
image.png
其中插件工程名为hello. 现在我们要创建一个工程PlugTest1,所以用下面的命令
1.打开终端,cd 到你要的位置,比喻我就放到桌面
cd Desktop/
2.把上面的语句改一下
flutter create --org com.example --template=plugin --platforms=android,ios -i objc plugTest1
其中 参数 objc 表示iOS工程将会是用Objective-C语言来编写代码,对应安卓的是java;
同理如果把objc 换成swift,表示iOS工程将会是用swift语言来编写代码,对应安卓的是kotlin;
3.接着运行
flutter run
就会正常的跑起来.至此新建一个插件工程的坑填完(此坑是flutter 升级为1.20后才会出现的).
如下图的路径,就能找到插件实现的核心代码(iOS Android)
image.png
回到正题
此简单插件实现,只调用到原生自带的api
iOS
image.png
Android
image.png中等---->还会用到一些第三方的文件或者说是用到了第三方库
例如我之前写的一篇文章,关于实现udp扫描的插件,https://www.jianshu.com/p/803660ad39de
就是属于此类,有兴趣的可以看看上面链接的那篇文章.
不过在此 我还是从零开始带着大家看看,首先用上面的方法新建一个叫 plugUdp的插件
cd Desktop/
flutter create --org com.example --template=plugin --platforms=android,ios -i objc plugUdp
flutter run
建完之后是这样的,可以正常运行起来
image.png
这里我以iOS为例,同样的右键,用xcode打开原工程
image.png
想在xcode里面找到PlugUdpPlugin.h,PlugUdpPlugin.m还是不容易的,路径比较深的,这里我为了方便大家,把路径的图留下来了
image.png
回到正题
写udp插件,我是用到了GCDAsyncSocket这个库在iOS里面处理socket相关的比较容易,他有几个文件,我们现在要把它放在哪里呢,
image.png
经过多番测试是放在Classes里面是可以的.可以正常用起来
image.png但是flutter 升级为1.20后,又不行了
我们来填坑 (重点就在这里,后面复杂一点的配置也是以此为基础的)
1.回到android studio下plugUdp插件工程, 在iOS文件夹下面新建一个文件夹,比喻Frameworks,把需要的文件放在Frameworks文件夹里面
image.png
2.配置podspec文件,把.h .m文件路径配置进去
sg
3.打开终端,cd到工程目录下的plugUdp/example/ios下,里面有podfile文件
cd /Users/XXXXXX/Desktop/plugUdp/example/ios
4.在终端 安装一下
pod install
5.再右键用xcode打开原生工程
image.png
你会发现多了一个叫Frameworks的文件夹,并且里面有相应的文件.
在PlugUdpPlugin.h 试着引入头文件,是正常,并且使用它,
在PlugUdpPlugin.m调用它里面的方法,也是正常的.
image.png
此到大功告成, 坑已填完.
有难度--->插件里面用到 第三方封装好的sdk,(有framework,有.h头文件,有.a静态库等)
怎么在插件里面导入第三方封装好的Framework,并且能正常使用它,还有些难度的.说得更清楚一些就是怎么配置podspec文件.
关于怎么配置podspec文件 我们再来一个实例
1.新建一个plugvideo的插件(前面已经多次用到了,不再赘述),用android studio打开插件工程;
2.在ios文件夹下,新建一个frameworks文件夹,再把.a /.framework文件放进去,把.h /.m文件放到Classes文件夹(如下图第一图)
3.配置podspec(如下图第一图)
4.找到plugvideo插件工程目录下的podfile文件,进行pod install(前面有提到,可以回头看上面)
5.右键用xcode打开原生工程,
6.验证一下是否正常(如下图第二图)
image.png img01.png
最后附上podspec配置遵循的规则
Pod::Spec.new do |s|
s.name = "XXXSDK"
s.version = "1.0.0"
s.summary = "这是一个SDK"
s.description = "这是一个SDK 一定要比summary长."
s.homepage = "https://github.com/xxxx/XXXSDK"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "作者" => "123456@qq.com" }
s.platform = :ios, "8.0"
# When using multiple platforms ios部署版本
# s.ios.deployment_target = "5.0"
# s.osx.deployment_target = "10.7"
#1 git commit -m =>"13287dd",讲pod版本与git仓库中的某一次提交绑定
#s.source = { :git => "https://github.com/xxxx/XXXSDK", :commit => "13287dd" }
#2 将这个Pod版本与Git仓库中某个版本的comit绑定
#s.source = { :git => "https://github.com/xxxx/XXXSDK", :tag => 1.0.0 }
#3 将这个Pod版本与Git仓库中相同版本的comit绑定
#s.source = { :git => "https://github.com/xxxx/XXXSDK", :tag => s.version }
s.source = { :git => "https://github.com/xxxx/XXXSDK.git", :tag => "v#{s.version}" }
s.source_files = "XXXSDK", "XXXSDK/openSource/*.{h,m}"
s.vendored_frameworks = 'XXXSDK/lib/XXXSDK.framework'
s.resources = "XXXSDK/resource/resource.bundle"
s.framework = "UIKit"
#s.resource = "XXXSDK/resource/resource.jpg"
#s.frameworks = "SomeFramework", "AnotherFramework"
#引用libxml2.lib和libz.lib、tbd ,去掉头尾的lib
# s.library = "z"
# s.libraries = "z", "xml2"
#s.vendored_libraries = 'XXXSDK/lib/XXXSDK.a'
s.requires_arc = true
# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
# s.dependency "JSONKit", "~> 1.4" s.dependency = 'AFNetworking', '~> 2.3' s.dependency = 'SDWebImage'
# 创建子库
#s.subspec 'Components' do |ss|
#ss.source_files = 'YDKit/Components/*/.{h,m}'
#end
end
###以下是上面代码的功能注解
s.name:
名称
pod search 搜索的关键词,一定要和.podspec的名称一样,否则报错
s.version:
版本号
s.ios.deployment_target:
支持的pod最低版本
s.summary:
简介
s.homepage:
项目主页地址
s.license:
开源协议(创建github库的时候选择的)
s.author:
作者信息(这里随便谢谢也可以通过)
s.social_media_url:
社交网址
s.source:
项目的地址
s.source_files:
需要包含的源文件
s.resource:
资源文件,单个
s.resources:
资源文件(含bundle)
s.vendored_frameworks:
包含的framework,也就是我们自己制作的pod
s.requires_arc:
是否支持ARC
s.dependency:
依赖库,不能依赖未发布的库.如AFNetWorking
s.description:
描述,字数要比s.summary长
s.screenshots:
截图
s.exclude_files:
隐藏的文件
s.public_header_files:
公开的头文件
s.framework:
所需的framework,单个
s.frameworks:
所需的framework,多个用逗号隔开
s.library
引用的静态库
s.libraries
引用的静态库,多个用逗号隔开
s.vendored_libraries:
引用自己生成的.a
s.vendored_frameworks:
引用自己生成的.framework,多个用逗号隔开
s.dependency:
依赖的库
s.ios.deployment_target
iOS部署版本
结尾
关于插件这块,因为涉及的东西比较多,所以本来就是有点复杂.遇到坑后,就感觉更难了,这个时候,就需要耐心啦.就像看这篇文章一样,要有耐心把它看完,一边看,一边动手做,多练几次,相信会有收获的~ 祝君好运~~~
如果觉得有点帮助,请点赞加关注哦~
网友评论