Swift + framework 的制作(基于project)

1.framework开始前的 理论

1).初衷

开始的理由千千万,但殊途同归.
(1) 提供给公司外部的人员使用, 不希望暴露内部"高大上"的实现
(2) 公司内部多个项目公用资源, 使用方便
(3) 模块化、分工合作, 架构组完成基础的实现, 功能开发工程师只需要关注功能实现, 不需要关注底层实现
(4) 提高编译速度,减少少量的改动引起的大量重复的编译
......

2).动态库,静态库

动态库存在形式: .framework, .dylib, .tbd

动态库是引用关系,编译时不会被拷贝到程序中,程序运行时 由系统动态加载

静态库存在形式: .a 和 .framework

静态库编译时会被完整拷贝一份到目标程序中

动态库与静态库详细的区别 参考:
https://my.oschina.net/shoutan/blog/786636

2.创建framework

1).创建工程

模板选择Cocoa Touch Framework

1创建framework.png
2).编写自定义代码

对需要共享的内容分模块添加

2编辑自定义代码.png
!建库时不得不注意的就是 swift的访问级别

Swift 提供了三种访问级别。这些访问级别相对于源文件中定义的实体,同时也相对于这些源文件所属的模块。
其中,函数的访问级别需要根据该函数的参数类型访问级别、返回类型访问级别得出。如果根据参数类型和返回类型得出的函数访问级别不符合上下文,那么就需要明确的申明该函数的访问级别。

代码中的所有实体,如果你不明确的定义其访问级别,那么它们默认为internal级别, 所以, 只是在一个工程中使用, 可以不用声明访问类型, 该工程 均可访问。

swift 三个等级的访问控制权限,可以简单的通过下面的规则来进行选择:

  • Public: 对 App 或其他 framework 可见。
  • Internal: 对该 framework 可见
  • Fileprivate: 对该编译文件可以见
  • Private: 对该类可见

具体参考文档: http://wiki.jikexueyuan.com/project/swift/

3.编译 真机 / 模拟器 的 包

1).编译

对工程进行编译(command + B), 找到project->products->选中EKWBaseUIKit.framework->Show In Finder, 如下图:

3编译得到framework.png
2).查看库文件

可以看到生成的 真机和模拟器下的两个包文件(当前设置的模式为release模式, 所以为release模式下的两个包文件), 如下图:

编译得到的库文件.png
3). 查看库文件支持框架

在终端通过lipo -info 静态库名字可以查看动态库支持的架构, 如下:

4lipinfo.gif

可以看到当前支持的框架包含: 有armv7arm64

目前iOS设备包含的架构:
模拟器:iPhone4s-iPnone5:i386; iPhone5s-iPhone7 Plus:x86_64
真机: iPhone3gs-iPhone4s:armv7; iPhone5-iPhone5c:armv7s; iPhone5s-iPhone7Plus:arm64

我们需要把对应的framework引入工程中即可使用, 但是我们平时可能用到真机调试,也可能使用模拟器调试,来回切换framework会很繁琐,所以一般使用终端把支持真机和模拟器的framework合并成一个framework(fat版)

命令格式:lipo -create 第一个.framewor下的esec文件的绝对路径 第二个.framework下的esec文件的绝对路径 -output 最终的.framework文件路径
操作如下:

lipocreate.gif

4.使用脚本编译

如上的单调频繁的操作可能会让你感觉累觉不爱,xcode目前支持的脚本编译,包治百病

1).创建Aggregate

targets点击左下角 “+”, 添加Aggregate

创建Aggregate.png
2). 添加脚本文件
添加脚本.png

Run Script 中可以放入待执行的脚本文件, 也可以放入待执行的脚本, 但是放入待执行脚本时, 遇到过文件权限的问题(涉及pod管理的framework), 所以此处推荐使用脚本文件的路径代替脚本

3).使用到的脚本如下:
#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products/"

#创建输出目录,并删除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"

#分别编译模拟器和真机的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

#拷贝framework到univer目录
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"

#合并framework,输出最终的framework到build目录
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"

#删除编译之后生成的无关的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done
#判断build文件夹是否存在,存在则删除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi
rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
#打开合并后的文件夹
open "${UNIVERSAL_OUTPUT_FOLDER}"

4). 脚本以及生成的framework位置
脚本位置:framework位置.png
5).检测 framework支持的类型

使用lipo -info ...查看合成的framework支持的类型 包含:i386, Plus:x86_64, armv7, arm64

framework 支持框架.gif

6.framework制作过程中的坑

1. Module

在工程中, 我们可以通过桥接文件引入需要使用的OC或者C相关的, 但是swift动态库中, 是不能使用桥接文件的,比如: 需要使用CommonCrypto里面的内容, 在工程中可以直接导入CommonCrypto使用, 在库中则不能使用

8056F28B-E7F2-46C2-A2DF-D9429B6F25B1.png

这个问题可以使用模块化解决:
1).创建一个模块化文件, 并加入对应模块

26C785ABDF49722CC331A28B994DD3E9.png
module CCommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}

2). 模块化的使用
在需要使用的文件中 输入 import CCommonCrypto即可使用相关内容

3)参考文档
https://spin.atomicobject.com/2015/02/23/c-libraries-swift/ 英文原文
http://blog.csdn.net/quentingui/article/details/44115285 翻译
http://www.ethanwhy.com/2016/12/17/swift-framework-call-objective-c-c-language/
https://stackoverflow.com/questions/25248598/importing-commoncrypto-in-a-swift-framework/37125785#37125785
https://github.com/onmyway133/arcane

更新(2018-10-12):
xcode10中, swift增加了对 CommonCrypto的支持,在需要使用的 CommonCrypto的swift库中,不需要Module的方式,直接添加使用即可,如下:

import CommonCrypto

自己封装的库也可能使用了pod管理,基于workspace的库的制作将在接下来的文章中谈到...

以上仅是个人使用总结,欢迎批评指正补充~~~~~~~

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

推荐阅读更多精彩内容

  • 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别...
    吃瓜群众呀阅读 11,882评论 3 42
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,029评论 4 62
  • 2017.7.4 星期二 晴转小雨 亲子日记(72) 今天把儿子送托付去了,中午去给他送凉席,看到他在托付很开心...
    于泽妈妈阅读 209评论 0 0
  • 想了半天,还是用这么俗的一个标题,我也是一个俗人,从小就不安分,骨子深处藏着叛逆和不服,小的时候表现的还算乖巧,只...
    unsaid阅读 174评论 0 1
  • 第一次在黑板报上画蝴蝶。
    northern姑娘阅读 198评论 0 2