前面介绍过,虽然苹果公司禁止在iOS开发中使用动态库,而且也从XCode中移除了创建静态框架的功能,但我们还是可以通过对XCode进行小小的改动来创建静态框架。

编译环境:Macbook Air + OS X 10.9.2 + XCode5.1 + iPhone5s(iOS7.0.3)

首先创建一个静态库工程

给工程起个名字

创建成功

XCode5.0以后,创建的工程中默认自带了单元测试的代码:

即MyToolsFrameworkTestTests目录及TARGETS中的MyToolsFrameworkTestTests,这些代码不会对我们的代码产生任何影响,不用去管它们,如果实在看着不爽也可以删掉。

framework本质上是一个bundle,而我们当前的编译目标是一个静态库,所以必须删除当前的目标,新建一个bundle编译目标。

新建Target:File -> New -> Target... (该动作没有快捷键)

iOS框架中没有bundle模板,只有借助于OS X下面的bundle模板

新Target命名为MyTools,也可以使用原Target的名字,这样可能减少些麻烦

移动新Target中的Info.plist文件

删除MyTools目录,"Move to Trash"

删除多余的系统框架framework,此处要特别小心,千万不能用"Move to Trash",系统级框架,只有一份

此处会有个小问题(也可以不用理会),找到工程所在目录

发现MyTools目录实际上还在,MyTools-Info.plist文件仍在MyTools目录下,所以有时候,在XCode中进行的操作并不会在文件系统中体现出来,当然,这并不影响我们后续的工作

不过为了代码的整洁,还是可以整理一下

由于我们在文件系统中直接移动了MyTools-Info.plist的位置,所以XCode找不到了该文件,即二者之间的映射关系断开了,所以MyTools-Info.plist变成了红色,需要重新添加该文件到XCode中,也可以直接在Finder中拖拽该文件到XCode中

由于MyTools-Info.plist已经在指定位置,所以无需拷贝

删除红名的MyTools-Info.plist

首先选中TARGETS -> MyTools目标下的Build Settings面板,我们下面的一系列修改工作都在这里进行

由于我们选用OS X下面的模板,所以需要修改Architectures下Base SDK的值为Latest iOS(iOS 7.1)

修改Linking下面的:

Dead Code Stripping值为No

Link With Standard Libraries值为No

Mach-O Type值为Relocatable Object File

修改Packaging下面的Wrapper Extension值为framework

修改成功后会发现Products下面的MyTools.bundle变成了MyTools.framework

修改Deployment下面的OS X Deployment Target值为Compiler Default

由于我们修改了MyTools-Info.plist的位置,所以需要修改配置文件中的搜索路径

同时需要修改预编译文件pch的搜索路径及文件名

Build Settings面板里的修改完毕

最后一项,修改MyTools-Info.plist文件中的Bundle OS Type code的值为FMWK

修改全部完成

删除默认的.h和.m文件

将我们前面创建的静态库文件MyTools.h和MyTools.m文件拷贝过来

借用前面的成功,此处就不再重新建了

//
// MyToolsA.h
// MyToolsA
//
// Created by LZH on 14-8-14.
// Copyright (c) 2014年 LZH. All rights reserved.
// #import <Foundation/Foundation.h> @interface MyToolsA : NSObject - (int)add: (int)x Second: (int)y; //对象方法
+ (int)sub: (int)x Second: (int)y; //类方法 @end 
//
// MyToolsA.m
// MyToolsA
//
// Created by LZH on 14-8-14.
// Copyright (c) 2014年 LZH. All rights reserved.
// #import "MyToolsA.h" @implementation MyToolsA - (int)add: (int)x Second: (int)y{ return x + y;
} + (int)sub: (int)x Second: (int)y{ return x - y;
} @end

  

准备就绪,首先选定真机版本,"Command + B"编译

事情并没有我们预想的那般顺利

编译出错,原因是我们将原来默认的编译目标删除了,却没有重新配置编译目标,因此要重新配置项目

按下快捷键"Command + shift + ,"

修改编译目标为MyTools,同时配置生成Release版本

再次按下"Command + B",这次编译成功

Products下面的MyTools.framework也由红色变成了黑色,说明成功生成了framework框架

到文件系统中查看

发现虽然生成了框架目录,但是里面却没有发现必备的头文件,生成的framework有问题

清理掉先前的编译

选择TARGETS下MyTools目标的Build Phases

由于Compile Sources中已经添加了源文件MyToolsA.m,所以生成的框架中我们看到了二进制的框架文件MyTools

但是,这里并没有添加头文件,所以生成的框架中也没有头文件

手动添加头文件

点击下面的"+",选择MyToolsA.h头文件

拖动至Public

如下头文件MyToolsA.h和源文件MyToolsA.m都已成功加入

再次编译,看到了我们期待已久的头文件和二进制库文件,成功!

将目标平台由真机换成模拟器

再次编译,生成模拟器版本

注意:

如果先编译模拟器版本,即使编译成功了,Products下面的MyTools.framework也可能并不会又红色变成黑色,此处可能只关联到真机版本,所以不要怀疑自己,直接到文件系统下面去寻找。

找到生成的framework在文件系统中的路径

打开终端,开始版本合并

至此,framework创建完成,下面创建测试工程

工程命名

将生成的framework拖拽至工程中(我们刚刚把合并后的二进制文件MyTools放到了真机版的framework中覆盖掉了原来的MyTools文件,所以此处选择真机版的framework)

选择复制

在测试工程中看到了我们自定义的MyTools.framework

编写测试代码

//
// ViewController.m
// MyToolsFrameworkTest
//
// Created by LZH on 14-8-21.
// Copyright (c) 2014年 LZH. All rights reserved.
// #import "ViewController.h"
#import <MyTools/MyToolsA.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. int x = 10, y = 7; //使用类方法
NSLog(@"%d - %d = %d", x, y, [MyToolsA sub: x Second: y]); //使用对象方法
MyToolsA *myToolsA = [[MyToolsA alloc] init]; NSLog(@"%d + %d = %d", x, y, [myToolsA add: x Second: y]); } - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end

  

按下快捷键"Command + R"运行

模拟器版本运行结果

真机版本运行结果

大功告成!

收工!!!

iOS开发之静态库(四)—— 静态框架framework制作的更多相关文章

  1. ios 开发中 动态库 与静态库的区别

    使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用 动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库, ...

  2. 【转】iOS静态库 【.a 和framework】【超详细】

    原文网址:https://my.oschina.net/kaqijiang/blog/649632 一.什么是库? 库是共享程序代码的方式. 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存 ...

  3. iOS开发UI篇—简单介绍静态单元格的使用

    iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...

  4. iOS开发中与库相关的术语

    动态库 VS 静态库 Static frameworks are linked at compile time. Dynamic frameworks are linked at runtime

  5. iOS开发网络篇—简单介绍ASI框架的使用

    iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...

  6. iOS开发Swift篇—(四)运算符

    iOS开发Swift篇—(四)运算符 一.运算符 1.Swift所支持的部分运算符有以下一些 赋值运算符:= 复合赋值运算符:+=.-= 算术运算符:+.-.*./ 求余运算符:% 自增.自减运算符: ...

  7. iOS开发常用第三方库

    UI 动画 网络相关 Model 其他 数据库 缓存处理 PDF 图像浏览及处理 摄像照相视频音频处理 响应式框架 消息相关 版本新API的Demo 代码安全与密码 测试及调试 AppleWatch ...

  8. ios开发必备第三方库

    引言 作为iOS开发人员,在开发App的过程中怎么会不使用第三方库呢?相信没有App是不使用第三方库的! 网络库 网络库,这是开发必备,除非你的App玩单机.现在特别火也特别好用的网络库就数AFNet ...

  9. iOS开发 引用第三方库出现duplicate symbol时的处理方法

      该篇文章是我自己从我的新浪博客上摘抄过来的, 原文链接为: http://blog.sina.com.cn/s/blog_dcc636350102wat5.html     在iOS开发中, 难免 ...

随机推荐

  1. MATLAB - 练习程序,直方图均衡化

    直方图均衡化的作用是图像增强. 有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布. 第一个问题.均衡化过程中,必须要保证两个条件:①像素无论怎么映射, ...

  2. Redis 软件和配置

    Redis 下载 1.通过CMD命令进入redis 文件目录 2.运行[redis-server redis.windows.conf]

  3. myBatis自动生成mapping,dao和model

    myBatis没有自动封装实体类.所以都需要自己编写,但是表数据过多时.编写难度就会增加,错误率也会增加! 所以myBatis提供mybatis-generator-core-1.3.2-bundle ...

  4. MongoDB文档、集合、数据库简介

    文档 概述 文档是MongoDB的核心概念,是数据的基本单元,非常类似于关系数据库中的行.在MongoDB中,文档表示为键值对的一个有序集.MongoDB使用Javascript shell,文档的表 ...

  5. Python环境下NIPIR(ICTCLAS2014)中文分词系统使用攻略

    一.安装 官方链接:http://pynlpir.readthedocs.org/en/latest/installation.html 官方网页中介绍了几种安装方法,大家根据个人需要,自行参考!我采 ...

  6. SQL2008性能计数器注册表配置单元一致性失败

    按照这个操作 http://jingyan.baidu.com/article/7c6fb4287c923880652c9074.html如果在注册表中没有 HKEY_LOCAL_MACHINE\SO ...

  7. img图片放大控件 lightbox.js

    1.引入相关js,css jquery-1.7.2.min.js,lightbox.css,lightbox.js   2 图片增加<a href="大图片地址" rel=& ...

  8. android stuido build 慢的解决办法

    Enable Offline Work: Click File -> Settings. Search for "gradle" and click in Offline w ...

  9. nginx 从vagant挂载目录中加载nginx.conf配置进行开机启动

    nginx从vagrant挂载目录中读取配置启动,将nginx加入开机启动项!开机启动的时候nginx会因为加载不了配置导致启动失败! 原因是开机启动nginx服务在vagrant挂载之前,导致无法正 ...

  10. Python爬虫(一) 信息系统集成及服务资质网

    警告:不要恶意的访问网站,仅供学习使用! 本教程实例只抓取信息系统集成及服务资质网的企业资质查询. 1. 抓包 打开谷歌浏览器的开发者工具并访问该网站,过滤请求后找到请求数据的包. 1.1 找到相应封 ...