face++静态库转为动态库
前言
苹果商店上架应用,有规定支持iOS8.0以上的iPA可执行文件的大小不能超过60M。 face++提供过来的是静态库,会导致苹果上架的ipa的包增加1.5M左右。而刚好我们的APP包Mach-O文件大小接近60M,因而,最好的方式是通过动态库的方式来接入。
Face++文件: https://faceid.com/pages/documents/37661898
SDK需要问Face++的人拿,Demo跑起来是需要key和secret的
静态库转动态库
静态库转动态库,有两种转换方式,一是直接建一个动态库工程,将相关的framework拉进入构建打包,二是通过carthage来打包构建。这两种方式都需要处理一下图片资源的读取方式。
carthage构建动态库
1、工程Demo
face++的SDK里有Demo,我们拿到demo,填入kApiKey 和 kApiSecret 是可以直接跑起来的。实际上,SDK只有下面三个文件
- MGFaceIDBaseKit.framework
- MGFaceIDLiveDetect.framework
- MGFaceIDLiveCustomDetect.bundle
2、创建framework
直接在face++的Demo的工程上,新建一个Target。项目-> File -> New -> Target , 选择Framework ,命名为 MGLiveDetectFramework。
创建成功后如下图,并删除多出来的MGLiveDetectFramework.h
3、将SDK的头文件公布出来
将MGFaceIDLiveDetect.framework的头文件拉出来,放在sdk文件夹里面,注意,虽然是拉了出来,但文件的路径是和原来一样的。
新的项目结构如下:
4、配置你的framework
- 工程 -> 选择framework所在的Target -> 选择Build Phases
- 点击Header左下角的+号把你要暴露的头文件添加到Public里面(默认添加到Project里面,用鼠标把它拽过去)
- 在Compile source里面添加实现的.m文件。由于没有.m文件,可以直接忽略掉
- 在Link Binary With Libraries 中,将libs的文件全部增加进去,同时,还需要将demo里所有依赖的系统framework也增加进去。
5、修改framework的Deployment Target
改为和项目工程一样的支持版本,我这边是8.0。 一定要注意这里,要不然,编译会报错或者编译不报错时,低版本的系统会安装不了。报错类似:
ERROR: Install failed. Got error "ApplicationVerificationFailed" with code 0xe8008019: Failed to verify code signature of /private/var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.xY9xAg/extracted/Payload/Spec.app/Frameworks/MGLiveDetect.framework : 0xe8008019 (The application does not have a valid signature.)Build step 'Execute shell' marked build as failureFinished: FAILURE |
6、更改framework的名字
不需要更改可以直接忽略。项目Target -> Build Setting -> Product Module Name/Produce Name ,改成 MGLiveDetect
7、配置类别和支持Bitcode
- 在Build Settings的Linking的Other Linker Flags里加上
-all_load
- 工程需要支持bitcode,需要在Other C Flags 里加上
-fembed-bitcode
说明:如果你使用了类别,那么你需要在Build Settings的Linking的Other Linker Flags里加上。为了避免麻烦,直接改为 -all_load
8、分享你的工程
选择 Manager Schemes,给 MGLiveDetectFramework 勾上shared
9、指定编译方式
实际上,对普通的静态库,我们操作完前面的步骤,已经可以编译成动态库了。但是对于face++来说,在编译的时候,会报如下的错:
通过查看face++的demo集成work文档,写着静态库是采用Objective-C++的方式来实现
因此,我们需要改一下如下配置,编译成功。
本地验证
1、生成动态库
cd到项目文件夹,运行
$ carthage build --no-skip-current
命令运行完成后,你会发现你的项目文件夹里面多了一个Carthage文件夹,其中【MGLiveDetect.framework】就是我们需要的动态库。
2、集成到工程上验证
第一步:我们新拷一份face++给过来的demo,将Carthage全部拷到Demo根目录下
第二步:打开工程,将工程下面的framework和bundle文件都删除掉
第三步:添加动态库
要注意顺序,先1,再2,这样,添加的framework才会在工程的Frameworks文件目录下。
- target->Build Phases ->Link Binary With Libraries 添加你自己的动态库
- target->Build Phases ->左上角+号 ->New Copy Files Phase 然后在Copy Files下 Destination选择Frameworks ->添加你自己的动态库
新的目录结构如下,很清析
3、更改头的引用
OK,可以正常跑起来了。
上传到GitHub管理
1、上传github
将配置了carthage的工程Demo代码,上传到git上面,并打上标签。Carthage -> Build 目录是不需要上传的
git tag 0.1.
git push --tags
2、创建Carthage
在要接入的项目根目下,创建一个Carthage,并将github的链接指向。类似pod的操作
$ touch Cartfile git "http://www.github.com/xxxxMegLiveStill.git"~> 1.0.
3、保存并关闭cartfile文件,进行安装
carthage update --no-use-binaries --platform ios
安装完之后根目录会出现一个叫Carthage的文件夹,里面包含Build和Checkouts两个文件夹。
Build:iOS路径下的就是framework包,需要自行引用进来。
Checkouts:是从Github上获取来的源码,所以理论上来说你在这个文件夹里对源码进行任何的修改,再次执行 carthage build 就会根据这里的源码打包出相应的framework出来。但需要注意的是当每次执行carthage update后这里的源码又被覆盖了。所以你有特别需要修改的地方可以加例外防止覆盖!!!! 重要
4、项目引入framework
这个和上面的【本地验证】是一样的。
- target->Build Phases ->Link Binary With Libraries 添加你自己的动态库
- target->Build Phases ->左上角+号 ->New Copy Files Phase 然后在Copy Files下 Destination选择Frameworks ->添加你自己的动态库
存在的问题
1、Bundle图片资源加载不出来
使用动态库跑起来之后,我们发现,界面的图片资源不见了,我们在打动态库的时候,明明已经加了将Bundle文件打包进来了呀。通过分析,大多数的SDK加载图片,都写死了是从根目录读取,写法如:
但我们打包成动态库之后,Bundle文件已经不在根目录了,根本就找不到。
有两种处理方式
第一种(不推荐)
将bundle再引进工程里,可以解决大部分APP的资源加载。
缺点:
bundle没有任何地方引用,容易被误伤
项目是模块化结构,每个业务线是一个独立的framework的时候,还是加载不出来。
第二种(推荐)
通过查资料,参照一下github上的开源库MJRefresh(https://github.com/CoderMJLee/MJRefresh)的写法,先读取存在类的Bundle路径,再找到图片的路径。这样,不管封装多少层,bundle图片资源都不会丢失。
我们可以写在一个NSBundle的分类里,写法如下:
具体思路,别人修改的实现方式
1. main bundle 下判断是否存在bundle,存在就直接使用
2. 如果1找不到,就会到SDK可执行文件对应的目录下面去找WBOCRService.bundle
基本上都是创建一个UIImage的分类来统一处理。
直接工程创建动态库
通过直接建一个动态库工程,将相关的静态库framework拉进入构建打包成动态库,点击链接到下一篇的分享:
face++静态库转为动态库的更多相关文章
- face++静态库转为动态库之二
上一篇的时候,已经介绍了如何将carthage转为动态库.这一篇,我们是单纯的建一个动态库.还是以face++为例 查看上一篇: face++静态库转为动态库 制作动态库 1.创建一个工程MGLive ...
- Carthage 让项目支持及使用,第三方静态库转为动态库
Carthage介绍 具体使用,可以查看官网的,文档地址 https://github.com/Carthage/Carthage.如果看不懂英文,可以看一下官文的翻译:https://www.jia ...
- C++ 系列:静态库与动态库
转载自http://www.cnblogs.com/skynet/p/3372855.html 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择 ...
- C++静态库与动态库
C++静态库与动态库 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...
- Linux下Gcc生成和使用静态库和动态库详解(转)
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- Makefile中静态库,动态库的创建和使用以及解压缩命令
应用层通过操作文件操控硬件 使用制作好的工具链: 刚开始学习时,用一些已经制作好的工具链,使用以下命令解压到gcc-3.4.5-glibc-2.3.6目录 cd /work/tools tar xjf ...
- VS中Debug和Realease、及静态库和动态库的区别整理(转)
原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...
- Linux下C++静态库、动态库的制作与使用
参考博文:C++静态库与动态库 >> 静态库 1. 静态库的制作 a) 编辑 name.cpp 和name.h文件 b) $g++ -c name.cpp //注意带参数-c,否则直接编译 ...
- 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库
最近在编写的一个Apache kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a 静态库编译的,,,而我们这 ...
随机推荐
- ThreadLocal, HandlerThread, IntentService
1. ThreadLocal用法详解和原理https://www.cnblogs.com/coshaho/p/5127135.html // ThreadLocal methods: public T ...
- vuejs使用jsx语法
想要vuejs项目支持jsx语法,需要一些插件 babel-plugin-transform-vue-jsx Babel plugin for Vue 2.0 JSX 使用方法: 安装 npm ins ...
- PSO:利用PSO实现对一元函数y = sin(10*pi*x) ./ x进行求解优化,找到最优个体适应度—Jason niu
x = 1:0.01:2; y = sin(10*pi*x) ./ x; figure plot(x, y) title('绘制目标函数曲线图—Jason niu'); hold on c1 = 1. ...
- 网络编程-Python高级语法-GIL全局解释器锁
知识点:GIL全局解释器锁其实和Python没有任何关系,是由于当初编写Python解释器时留下的,它只对多线程有影响,GIL保证同一时刻只有一个线程在运行,即使是多核配置电脑,同一时刻也只会让一个线 ...
- 【redis】-- springboot集成redis及使用
springboot自动配置的redis并不是特别好用,所以需要我们使用原生的jedis, 1.添加依赖 2.在application文件中配置 # Redis服务器地址 redis.host= # ...
- gets()的替代问题
gets()的替代方法 1.<iostream>中getline (char* s, streamsize n) 2.scanf("%[^\n]",s);
- port bridge enable命令导致的环路
1.故障描述 前几天机房一台连接数据中心与核心交换的交换机宕机(硬件故障),机房有备用的设备,随即更换(配置也是早就配置好了的),但是下午就出现数据中心网络丢包问题,表现为存在mac漂移 2.拓扑 核 ...
- 06-JDBC
JDBC > JAVA Database Connectivity java 数据库连接 * 为什么会出现JDBC > SUN公司提供的一种数据库访问规则.规范, 由于数据库种类较多,并且 ...
- js中return false; jquery中需要这样写:return false(); Jquery 中循环 each的用法 for循环
js中return false; jquery中需要这样写:return false(); Jquery 中循环 each的用法 $(".progressName").each(f ...
- js的一些
// 1 定时器参数问题 无限个参数 /*setTimeout(function(num1,num2,num3,num4){ alert(num1+num2+num3+num4) },1000,1,2 ...