iOS使用Workspace来管理多项目
开发中会有一些常用的类或方法,或者是某个特定功能的,比如一个自定义的弹框、一个更容易使用的网络请求库,可以把它们放到一个单独的工程里,通过静态库(library、FrameWork)的方式应用到任何其他需要的项目里。就像使用百度地图sdk那样。
现在有一些文章介绍如何构建和使用自定义的静态库,但似乎没有说使用Workspace的。其实本质上,Workspace还是编译静态库然后给主工程使用,但不用先打开工程A,编译出libA.a,然后把文件拖到工程B,然后再工程B里面使用。主工程和它所用到的库工程是在同一个工作环境下(估计这就是Workspace的名字意思吧)。配置好了之后,你只需要运行主工程的target,会自动帮你编译需要的库。用过Pods库应该就明白。
好处就是:1.只需要打开一个工作环境,需要修改、同步代码,都不需要打开新的项目、新的文件,让人可以集中心思在代码上,在不同的项目里跳来跳去很容易打断思维的。
2.可以像同一个工程里一样,直接点击方法名查看引用库项目的代码,否则就要打开另一个项目,然后找到对应文件再找到方法。
3.只要运行自己的项目就行,就会自动帮你编译库文件。
下面以一个图书管理的demo来说WorkSpace的整个操作。
构建一个Workspace
如图选择构建一个WorkSpace,会生成.xcworkspace文件,以后就通过打开这个文件来打开WorkSpace。打开工程,会发现什么都没有,然后我们要添加各个工程(project)。在Xcode文管理文件的面板里,右键选择添加新文件。
当然,先要把项目建好。这里我建个项目叫BookManager,然后上面的添加文件,就把项目的BookManager.xcodeproj文件加进来就可以了。
重复上述动作,把所有需要的项目都加进来。这里我再建一个项目,用作对书籍的处理,假设这个库的作用是给一个URL,然后把书籍信息获取下来,并存到本地数据库,取名BookObtain吧。当然,这里建项目就要选择库类型了。
虽然添加项目是可以任意路径的,但是建议把所有要添加的项目放到同一个文件夹里,这样便于像header search paths这类的路径配置。
在BookObtain项目里构建了两个类,BookObtain负责获取书籍,Book是书籍的类。代码如下:
然后,现在我的项目里,想使用这个库里的获取书籍的功能,假设是写在ViewController这个类里,我在界面上加一个按钮,点击我就获取图书,然后把书籍信息显示到一个label里,就这么简单功能。
那其实就是调用BookObtain的+(Book*)obtainAndSaveBookWithURL:(NSString*)urlString方法,那要先导入头文件吧,发现#import"BookObtain.h" 报错,找不到头文件。那现在就遇到第一个问题:指定引用库的头文件路径。
在主项目的Build Settings 里找到Header Search Paths,添加一项$(SRCROOT)/../BookObtain,并且设置为recursive。$(SRCROOT)是当前的工程路径,..是返回上一层,然后到BookObtain文件夹。使用了相对路径,为了是项目移动不会影响这个配置,只要主工程和其他工程的相对位置不变,这里的相对位置是固定在同一个文件夹。
好了,添加代码:
- (IBAction)obtainBook:(UIButton*)sender {
Book* book = [BookObtainobtainAndSaveBookWithURL:@"xxx"];
NSLog(@"%@",book);
编译,报错:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_BookObtain", referenced from:
objc-class-ref in ViewController.o
BookObtain这个类未定义,什么原因?
头文件#import,只是知道了头文件,但是源码不知道,BookObtain并没有被编译到,这时要把静态库添加到主工程里。
到主工程的Build Phases的Link Binary With Libraries里添加,点击“+”按钮,会给出整个Workspace可选的静态库,把BookObtain.a加进来就好了。这是第二个问题:添加静态库。
但是,还有一个大问题,那就是静态库是不能携带资源的,比如书籍如果没有获取到封面信息,就是用一个默认封面,那这个图片肯定是固定并且存放在BookObtain项目里,因为这个功能被做成静态库就是为了能够在多个项目里使用,如果每个使用的项目还得负责这个图片,那就违背了节省工作的初衷了。
这是第三个问题:怎么携带资源文件?
我知道的,有两种处理:1.使用bundle,这个东西本就是用来携带资源的,百度地图的sdk同时也携带一个bundle.这种呢,比较正规一些,麻烦的是资源就不是在mainBundle里面了,找图片啥的麻烦。
2.使用shell脚本,Xcode本身支持使用脚本做编译处理,脚本里做的事就是把资源文件编译到 xxx.app文件里面去,xxx.app目录就对应着mainBundle。
点“+”添加bundle,iOS那一类里没有,选OS X里的frameWork...,也因为这个,bundle建立后,要把Build Settings 里的Base SDK由OS X换成iOS。
然后为了编译项目的时候先把需要的bundle编译了再编译主工程的target,可以在Edit Scheme->Build里把bundle加进去,而且加到主工程target前面。
脚本拷贝资源,Pods是个很好的例子,它的脚本文件名叫Pods-resources.sh.里面写好了对各种资源类型的处理。
脚本使用就是在Build Phases里,添加一个新的组件,在顶端左边有个“+”,点开选择New Run Script Phase,
然后在脚本组件里,写入执行脚本的代码:
/Users/sh/Pods/Pods-resources.sh指定脚本文件,后面跟着的是给它的参数/Users/sh/Desktop/BookObtain/Resource。我们可以把需要拷贝的资源都放到一个文件夹里,然后把这个文件夹路径作为参数。脚本只要针对给定的文件路径做处理就可以了。
iOS使用Workspace来管理多项目的更多相关文章
- iOS使用Workspace来管理多项目 ( 转 )
开发中会有一些常用的类或方法,或者是某个特定功能的,比如一个自定义的弹框.一个更容易使用的网络请求库,可以把它们放到一个单独的工程里,通过静态库(library.FrameWork)的方式应用到任何其 ...
- 用CocoaPods做iOS程序的依赖管理(转摘)
转摘自:http://blog.devtang.com/blog/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/ 文档更新说明 2012-1 ...
- iOS开发拓展篇——如何把项目托管到GitHub
iOS开发拓展篇——如何把项目托管到GitHub 说明:本文主要介绍如何把一个OC项目托管到Github,重操作轻理论. 第一步:先注册一个Github的账号,这是必须的 注册地址:Github官网注 ...
- 用CocoaPods做iOS程序的依赖管理
CocoaPods简介 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如Java语言的Maven,nodejs的npm.随着iOS开发者的增多,业界也出现了为iOS程序提供依赖管理的工具,它的 ...
- iOS 用CocoaPods做iOS程序的依赖管理
文档更新说明 2012-12-02 v1.0 初稿 2014-01-08 v1.1 增加设置 ruby 淘宝源相关内容 2014-05-25 v2.0 增加国内 spec 镜像.使用私有 pod.po ...
- iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇
iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...
- 利用cocoapods管理开源项目,支持 pod install安装整个流程记录(github公有库)
利用cocoapods管理开源项目,支持 pod install安装整个流程记录(github公有库),完成预期的任务,大致有下面几步: 1.代码提交到github平台 2.创建.podspec 3. ...
- 【转】用CocoaPods做iOS程序的依赖管理 -- 不错
原文网址:http://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/ 文档更新说明 2012-12-02 ...
- iOS开发之通过Framework建立项目依赖
https://www.jianshu.com/p/d146db167bf3 项目开发时经常会遇到个别模块想打包成framework的情况,传统的打包方式太繁琐,反复测试时很麻烦,不如一个项目管理来得 ...
随机推荐
- Asp.net Mvc4 使用Cas单点登录
因项目需要,使用了耶鲁大学的Cas单点登录方案,在java中使用一直正常,但是在.Net中碰到了循环重定向的问题,反复测试后,总算解决了,最终的配置如下: <?xml version=" ...
- 编写高质量JS代码的68个有效方法(十二)
No.56.避免不必要的状态 Tips: 尽可能地使用无状态的API 如果API是有状态的,标示出每个操作与哪些状态有关联 无状态的API简洁,更容易学习和使用,也不需要考虑其他的状态.如: 'tes ...
- 内存中OLTP(Hekaton)里的事务日志记录
在今天的文章里,我想详细讨论下内存中OLTP里的事务日志如何写入事务日志.我们都知道,对于你的内存优化表(Memory Optimized Tables),内存中OLTP提供你2个持久性(durabi ...
- 2013 - Lost connection to MySQL server at 'reading initial communication packet' 错误解决
一.操作与状态 当使用MySQL客户端连接localhost本地数据库时,连接不上,报错.(使用Tomcat连接数据库时可以连接上,但需要很长的请求时间.) 二.原因与解决办法 关于这个问题网上的解决 ...
- 重构第14天 分离职责(Break Responsibilities)
理解:面向对象的五大特征: SOLID,其中S就是职责单一原则.分离职责指当一个类有许多职责时,将部分职责分离到独立的类中,这样也符合面向对象的五大特征之一的单一职责原则,同时也可以使代码的结构更加清 ...
- 实用笔记-EF中直接运行SQL命令
在EF4.1,API的名字 有了些许改变,DbContext.Database就是对应于数据库端信息的封装.执行SQL命令也自然从Database类型开始.对应于ExecuteStoreCommand ...
- 根据数据库输出XML菜单
USE [test_YTHH] GO /****** Object: StoredProcedure [dbo].[usp_Print_SCC_Menu] Script Date: 04/08 ...
- BI之SSAS完整实战教程5 -- 详解多维数据集结构
之前简单介绍过多维数据集(Cube)的结构. 原来计划将Cube结构这部分内容打散,在实验中穿插讲解, 考虑到结构之间不同的部分都有联系,如果打散了将反而不好理解,还是直接一次性全部讲完. 本篇我们将 ...
- 别误用IsDigit与IsNumber函数
1.起因 最近发现程序中有一段控制TextBox数字输入的代码,相信大家都不会太陌生,如下: void int_KeyPress(object sender, KeyPressEventArgs e) ...
- EasyUI中Base(基础)的基本用法
EasyUI中Base(基础)的用法 一.Base(基础) 1.parser 解析器 2.easyloader 简单加载 3.draggable 拖动 4.droppable 放置 5.resizab ...