随着我们游戏社区产品的功能越来越丰富,多个项目的并行开发,以及一些功能模块重复开发,严重的增加了项目的维护成本,为了提升开发效率,以及解耦合,对于一些公共的模块,保证一端开发多端使用,对项目进行组件化,便提上了改造日程,首先是对一些公共模块进行私有库组件,然后是对业务模块进行本地组件划分。
以登录模块组件为例 LoginModule
在终端上切换到你想要创建项目的位置 ,然后开始创建(前提条件你Mac上已经安装了cocoapod 工具)
bogon:~ hero$ cd /Users/hero/Desktop
bogon:Desktop hero$ pod lib create LoginModule
按回车后,终端会让你回答几个问题
What platform do you want to use?? [ iOS / macOS ]
iOS
What language do you want to use?? [ Swift / ObjC ]
Swift
Would you like to include a demo application with your library? [ Yes / No ]
Yes
Which testing frameworks will you use? [ Quick / None ]
None
Would you like to do view based testing? [ Yes / No ]
Yes
至此,系统会帮你创建一个包含本地私有库的项目,新版本的cocoapod会自动执行 pod install ,模板库加载完成后,会通过命令行 打开我们刚创建的 LoginModule 工程

1、进入到刚创建的项目,可以看到 LoginModule 文件夹,这个文件就是用来存储,我们制作私有库时需要的代码文件和资源文件(图片、xib,以及其他资源文件)

2、 把Class 文件内的文件进行替换

3、 把文件加载到项目中
此时上一步加载的文件并未真正加载到项目中,此时需要在终端中进入到 Example目录中执行以下命令:
pod update --no-repo-update
在项目中可以看到我们添加的文件已经加载到工程中了

4、加载本地化组件
在主项目中建一个专门存放本地库的文件夹,把LoginModule 组件放进去

在Podfile文件中添加组件

然后进行pod install ,就可以看到组件添加到项目中了


s.name 私有库的名字
s.version 私有库的版本:管理代码库的版本,这个是和git平台代码对应的tag版本是一一对应的
s.summary 私有库概要
s.description 描述
s.license 许可证
s.author 创建库的用户
s.source 代码在 gitLab上存储的地址,也就是远程仓库
s.ios.deployment_target 这个库最低可以安装的平台
s.source_files 存储代码文件的路径
s.resource_bundles 存储图片的路径
s.frameworks 代码中需要用到的 framework
s.dependency 依赖的第三方库
什么是 Spec Repo?它是所有的 Pods 的一个索引,就是一个容器,所有公开的pods都在这里面,它实际上是一个Git 仓库,remote 端在GitHub上,当我们使用 Cocoapods 后它会被 clone 到本地的 ~/.cocoapods/repos 目录下,可以看到有一个master文件件,这个就是官方的 Spec Repo 。
我们需要创建一个类似 master 的私有 Spec Repo,同理这个私有 Spec Repo也要有一个远程端,我们创建一个 Git仓库用来存储 .podspec 版本文件。如果创建私有的,需要给使用这个仓库的同事 Git仓库权限 ,我们在 Gitlab 创建仓库的名字是 HeroSpecKit ,此时,我们需要做一下关联,在终端 中执行如下命令:
命令格式# pod repo add [Private Repo Name] [GitLab HTTPS clone URL]
pod repo add HeroSpecKit Https://xxxxxxxxxxx
再次进入到~/.cocoapods/repos 目录时就可以看到 HeroSpecKit 目录了。
注意:如果有其他合作人员共同使用这个私有库 Spec Repo ,在他有对应 Git仓库权限的前提下执行相同的命令添加这个 Spec Repo 即可。
切换到 LoginModule 项目目录, 在终端执行命令:
git add .
git commit -m "第一次提交"
git remote add origin https://xxxxxxxx
git push --set-upstream origin master
下面是提交代码后的界面

因为 podspec 文件中获取 Git 版本控制的项目还需要 tag 号,所以需要打上一个 tag
在终端执行命令:
git tag 0.1.0
git push origin 0.1.0
注意:0.1.0 要和 podspec 中的 s.version 版本号一一对应
上一步已经把本地的代码同步到了远程仓库,并且打了 tag,此时需要把 LoginModule.podspec 推送到 [Spec Repo] 私有库
先把已经编辑好的 LoginModule.podspec 文件进行一下验证,终端切换到 LoginModule 目录,执行以下命令:
pod spec lint LoginModule.podspec
然后,提示没有通过验证

在命令后面 添加 --allow-warnings ,再次执行命令
pod spec lint LoginModule.podspec --allow-warnings
这次通过了验证

接下来把 0.1.0 版本 LoginModule.podspec 文件推送到 [私有repod] ,在终端执行命令:
pod repo push [私有repod] LoginModule.podspec --allow-warnings
注意:如果想看到实时的进度可以在命令后面添加 参数 --verbose

至此,已经把 LoginModule 制作组件的过程已经完成,接下来我们就可以在 主工程中使用这个组件了
在需要用到此组件的项目的 podfile 文件中添加 pod 'LoginModule' ,并在终端执行 pod install
注意:因为这是我们的私有库 ,需要在 podfile 中添加 podspec 的路径源 :
source 'http://xxxxxxxxxx' ,否则会提示找不到此库
目前业务组件之间的通讯我们使用的是 CTMediator ,具体的可以参考 文档
https://casatwy.com/CTMediator_in_Swift.html
可以参考这篇文章

关于xib 的加载遇到的一些坑,xib无法被加载 ,会报如下的错误:

从上面的错误信息,可以看到没有在bundle中找到要加载的 xib资源
这里加载xib的方式分为两种:
1、 如果在 LoginModule.podspec 添加了 s.static_framework = false ,也就是把当前的源码打包成动态库 ,此时不需要把资源加载到 Assets 资源库中,直接放到代码中即可


右键找到 Framework 文件夹

找到 LoginModule.framework 然后右键,可以看到xib文件被打包到 framwork 包中了

具体的加载xib代码如下:
let bundle = Bundle.init(for: LoginInfo.self)
let VC = LoginInfo.init(nibName: "LoginInfo", bundle: bundle)
view.addSubview(VC.view)
需要注意的地方:
因为xib的加载默认是从 mainbundle 中加载的,但是此时需要从指定的库中加载,所以在配置xib的时候,在 Tartget Membership 中选中 xib所属的库,同时,最后在设置一下xib所属的Module ,这样就可以正常加载 xib 了


2、 如果在 LoginModule.podspec 添加了 s.static_framework = true ,也就是把当前的源码打包成静态库,此时我们需要把 xib 添加到 Assets 资源库中才能正常使用和加载,此种情况打包后,LoginModule中的bundle资源库,会被加载到main bundle 中,如图:

进入到 LoginModule_Example.app 文件夹中

右键进入到 LoginModule.bundle 中,可以看到添加的 xib资源

可以看到 LoginModule.bundle,是在主 bundle中,此时加载xib的方式是从mainbundle中加载资源,代码如下:
let loginModuleBundlePath = Bundle.main.path(forResource:"LoginModule", ofType:"bundle")
let loginModuleBundle = Bundle.init(path: loginModuleBundlePath!)
let VC = LoginInfo.init(nibName: "LoginInfo", bundle: loginModuleBundle)
view.addSubview(VC.view)

看了网上一些解决方案,依然无法解决问题,最终是在podfile 文件上 添加 pod 源来解决
source 'https://github.com/CocoaPods/Specs.git'

根据提示执行 pod install --repo-update 命令 就可以解决问题
如图gitlab上的显示:

解决方案:
1、假如电脑A通过 pod lib create TestPod 创建一个 TestPod项目 ,默认 TestPod 项目包含一个git 隐藏文件,为了避免出现上面的问题,先把 .git 文件删除 ,然后把它放入到主项目中,此时做一次代码提交,然后,通过终端进入到 TestPod 目录,通过 git init 初始化 一个git ,然后,把 gitLab 上的远程仓库和TestPod做关联,提交代码即可。此时,两个工程【主工程和子工程】都可以提交代码了
组件化实施与探索,对提升我们的项目开发效率是加成的,在这期间,我们也开发了通过脚本自动发布 组件的工具,大大的提升了开发效率,在接下来一段时间会继续带着小伙伴,深入的探索架构的演变与开发效率提升的工作。
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正