美文网首页iOS开发心得about iOSiOS开发常用
iOS使用Workspace来管理多项目

iOS使用Workspace来管理多项目

作者: FindCrt | 来源:发表于2015-09-04 06:37 被阅读36526次

    demo地址开发中会有一些常用的类或方法,或者是某个特定功能的,比如一个自定义的弹框、一个更容易使用的网络请求库,可以把它们放到一个单独的工程里,通过静态库(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文件加进来就可以了。

    选择项目文件(.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

    点“+”添加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。我们可以把需要拷贝的资源都放到一个文件夹里,然后把这个文件夹路径作为参数。脚本只要针对给定的文件路径做处理就可以了。

    相关文章

      网友评论

      • 裤裆有ShaQi:大神问一下,使用这种方法,我要从A项目跳转到B项目里面的某个功能模块可以实现吗
        FindCrt:你的跳转是指代码调用还是Xcode里查看代码?不过这两个都可以
      • 灬暮Se丶毛虫:大神,我按照您的步骤操作,到了最后,已经在静态库项目中创建bundle,并且将资源放到了bundle中,却不知道怎么才能从bundle中拿到资源呢。哦,貌似我连bundle都拿不到。
        灬暮Se丶毛虫:Demo终于运行起来了。
        下载Demo后,需要执行了《然后为了编译项目的时候先把需要的bundle编译了再编译主工程的target,可以在Edit Scheme->Build里把bundle加进去,而且加到主工程target前面。》这一步。
      • 61d6a0c6dc33:你好 我按照文章步骤 使用bundle携带资源时 遇到了问题。
        我在静态库里添加了xib,和图片,在bundle里'Copy Bundel Resources'里添加了文件。
        编译工程后 .bundle是红色的
        在主工程里使用图片 [UIImage imageNamed:@"xxBundle/xx.png"],还是找不到文件。
        最好把Demo贴出来吧 谢谢!!!
        灬暮Se丶毛虫:Demo终于运行起来了,执行了《然后为了编译项目的时候先把需要的bundle编译了再编译主工程的target,可以在Edit Scheme->Build里把bundle加进去,而且加到主工程target前面。》这一步。
        灬暮Se丶毛虫:你的Demo运行起来了吗,我的怎么没有运行的起来,找不到bundle
        FindCrt:@轻而清 https://github.com/ToFind1991/WorkSpaceDemo 看下这个。是库要建自己的bundle,然后不是mainBundle取资源
      • b57bc247097e:楼主有没有试过一个主工程下导入多个子工程,不是静态库这种。因为我现在面临的业务场景是需要主工程能编译运行,下面的子工程切换一下也能编译运行,这样子工程也可以这样单独开发调试
        FindCrt:@咖啡铯眼涙 是子项目添加target,如果你还有pod也在一起,自己配置相关的东西。
        b57bc247097e:@Find1991 貌似这样加的target不能调用pods里面的东西。。
        FindCrt:@咖啡铯眼涙 workspace模式下,其他子项目也是可以编译的,只是target是静态库,就跟pod那样,断点、奔溃之类的也是可以定位到子项目的,修改代码后,编译主项目也会把它重新编译。如果你想也能运行,子项目可以再建一个APP的target。但我觉得,如果子项目也是可运行的,我建议可以把通用部分提取出来,做成公用的静态库。
      • 知行合一认知升级:好用。还有个问题。如果是3个工程之间相互调用 方法呢。这也必须要把另2个工程,做成静态库吗?
        FindCrt:@慢跑20 应该避免这种情况,必定是一个是项目,其他是通用库。3个互相调用,说明没把通用部分分割出来吧。
      • 1651b2fc93b1:大神还是尽早出一个demo好让我们看一下携带资源文件的脚本配置吧,不甚感激:smile:
        FindCrt:@卖火柴的安徒生_d976 好
      • 某非著名程序员:想问下,有demo吗?我现在建了bundle,用引入工程方法可以读取图片,用这种管理方式图片不显示
        某非著名程序员: @260d120058f7哦哦,我放.a中了,后来主和bundle绑定也可以使用了。我试试放主工程中
        FindCrt:有时间我更个demo吧。你可以检查下bundle的路径,放到主工程了吗?用代码bundle取得到吗?里面图片呢?bundle可以右键查看包看里面的文件。
      • 麦子_KB:有个建议:
        尽量在 BookObtain.h 中
        @class Book;
      • 怀念裸奔的童年:完美的解决了我的问题
      • 01abfc381d03:楼主 两个Xcode工程必须把其中一个做成静态库 才能合成吗 直接不能合成?
        FindCrt:@卢波 那unity的那部分就可以做成库,新建一个target,设成静态库类型
        01abfc381d03:@find_1991 是这样的 我在做Unity3d和iOS 的整合 Unity导出来的就是一个Xcode工程 我想把这个工程嵌入到公司已有的app里面 因为按照我之前的办法整合太麻烦 效率低
        FindCrt:@卢波 把一个拖到另一个里面好像也可以,workspace这样是便于管理。具有通用性的东西才需要多个项目里使用,也就符合做成library的性质。如果两个项目都是独立的app,那没必要混在一起,不如把通用的代码抽出来做一个library,然后两边通用。
      • Janice_love:大神,最后一步,我没有弄出来,我的报错也是“No such file or directory”,我看上面你的回答了,没看懂。按照您上面描述的步骤,第一步,创建workSpace,放在文稿文件夹里,第二步,导入一个现有工程,我的工程名字为“qqqq”,第三步,创建静态库BookObtain,修改路径,添加静态库。第四部,创建bundle,名为“BookObtainBundle”,修改OS X 为iOS,第五步为,创建new run script phase,填写脚本。我填写的脚本是“/Users/sh/Pods/Pods-resources.sh /Users/sh/文稿/BookObtain/Resource”。我发现,工程中,没有看到Resource文件夹,我就在静态库BookObtain内添加了一个group,命名为Resource。运行给出“No such file or directory”错误,我不知道,最后一步的脚本该怎么写,求大神指教,期待您的回复,谢谢。
        Janice_love:@find_1991 您好,感谢你的回复。刚才建文件夹时大意了,已按照您说的,在finder中的BookObtain文件夹中创建了Resource文件夹,并拖到工程中BookObtain文件夹下。现在Resource中添加了一张图片,来操练您说的实现携带资源文件。目前脚本我不知道怎么写,以我添加的图片为例,给我说明一下吧,大神。谢谢。
        FindCrt:@Janice_love 脚本是为了把资源拷到主目录,不需要拷贝的文件就不要放进去了。
        FindCrt:@Janice_love 使用xcode添加group这样加一个文件夹实际并没有增加文件夹,你到findder里看就知道。要到findder里建个文件夹然后再加到xcode里。这个错误加文件夹是对的。
      • 星兴:最后一步是把pod的那个脚本拿到我们项目里面,然后使用吗
        Calvin_Shen:赞一个,同是90后,感觉和楼主的经验技术差的不是一点半点
        FindCrt:@星兴 需要把pod的脚本改一下,因为拷贝的资源地址不一样。因为项目结构跟使用pod后的项目是一样的,所以借用它的脚本。你可以稍微看下脚本的代码
      • 小白猿:解决了困扰多日的问题,大神手下膝盖 :+1:
        FindCrt:@PQ小白猿 有帮助就好
      • UItachi:framework可以直接封装资源文件
        UItachi:@UItachi 如果说的资源全是图片的话,用xcassets更好
      • 2c8bba7cd843:作者你好,最后一步脚本执行资源拷贝那边,还需要将bundle导入主工程吗?
        而且我这边脚本运行好像出错了 说 “No such file or directory”
        我是把另外一个用了Cocoapods的工程里的 Pods-resources.sh文件复制到Workspace的文件路径下,然后拖进去的,这样是不是不对?
        FindCrt:@D3MO bundle和脚本都是为了把资源弄到主工程,任意一个就可以了。报错
        “No such file or directory”应该是你脚本指定的路径有问题,看我文章里写的有两个路径:/Users/sh/Pods/Pods-resources.sh /Users/sh/Desktop/BookObtain/Resource。前一个是脚本文件路径,后一个是资源的路径(实际应该是脚本的输入参数,但pod的脚本本身是复制这个路径下的资源的)
      • 3eda46c22ce6:大神,想问一下,现在是已有的带pod的项目,想要添加新的工程进去,进行关联,使用新的工程的类。该怎么弄呢?
        01abfc381d03:@3eda46c22ce6 你好你的问题解决了吗?
        FindCrt:编译APP的那个项目是主项目,其他被引用都做成静态库,在那个target里建个静态库,把需要的类源码都加进去。当然这个项目也要放入worksapce里,你查下静态库使用吧。
      • 木木烈少:最后脚本那一块没看懂
        ChardXu:@find_1991 你的脚本路径应该是绝对路径吧,而在实际的项目中应该写相对路径啊,能否给个demo,邮箱1007034110@qq.com,或者把项目上传到github上,多谢了
        FindCrt:@林少烈 有时间我补充一下
      • elite_me:不错
      • LostAbaddon:代码可以使用代码块:
        ```code_lang
        blablabla
        ```
        FindCrt:@ChronosTartaro 搞了半天终于出来了,原来要先切换到Markdown模式下

      本文标题:iOS使用Workspace来管理多项目

      本文链接:https://www.haomeiwen.com/subject/nvvlcttx.html