http://years.im/Home/Article/detail/id/52.html

http://www.cocoachina.com/industry/20131204/7468.html

xCode6制作动态及静态Framework

Posted on 2014-09-21 22:29:00

有没有写SDK或者要将一些常用的工具类做成Framework的经历? 你或许自己写脚本完成了这项工作,相信也有很多的人使用 iOS-Universal-Framework ,随着xCode6的发布,相信小伙伴们已经都知道了,xCode6支持做Framework了. 同时iOS-Universal-Framework开发者也宣布不在继续维持此项目的开发,建议开发者使用xCode6制作,目前网上也有很多制作iOS Framework的资料,但大多都不够详细,接下来本文会详情介绍一下在xcode6下制作iOS Framework.


关于静态库和动态库的概念,网上资料很多,这里不做叙述,只讲解制作过程。

创建iOS动态库

新建工程并选择默认Target为Cocoa Touch Framework, 如图:

做编码工作,在这里我简单的写了一个Utils的类,并写了一个log方法

设置开放的头文件:Framework中有些类可能是一些私有的辅助工具,不需要使用者看到,在这里只需要把开放出去的类放到Public下, 如图

这样生成的Framework的Headers目录下也只能看到Public的头文件

编码完成之后,直接Run就能成功生成Framework文件了,选择 xCode->Window->Organizer->Projects->Your Project, 打开工程的Derived Data目录,这样就能找到生成的Framework文件了,如图

新建测试工程,使用生成的Framework

将Framework文件导入到测试工程,调用Framework中的代码

MyUtils *utils = [MyUtils new];
[utils log:@"didFinishLaunchingWithOptions"];

运行报错(Reason: Image Not Found)

为什么会这样的?因为我们做的是动态库,在使用的时候需要额外加一个步骤,要把Framework同时添加到‘Embedded Binaries’中

注意: 在xCode6之前是没有这个选项的(我没发现),所以理论上xCode5及之前的版本无法使用xCode6下生成的Framework动态库

到这里,假定你整个过程都是使用的模拟器做的,那看上去会很顺利。这时候尝试将测试工程部署到真机上,问题来了

ld: warning: ignoring file /work/ios/MyFrameworkTest/MyFrameworkTest/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (armv7): /work/ios/MyFrameworkTest/MyFrameworkTest/MyFramework.framework/MyFramework
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_MyUtils", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

为什么会这样?错误提示已经很明显了,因为我们制作动态库的时候,选的设备是模拟器,如果选真机的话,那生成的库也只能在真机上使用,那我们该怎样制作一个通用的动态库呢? 简单的方法是分别生成模拟器和真机上运行的库,然后在合并,这个方法,在每次生成动态库的时候,过程都会很繁琐,下面我们用一个脚本来自动完成它。

制作通用动态库

新建Aggregate Target

添加script到新建的Target

# Sets the target folders and the final framework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
# 例如: FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME} # Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework # Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework # -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build # Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi mkdir -p "${INSTALL_DIR}" cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/" # Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}" rm -r "${WRK_DIR}" open "${INSTALL_DIR}"

选中新建的Target,Run, 如果没有异常的话,会自动弹出生成的Framework文件

这样生成的动态库就能同时支持模拟器和真机了

xCode6下制作通用静态库

上面我们也提到了,这样生成的动态库恐怕很难在xCode5上使用,那我们为什么非要用动态库呢,一般情况下不是用静态库就好了吗? So Easy!只需要修改一个参数即可生成静态库了

使用静态库的话,就可以把Framework从‘Embedded Binaries’中删除了. 亲测在xCode5下可用。把新生成的库导入到测试工程,试试在模拟器和真机上运行,一切OK.

不巧,如果你用的真机是iPhone5 C, 那悲剧又要发成了,生成的Framework竟然不支持armv7s,不知是xCode6的bug,还是因为苹果认为使用armv7s的设备太少,可以不支持了.xCode6新建工程,默认的Architectures竟然不包含armv7s

想要生成的库支持armv7s,把armv7s添加到Architectures中,重新生成Framework即可

判断一个Framework支持哪些架构

我们该怎么验证生成的Framework支持哪些平台呢,总不能一个个测试吧?当然不用.下面的命令是加上armv7s前后生成的framework的对比

Yearsdembp:Products Years$ lipo -info ./MyFramework.framework/MyFramework
Architectures in the fat file: ./MyFramework.framework/MyFramework are: i386 x86_64 armv7 arm64
Yearsdembp:Products Years$ lipo -info ./MyFramework.framework/MyFramework
Architectures in the fat file: ./MyFramework.framework/MyFramework are: armv7 armv7s i386 x86_64 arm64
 

创建通用型framework的更多相关文章

  1. Amazon RDS的通用型存储(SSD)

    在今年的6月份,我们曾介绍过为Amazon EC2实例提供的基于SSD的弹性块级存储. 在公布几个月过后,这样的被称为通用型存储(SSD)的新型选择方式在创建新的EBS卷中已经占到了90%,我们从客户 ...

  2. 通用型CRM还是行业型CRM?-定制为王

    大数据时代,怎样利用工具摆脱繁杂的数据管理之苦,洞察有价值的销售信息,是每一个管理者的迫切须要.Zoho  CRM问世10年来,见证了一个个行业客户怎样在CRM帮助下实现了效率和业绩提升.相同,广泛的 ...

  3. 城市经纬度 json 理解SignalR Main(string[] args)之args传递的几种方式 串口编程之端口 多线程详细介绍 递归一个List<T>,可自己根据需要改造为通用型。 Sql 优化解决方案

    城市经纬度 json https://www.cnblogs.com/innershare/p/10723968.html 理解SignalR ASP .NET SignalR 是一个ASP .NET ...

  4. Android应用安全之Android APP通用型拒绝服务漏洞

    0xr0ot和Xbalien交流所有可能导致应用拒绝服务的异常类型时,发现了一处通用的本地拒绝服务漏洞.该通用型本地拒绝服务可以造成大面积的app拒绝服务. 针对序列化对象而出现的拒绝服务主要是由于应 ...

  5. 从AlphaGo谈通用型人工智能设计

    最近赢了人机大战的AlphaGo火了,火得一塌糊涂,圈里圈外,是人都在谈AlphaGo.但是AlphaGo毕竟是为特定场景特定应用设计的特定型人工智能,和通用型人工智能还是有很大差别,离人工智能普及更 ...

  6. Xcode7 制作通用的framework(转)

      2016-01-07 16:24 2994人阅读 评论(0) 收藏 举报 分类: ios x code(55) 1.新建一个静态库工程. file→ new→ project, 弹出框中选择iOS ...

  7. 泛型理解及应用(二):使用泛型编写通用型Dao层

    相信目前所有的IT公司网站在设计WEB项目的时候都含有持久层,同样地使用过Hibernate的程序员都应该看过或者了解过Hibernate根据数据库反向生成持久层代码的模板.对于Hibernate生成 ...

  8. Android APP通用型拒绝服务、漏洞分析报告

    点评:记得曾经有段时间很多SRC平台被刷了大量APP本地拒绝服务漏洞(目前腾讯金刚审计系统已经可检测此类漏洞),移动安全团队发现了一个安卓客户端的通用型拒绝服务漏洞,来看看他们的详细分析吧. 0xr0 ...

  9. C++内存管理变革(6):通用型垃圾回收器 - ScopeAlloc

    本文已经迁移到:http://cpp.winxgui.com/cn:a-general-gc-allocator-scopealloc C++内存管理变革(6):通用型垃圾回收器 - ScopeAll ...

随机推荐

  1. 392. Is Subsequence

    392. Is Subsequence 水题,先是判断长度,长度t比s小,返回false,然后从左到右扫描t,然后同时扫描s,如果相同,s的index就往后拉一个,如果s的index等于s长度,返回t ...

  2. 九度OJ 1163 素数

    题目地址:http://ac.jobdu.com/problem.php?pid=1163 题目描述: 输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和 ...

  3. mysql远程访问的权限

    1.改表法 mysql>use mysql; mysql>update user set host = '%' where user = 'root'; 2.授权法 例如,你想myuser ...

  4. linux shell编程学习笔记(二) --- grep命令

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...

  5. opensuse13.1 双屏幕扩展

    最近搞一项j2eeweb工程,想要使用Linux平台编写程序.对比Ubuntu 14.04.Redhat.openSUSE,选择了最后这个. 安装的时候将/boot只分了100M,后来空间不足软件都安 ...

  6. java Object类

    常用的共性内容 1,实现任何对象的比较,一般比较同一种对象的比较 Object1.equals(Object obj);等同于Object1 == obj: 只有当两个引用指向同一个对象时方法返回tr ...

  7. java异常处理机制 (转载)

    java异常处理机制 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C ...

  8. javascript操作html元素CSS属性

    下面先记录一下JS控制CSS所使用的方法. 1.使用javascript更改某个css class的属性... <style type="text/css"> .ori ...

  9. 摘自淘宝的js地区组件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Rsync+Inotify-tools实现数据实时同步

    inotify是一种强大的,细粒度的,异步文件系统时间监控机制,它可以替代crond实现与rsync的触发式文件同步,从而监控文件系统中添加,删除,修改,移动等细粒事件,从LINUX 2.6.13起, ...