原创:知识点总结性文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容
目录
- 一、Git
- 1、知识点
- 2、安装和基本使用
- 3、常用命令
- 二、CocoaPods
- 1、安装 cocopods
- 2、使用 cocopods
- 3、知识点
- 4、常见的疑难杂症
- 三、制作cocoapod库
- 1、iOS组件化/模块化的需求
- 2、cocoapod原理
- 3、新建仓库
- 4、配置.podspec
- 5、更新GitHub里面的库
- 6、提交.podspec到CocoaPods
- 7、使用创建的库
- 8、创建过程遇到的问题
- 四、python3.7
- 1、安装 python3.7
- 2、使用 python3.7
- 参考文献
一、Git
1、知识点
a、管理模式
集中管理模式:SVN
分布式管理模式:有一个中心代码库,每位团队人员本地也都有代码库
- 代码库 (repository): 存放项目代码以及历史备份的地方
- 分支 (branch):为了验证和实验一些想法、版本发布、缺陷修改等需要
- 合并分支 (merging branch)
- 签出 (checkout):从代码库获得文件或目录,将其作为副本保存在目录下
- 提交 (commit):修改的文件或目录作为新版本复制回代码库
- 冲突 (conflict)
- 解决 (resolution):需要人为干预解决,以接受一组更改并删除另一组更改
- 索引 (index):快照
b、Git还有成熟的代码托管服务GitHub网站
- 服务器搭建
- 如果项目不需要与其他开发人员协同开发,我们就不需要
Git
服务器。 - 任何能够提供通信协议和安全认证的代码库, 都可以认为是服务器。
-
HTTP(S)
协议和SSH
协议都可以支持远程库读写 、身份认证等操作。 -
Git
常用的协议是SSH
协议,我们需要在本机上生成后,将公钥提供给GitHub
网站
- 如果项目不需要与其他开发人员协同开发,我们就不需要
- 只有付费账户才可以创建私有库
- 选中
Initialize this repository with a README
复选框创建一个README
文件,用来说明这个代码库的用途 - 但此时代码库中还是空的,我们需要在本地电脑中推送一个
Xcode
项目到GitHub
代码库 - 通过
SourceControl- Push
菜单项推送到GitHub
服务 器 ,其中选择Remote
为origin/master
- 派生与
Git
中的分支很像,可以把它理解为代码库级别的分支,把Fork
代码库派生到当前账户下面了 - 点击
Transfer
按钮,输入要转移的代码库和新的拥有者 - 组织中会有管理员,他可以管理代码库,对代码库重新命名 、 删除和转移代码库等
- 普通成员对代码库进行接受推送请求、合并推送
c、图形界面辅助工具sourtree
sourtree sourtreed、SSH密钥
- 查看是否已经有了
ssh
密钥:cd ~/.ssh
,如果没有密钥则不会有此文件夹,有则备份后删除 - 生成密钥:按3个回车,密码为空。最后得到了两个文件:
id_rsa
和id_rsa.pub
- 辅助串添加到
GitHub
中的git.lab
框里 - 修改
sourtree
为SSH
方式而不是HTTP
e、注意点
- 每天修改量在10M以内,尽量每天提交修改,防止一次性提交造成大量代码冲突问题
- 每次
push
之前一定需要先进行pull
操作,先将本地更新再提交自己的修改 - 遇到冲突,可以使用如
$ open ucareshop/AppDelegate.m
可以打开文件的冲突部分将其删除 - 切换到分支再
git push
,不要困扰了master
,之后等代码审核通过了再更新到master
2、安装和基本使用
a、安装镜像
使用以下命令替换 gems 默认源
// 添加 TUNA 源并移除默认源
gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/ --remove https://rubygems.org/
// 列出已有源,应该只有 TUNA 一个
gem sources -l
b、Git用户信息
当安装完 Git
应该做的第一件事就是设置你的用户名称与邮件地址
git config --global user.name "Xie Jiapei"
git config --global user.email jiapei@ucarinc.com
c、Git 通常使用流程
// 切换到本地想安装的目录
$ cd Desktop/
// 安装Github上的项目
git clone http://gitlab.10101111.com:8888/jiapei.xie/gitlearn.git
// 切换进该项目目录
$ cd gitlearn/
将本地想要添加的文件拖进到下载下来的项目中
// 切换到分支,不影响mainTree
$ git checkout develop
// 将拖进来的文件添加到项目中
git add .
// 本地提交,写好提交原因
git commit -m "init"
// 先拖下来远程Github上的最新内容
// git pull命令是git fetch和git merge命令的一个组合
git pull
// 再将自己修改后的提交到远端
git push
// early EOF 文件太大
git config --global http.postBuffer 15728640
d、Generate New Token
Account点击「+」按钮添加帐号并选择 GitHub
之后,你会发现此处需要填写 Account
和 Token
。其中 Account
是 GitHub
用户名,Token
则是一个特殊的许可,它允许 Xcode
使用你的 GitHub
帐号管理你的 Remote Repository
远程仓库。
进入 GitHub
设置页面,点击右上角的「Generate new token
」即可生成一串许可数字,将这串数字复制回到 Xcode
登录界面的 Token
文本框中,并点击「Sign In
」登录即可完成 GitHub
帐号的设置。
3、常用命令
a、查找命令的帮助信息
git help
b、目录和文件
// 新建目录
$ mkdir learngit
// 用于显示当前目录路径
$ pwd
// 上一级
$ cd ..
// 新建文件
$ touch readme.txt
// 查看文件内容
$ cat Podfile
// 文件状态,用于解决冲突
$ git status
// 查看所有文件
$ ls -al
c、分支
// 创建仓库
$ git init 这个目录默认是隐藏的
// 创建并切换到分支
$ git checkout -b develop
// 切换到master
$ git checkout master
// 删除分支
$ git branch -d develop
d、vim文本编辑器
// 进入
$ vim readme.txt
// 保存修改并退出
wq (或者shift zz)
// 忽略文件
$ vim .gitignore
e、log日志
// 历史记录
$ git log
// 如果嫌输出信息太多,看得眼花缭乱
$ git log --pretty=oneline
// 如果只想看最近几条的数据
$ git log -n 1
// 例如
1 file changed:1个文件被改动(我们新添加的readme.txt文件)
2 insertions:插入了两行内容(readme.txt有两行内容)
f、reset 回退
// 寻找版本号
$ git reflog
// 文件的索引-文件内容的哈希值
5e9ae2dd
// 回退机制,上上一个版本就是HEAD^^,上100个版本写成HEAD~100,版本号没必要写全,前几位就可以了
$ git reset --hard HEAD^(版本号)
$ git reset HEAD readme.txt
// 回滚版本
git revert
// 删除文件
$ rm test.txt 并且 git commit
g、gitignore 忽略 Pods
- 打开terminal (终端)
- 输入指令:
cd
'项目目录' - 输入指令:
vim .gitignore
- 把 附文代码
copy
到终端 - 按
esc
键 ,输入指令:wq
(指令意思:保存并返回上一层) - 此时,可以输入指令
sudo ls
查看目录下是否存在gitignore
,有则表示成功 - 如果之前没有提交过第三方到远端,则按照正常情况,
commit
一下再push
到远端就完成了 - 如果之前提交过得话,则输入指令
git rm -r Pods
,然后再comit
,再push
。 - 重新
clone
一份这个项目到本地,你会发现这个项目中没有了Pods
这个文件夹,运行项目也会报错。 -
cd
到项目目录 ,执行pod install
试试,大功告成。
# Xcode
.DS_Store
*/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.hmap
*.xccheckout
*.xcworkspace
!default.xcworkspace
#CocoaPods
Pods
!Podfile
!Podfile.lock
二、CocoaPods工具管理依赖
1、安装 cocopods
// 安装cocopods的索引目录
$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git master
// 安装cocopods
$ sudo gem install cocoapods
2、使用 cocopods
a、安装框架
在根目录下建立Podfile
文件,然后修改其中的内容
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'UseUIControlFramework' do
pod 'DZNEmptyDataSet'
pod 'MGSwipeTableCell'
pod 'FSCalendar'
pod 'Toast'
pod 'MBProgressHUD'
pod 'zhPopupController'
pod 'Masonry'
end
在终端安装框架
xiejiapei@xiejiapeis-iMac Example % pod install
Analyzing dependencies
Downloading dependencies
Installing XJPCategoryKit 0.1.0
Generating Pods project
Integrating client project
Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed.
b、升级CocoaPods
sudo gem install cocoapods
3、知识点
a、与Carthage比较
中心化
-
CocoaPods
搭建了一个中心库(cocoapods.org)
, 第三方库被收录到该中心库中,没有收录的第三方库是不能使用CocoaPods
管理的,这就是所谓的"中心化“思想。 -
Carthage
没有这样的中心库,第三方库基本上都是从GitHub
或私有Git
库中下载的,这就是“去中心化"。
侵入性
-
CocoaPods
在下载第三方库后,会将其编译成静态链接库或动态框架文件 ; 然后会修改Xcode
项目属性,配置依赖关系,这就是"侵入性"。 -
Carthage
下载成功之后, 会将第三方库编译为动态框架,注意Carthage
有个限制,即第三方库只能编译为框架,然后由开发人员自已配置依赖关系,Carthage
不会修改Xcode
项目属性,这就是“非侵入性" 。
b、明确第三方版本号
指定依赖库名一般是指 GitHub
上库的“用户名/项目名”,这个名字如果不能确定, 需要到 GitHub
上查询确定。
pod 'AFNetworking' //不显式指定依赖库版本,表示每次都获取最新版本 (<span style="color: rgb(50, 62, 50); font-family: Arial; font-size: 14px; line-height: 26px;">11、</span><span style="color: rgb(50, 62, 50); font-family: Arial; font-size: 14px; line-height: 26px;">pod update</span>)
pod 'AFNetworking', '2.0' //只使用2.0版本
pod 'AFNetworking', '> 2.0' //使用高于2.0的版本
pod 'AFNetworking', '>= 2.0' //使用大于或等于2.0的版本
pod 'AFNetworking', '< 2.0' //使用小于2.0的版本
pod 'AFNetworking', '<= 2.0' //使用小于或等于2.0的版本
pod 'AFNetworking', '~> 0.1.2' //使用大于等于0.1.2但小于0.2的版本
pod 'AFNetworking', '~>0.1' //使用大于等于0.1但小于1.0的版本
pod 'AFNetworking', '~>0' //使用最新版本,与不显示指定依赖库版本相同
c、轻量级和重量级框架的区别
最主要的衡量指标以启动程序需要的资源来决定。
框架的侵入性程度:轻量级的侵入性程度较低,重量级框架需要继承和实现框架的类或者实现框架的接口,以方便使用框架中间件特性。这就意味着,需要实例化大量的类并且注册到应用中去,虽然可能用不到。
轻量级框架一般是一组独立的特性实现集:而重量级框架往往依赖于其他类型的容器来支持框架的特性。
开发的方便程度:重量级框架开发时则要写一些框架绑定的类,部署、运行及测试过程都较为复杂,开发起来并不方便。
解决问题的侧重点不同:轻量级框架侧重于减小开发的复杂度,相应它的处理能力较弱,重量级框架则强调高可伸缩性,适合于开发大型企业应用。
轻量级框架总的特点:一般是非侵入性的、依赖的东西非常少,占用资源非常少,部署简单,比较容易使用。
4、常见的疑难杂症
三、制作cocoapod库
1、iOS组件化/模块化的需求
当 App 的功能逐渐庞大,开发人员越来越多的时候,就会出现各种各样的问题,比如:
- 代码量庞大,相同功能代码可能反复被实现,编译速度慢
- 功能交织,难以抽离,问题排查难度加大,提交容易出现冲突
- 一处出现错误,导致整个项目难以运行
这时合理的组织架构就变得尤为重要,通常的做法就是将 App 内的功能进行模块化:
- 功能分成不同的模块,不同的人员维护不同的模块,责任清晰
- 不经常改动的代码做成模块化之后,不需要编译整个项目(每个组件都有一个壳工程),增加编译速度
- 模块之间相互独立,减少依赖,不容易出现代码提交冲突
盲目组件化导致开发效率变低
- 两三个人维护的业务简单的项目,组件化的解耦调用可能会导致代码逻辑变复杂
- 组件化粒度过细也会导致一个业务需求需要修改多个组件,容易让代码追踪变得困难
- 与对应组件负责人的沟通也会拖慢开发的进度
总的来说,只有项目到达一定规模后,开始出现相对独立的业务,团队人员开始增加,单一项目的开发模式成为了开发效率的掣肘,这个时候才是应该开始做组件化的时候。
2、cocoapod原理
点开Specs后,在This repository
里输入AFNetworking
搜索
CocoaPods
是帮我们管理第三方和自己的库,它本身也是一个.xcodeproj
工程。只不过,它是专门管理第三方和自己的库的工程,而它的工作原理就是:你把.podspec
文件制作好,然后trunk push
给它,它再把.podspec
文件保存为.podspec.json
文件放到GitHub
,你需要的话,它通过这个.podspec.json
把GitHub
上对应的开源库的文件下载下来,放到你的工程里。
3、新建仓库
a、在GitHub上新建一个仓库
在GitHub上新建一个仓库b、创建框架工程
很多教大家制作pods
的教程,可笑又可恨的是连最基本的创建框架工程这一步都没告诉大家,结果很多小白忙活了半天还是在做APP,造成了一堆意外错误。
不要用上面👆这个来创建工程,小白的我最初就是分不清私人框架和公共的pods
库创建方式不同,使用了上面的方式创建了私有框架来进行下面的流程导致了一大批莫名其妙的诡异错误,浪费了很多时间。
使用下面的方式创建公共的pods
库
xiejiapei@xiejiapeis-iMac Desktop % pod lib create XJPCategoryKit
允许以上命令后会进入后续的选择流程,cocopods通过这些选择会为你创建相应的模板工程,包括框架、使用的示例和测试。
Cloning `https://github.com/CocoaPods/pod-template.git` into `XJPCategoryKit`.
Configuring XJPCategoryKit template.
What platform do you want to use?? [ iOS / macOS ]
> iOS
What language do you want to use?? [ Swift / ObjC ]
> ObjC
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
// 你应该测试你的库,测试可确保使用您库的人员的稳定性,建议使用测试框架,而不是依赖Apple的XCTest
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> Specta
// 根据您所构建的内容库,你可能会发现快照基于测试是验证结果的聪明的方式
Would you like to do view based testing? [ Yes / No ]
> Yes
// 使CocoaPods生成的所有类都适合您的样式,所有从Xcode内部生成的类都将以您的前缀开头
What is your class prefix?
> XJP
Downloading dependencies
Installing Expecta (1.0.6)
Installing Specta (1.0.7)
Installing XJPCategoryKit (0.1.0)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `XJPCategoryKit.xcworkspace` for this project from now on.
Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed.
Ace! you're ready to go!
We will start you off by opening your project in Xcode
open 'XJPCategoryKit/Example/XJPCategoryKit.xcworkspace'
可能运行pod install
后会遇到被墙屏蔽导致的超时问题
[!] CDN: trunk Repo update failed - 22 error(s):
CDN: trunk URL couldn't be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/5/0/9/FBSnapshotTestCase/1.1/FBSnapshotTestCase.podspec.json Response: Timeout was reached
解决方案是进入到Podfile
文件中,添加清华大学开源软件镜像站
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
再执行如下命令清除当前的 trunk
pod repo remove trunk
再次尝试 pod install
就可以了
xiejiapei@xiejiapeis-iMac repos % pod repo remove trunk
Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2
Removing spec repo `trunk`
xiejiapei@xiejiapeis-iMac repos % cd /Users/xiejiapei/Desktop/XJPCategoryKit/Example
xiejiapei@xiejiapeis-iMac Example % pod install
Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2
Analyzing dependencies
Downloading dependencies
Installing Expecta (1.0.6)
Installing Expecta+Snapshots (3.1.1)
Installing FBSnapshotTestCase (2.1.4)
Installing Specta (1.0.7)
Installing XJPCategoryKit (0.1.0)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `XJPCategoryKit.xcworkspace` for this project from now on.
Pod installation complete! There are 5 dependencies from the Podfile and 5 total pods installed.
创建完成后自动打开的pod
库工程目录如下
c、拖入项目文件
将自己的工程文件拖入到项目中,分成两个部分,一个部分放资源文件,一个部分放自己的工程文件,这个架构很重要!!!
拖入项目文件 拖入项目文件再将这些文件放入到工程中,你可能会好奇为什么在Classes
目录下的文件在工程目录中跑到了XJPCategoryKit
文件下,这个无需担心,系统会根据XJPCategoryKit.podspec
文件进行自动关联,不信你在Classes
目录下删除个文件试试,工程目录中XJPCategoryKit
文件下的该文件马上会爆红表示不存在该文件了。
有个小技巧,直接pod install
就可以更新工程目录。
4、配置.podspec
a、创建.podspec文件,create后面必须是开源库名
podspec
文件会自动生成,假如不小心删除掉了,则可以通过以下的方式进行创建。
xiejiapei@xiejiapeis-iMac desktop % cd /Users/xiejiapei/Desktop/DriverRecordSoundKit
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % pod spec create DriverRecordSoundKit
Specification created at DriverRecordSoundKit.podspec
使用Sublime Text
打开podspec
文件后阅读注释
Be sure to run `pod spec lint RecordSoundKit.podspec' to ensure this is a valid spec and to remove all comments including this before submitting the spec.
在你提交.podspec文件到CocoaPods前,务必要在命令行运行 pod spec lint RecordSoundKit.podspec 来确保.podspec有效,并且删除所有的注释,包括这句(Be sure ... submitting the spec.)
b、podspec 的语法说明
Pod::Spec.new do |spec| #表示用spec作为代称
#开源库的名字
spec.name = "DriverRecordSoundKit"
#开源库当前版本
spec.version = "1.0.0"
#开源库概述(打开GitHub能看到的描述)
spec.summary = "使用场景包括:司机行驶过程、会议、课程等的全程录音"
#开源库描述 (这个描述会被用来生成开源库的标签和提高被搜到,必需写在中间一行,只要在中间一行,不需要考虑缩进)
spec.description = <<-DESC
1. 部分城市运管部门要求网约车需提供服务过程中录音功能
2. 与高德等聚合平台对账时,对于部分争议作弊订单,需要行程中录音证据
3. 司乘发生纠纷时,有行程中录音可方便责任判定,并且行程中录音功能的存在,可在一定程度上避免一些恶意投诉或司机不规范服务
4. 便于业务部门抽查司机服务规范情况,例如人工抽查或语音质检
5. 本录音工具类也可用于会议或者上课等场景进行全程录制
DESC
#可以是开源库的GitHub地址
spec.homepage = "https://github.com/xiejiapei-creator/DriverRecordSoundKit"
#协议
spec.license = "MIT"
#开源库作者
spec.author = { "jiapei.xie" => "2170928274@qq.com" }
#开源库作者的社交链接(此处我放的是简书)
spec.social_media_url = "https://www.jianshu.com/u/1ceb4a330607"
#开源库支持的平台(暂时没考虑tvOS、OSX等)
spec.platform = :iOS
#开源库最低支持
spec.ios.deployment_target = "10.0"
#支持的swift版本
spec.swift_version = "4.0"
#是否使用静态库。如果podfile指明了use_frameworks!命令,但是pod仓库需要使用静态库则需要设置
spec.static_framework = true
#开源库GitHub的路径与tag值,GitHub路径后必须有.git,tag实际就是上面的版本
spec.source = { :git => "https://github.com/xiejiapei-creator/DriverRecordSoundKit.git", :tag => "#{spec.version}" }
#开源库头文件
spec.public_header_files = 'DriverRecordSoundKit/DriverRecordSoundKit.h'
#私有库依赖的三方库
spec.dependency 'AFNetworking', '~> 1.0'
#指定私有库 文件是否 是ARC.默认是true,表示所有的 source_files是arc文件
spec.requires_arc = true
#pod库使用的系统库
spec.ios.framework = 'CFNetwork'
spec.frameworks = 'QuartzCore', 'CoreData'
#libraries使用的静态库 比如libz,sqlite3.0等,多个用逗号分开
spec.ios.library = "xml2"
spec.libraries = 'xml2', 'z'
#自定义前缀文件,默认是true cocoapos会生成默认前缀.pch文件
spec.prefix_header_file = false
spec.prefix_header_file = 'iphone/include/prefix.pch'
#pod文件路径
#一个宗旨:库里面每个文件、资源都要有路径指向它。
spec.source_files = "Classes/*.{h,m}" #表示匹配所有Classes目录下文件,不包含子目录的
spec.source_files = "Classes/**/*.{h,m}" #表示匹配所有.h、.m结尾的文件(主目录和子目录,其中**相当于省略中间层级)的
spec.source_files = 'Classes/**/*.{h,m}', 'More_Classes/**/*.{h,m}'
s.source_files = "UnionPay/**/*.{h, mm}"
#公共头文件,这些头文件将暴露给用户的项目。如果不设置,所有source_files的头文件将被暴露
#private_header_files.和public_header_files相反,指定不暴露的头文件
spec.public_header_files = 'Headers/Public/*.h'
#依赖的框架
s.dependency 'UCARLogger'
#指定三方库的路径
spec.ios.vendored_frameworks = "MyPod/Frameworks/MyFramework.framework"
spec.vendored_frameworks = 'MyFramework.framework', "TheirFramework.framework"
#三方静态库,指明具体路径
spec.ios.vendored_library = "Libraries/libProj4.a"
spec.vendored_libraries = 'libProj4.a', 'libJavaScriptCore.a'
s.ios.vendored_libraries = "UnionPay/**/*.a"
s.vendored_libraries = 'UCARFaceID/UCarLive/MGBaseKit/libMobileSDKAuth.a', 'UCARFaceID/UCarLive/FacePlusPlus/libliveness.a'
#系统的框架
s.frameworks = "CFNetwork", "SystemConfiguration"
s.framework = 'CoreMotion', 'CoreMedia', 'AVFoundation'
s.frameworks = "Foundation"
#系统的静态库,需要去掉lib前缀
s.library = 'c++', 'z'
#资源文件
s.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
s.resource_bundles = { 'XBPodSDK' => ['XBPodSDK/Assets/**']}
s.resource = "FaceID/MGLiveResource.bundle"
s.resource_bundles = { 'PushEngine' => ['PushEngine/Assets/*.plist'] }
#被排除的文件
spec.ios.exclude_files = "Classes/osx"
spec.exclude_files = 'Classes/**/unused.{h,m}'
#Subspecs 私有库模块
spec.subspec 'ConvertMP3' do |ss| #简单
ss.source_files = 'DriverRecordSoundKit/ConvertMP3.h' #指定子模块路径
end
#Subspecs 私有库模块
spec.subspec 'Encryption' do |ss| #有几个do就有几个end
ss.subspec 'RNCryptor' do |sss| #复杂
sss.source_files = 'DriverRecordSoundKit/Encryption/RNCryptor/*.{h,m}' #指定子模块路径
end
end
s.subspec 'BaiduComponent' do |f|
f.source_files = 'MapFundation/Classes/Baidu/**/*.{h,m}'
f.public_header_files = 'MapFundation/Classes/Baidu/**/*.h'
f.vendored_libraries = 'MapFundation/thirdlibs/*.{a}'
f.vendored_frameworks = 'MapFundation/frameworks/*.{framework}'
f.frameworks ='CoreGraphics','CoreLocation','OpenGLES','QuartzCore','Security','SystemConfiguration'
f.libraries = 'iconv','sqlite3','c++','z'
f.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-ObjC' }
f.dependency 'MapFundation/Common'
end
#部署的架构
s.pod_target_xcconfig = { 'VALID_ARCHS' => 'arm64 armv7', 'OTHER_LDFLAGS' => '-force_load'}
s.user_target_xcconfig = { 'VALID_ARCHS' => 'arm64 armv7', 'OTHER_LDFLAGS' => '-force_load'}
end
c、模仿默认的podspec文件
Pod::Spec.new do |s|
s.name = 'XJPCategoryKit'
s.version = '0.1.0'
s.summary = 'A short description of XJPCategoryKit.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://github.com/xiejiapei-creator/XJPCategoryKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'xiejiapei-creator' => '2170928274@qq.com' }
s.source = { :git => 'https://github.com/xiejiapei-creator/XJPCategoryKit.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
s.source_files = 'XJPCategoryKit/Classes/**/*'
# s.resource_bundles = {
# 'XJPCategoryKit' => ['XJPCategoryKit/Assets/*.png']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end
d、DriverRecordSoundKit最终的podspec文件
Pod::Spec.new do |s|
s.name = 'DriverRecordSoundKit'
s.version = '1.0.0'
s.summary = '使用场景包括:司机行驶过程、会议、课程等的全程录音'
s.description = <<-DESC
1. 部分城市运管部门要求网约车需提供服务过程中录音功能
2. 与高德等聚合平台对账时,对于部分争议作弊订单,需要行程中录音证据
3. 司乘发生纠纷时,有行程中录音可方便责任判定,并且行程中录音功能的存在,可在一定程度上避免一些恶意投诉或司机不规范服务
4. 便于业务部门抽查司机服务规范情况,例如人工抽查或语音质检
5. 本录音工具类也可用于会议或者上课等场景进行全程录制
DESC
s.homepage = 'https://github.com/xiejiapei-creator/DriverRecordSoundKit'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'xiejiapei-creator' => '2170928274@qq.com' }
s.source = { :git => 'https://github.com/xiejiapei-creator/DriverRecordSoundKit.git', :tag => s.version.to_s }
s.social_media_url = "https://www.jianshu.com/u/1ceb4a330607"
s.ios.deployment_target = '10.0'
s.source_files = 'DriverRecordSoundKit/Classes/**/*'
s.public_header_files = 'DriverRecordSoundKit/Classes/UCARRecordSoundTool.h'
s.vendored_libraries = 'DriverRecordSoundKit/Classes/**/*.a'
s.frameworks = "AVFoundation", "Foundation", "Security"
s.dependency 'RNCryptor-objc'
end
e、XJPCategoryKit最终的podspec文件
Pod::Spec.new do |s|
s.name = 'XJPCategoryKit'
s.version = '0.1.0'
s.summary = '提供便利的分类'
s.description = <<-DESC
提供OC常见的各种分类方法
DESC
s.homepage = 'https://github.com/xiejiapei-creator/XJPCategoryKit'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'xiejiapei-creator' => '2170928274@qq.com' }
s.source = { :git => 'https://github.com/xiejiapei-creator/XJPCategoryKit.git', :tag => s.version.to_s }
s.social_media_url = "https://www.jianshu.com/u/1ceb4a330607"
s.ios.deployment_target = '8.0'
s.source_files = 'XJPCategoryKit/Classes/**/*'
s.public_header_files = 'Pod/Classes/XJPCategoryKit.h'
end
f、库的问题
首先逐个查找文件,看看依赖了哪些系统的库
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import "UCARSingle.h"
#include <mach/mach.h> //获取CPU信息所需要引入的头文件
然后将其添加到DriverRecordSoundKit.podspec
文件中
s.frameworks = "AVFoundation", "Foundation", "Security","mach"
接着就报错了说是该系统库不存在
ld: framework not found mach
clang: error: linker command failed with exit code 1 (use -v to see invocation)
所以添加到DriverRecordSoundKit.podspec
文件中之前需要先去查找下看看该系统库是否存在,如果不存在说明其已经包含在其他系统库文件中了,这里mach
库包含在了Foundation
库中。
5、更新GitHub里面的库
依次执行下面命令
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git add .
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git commit -m "IOS司机端APP行驶全程录音框架"
// 添加tag标记
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git tag 1.0.0
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git push --tag
// 关联远程分支
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git remote add origin 'https://github.com/xiejiapei-creator/XJPCategoryKit'
// 得知分支名称为master
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git branch -a
* master
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git push origin master
验证podspec
文件是否有效。如果验证不通过,可以执行pod spec lint DriverRecordSoundKit.podspec --verbose
查看详细的ERROR
和WARING
提示,根据提示依次解决
pod spec lint DriverRecordSoundKit.podspec
检查错误的命令
pod spec lint DriverRecordSoundKit.podspec --verbose
修改后总是报错,清除缓存或直接删除重新执行就OK,因为使用pod repo push
的使用,pod
会从缓存中复制工程,然后再编译验证
pod cache list //查看缓存
pod cache clean --all //清除缓存
假如出现了无关痛痒的警告,可以直接忽略掉
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
- WARN | [iOS] xcodebuild: XJPCategoryKit/XJPCategoryKit/Classes/NSDate+Custom.m:70:67: warning: values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead [-Wformat]
xiejiapei@xiejiapeis-iMac XJPCategoryKit % pod spec lint XJPCategoryKit.podspec --allow-warnings
最后,终于出现了梦寐以求的成功符号!
Analyzed 1 podspec.
XJPCategoryKit.podspec passed validation.
更新版本之前要先删除远程库的tag
和本地的tag
// 删除本地tag
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git tag -d 1.0.0
Deleted tag '1.0.0' (was 9a60dca)
// 删除远程库tag
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % git push origin :refs/tags/1.0.0
否则会被拒绝更新
[!] Unable to accept duplicate entry for: XJPCategoryKit (0.1.0)
删除后更新tag
再提交就ok了
Downloading dependencies
Installing XJPCategoryKit 1.0.0 (was 0.1.0)
6、提交.podspec到CocoaPods
如果是第一次提交,需要先执行下面的命令去CocoaPods
注册(填写邮箱,收取验证链接,点击链接,就OK)
xiejiapei@xiejiapeis-iMac XJPCategoryKit % pod trunk register 2170928274@qq.com '谢佳培' --description='分类方法的库'
Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2
[!] Please verify the session by clicking the link in the verification email that has been sent to 2170928274@qq.com
然后再执行
pod trunk push DriverRecordSoundKit.podspec
[!] The spec did not pass validation, due to 3 warnings (but you can use `--allow-warnings` to ignore them).
如果出现警告的话则使用忽略警告的语法,执行然后大功告成!!!
xiejiapei@xiejiapeis-iMac XJPCategoryKit % pod trunk push XJPCategoryKit.podspec --allow-warnings
Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2
Updating spec repo `trunk`
CocoaPods 1.10.0 is available.
To update use: `gem install cocoapods`
For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.10.0
Validating podspec
🎉 Congrats
🚀 XJPCategoryKit (0.1.0) successfully published
📅 November 18th, 21:18
🌎 https://cocoapods.org/pods/XJPCategoryKit
👍 Tell your friends!
这时进入到远程仓库,发现我们没有显示我们提交的文件,而是有个警告框让我们审查一下提交的内容,究其原因是我们在远程仓库中出现了两个分支,一个main
分支,另外一个是master
分支,而我们目前正处于main
分支上,所以显示的内容还是之前的。
使用Sourcetree
工具来管理远程仓库
在Sourcetree
工具上从main
分支切换到master
分支,在远程仓库中不好进行这个操作,而在Sourcetree
工具中切换和合并分支的操作却很容易进行。
接下来在Sourcetree
工具上删除掉远程仓库中无用的main
分支,发现出错了
这是因为我们的远程仓库默认的分支仍然是main
分支,拒绝删除,所以需要到远程仓库中修改默认分支,修完完毕之后,不要忘记点击旁边的 update
按钮,update
一下才能生效。
之后就成功删除掉main
分支了,再回到github
的仓库首页看下,发现我们提交的库出来了,感到到哭😭,我做的第一个库完成了,一路坎坷都是泪。
在Github
上搜索发现也能够成功查找到了哈哈😄。
7、使用创建的库
a、安装框架
xiejiapei@xiejiapeis-iMac Example % pod install
Integrating client project
Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed.
b、导入框架
#import <XJPCategoryKit.h>
XJPCategoryKit.h
文件为公共入口文件,包括了以下头文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
//! Project version number for XJPCategoryKit.
FOUNDATION_EXPORT double XJPCategoryKitVersionNumber;
//! Project version string for XJPCategoryKit.
FOUNDATION_EXPORT const unsigned char XJPCategoryKitVersionString[];
#import "NSDate+Custom.h"
#import "NSObject+Custom.h"
#import "NSString+Custom.h"
#import "UIColor+Custom.h"
#import "UIImage+Custom.h"
#import "UILabel+Custom.h"
#import "UIScreen+Custom.h"
#import "UITextField+Custom.h"
#import "UIView+Custom.h"
#import "UIViewController+Custom.h"
c、使用框架
- (void)viewDidLoad
{
[super viewDidLoad];
// 判断一个字符串是否都是纯数字
NSString *testString = @"123456";
if ([testString judgeIsPureInt])
{
NSLog(@"该字符串为纯数字,说明生成的库可用");
}
}
输出结果为:
2020-11-19 15:08:54.798484+0800 XJPCategoryKit_Example[26855:668614] 该字符串为纯数字,说明生成的库可用
搞定!!!
8、创建过程遇到的问题
a、pattern did not match any file
- NOTE | [iOS] xcodebuild: DriverRecordSoundKit/DriverRecordSoundKit/RecordSoundKit.h:18:9: fatal error: 'lame.h' file not found
- NOTE | [iOS] xcodebuild: DriverRecordSoundKit/DriverRecordSoundKit/AudioTool.m:11:9: fatal error: 'RNCryptor iOS.h' file not found
- ERROR | [iOS] [DriverRecordSoundKit/SupportingFiles] file patterns: The `source_files` pattern did not match any file.
- ERROR | [iOS] file patterns: The `resources` pattern did not match any file.
- ERROR | [iOS] file patterns: The `vendored_libraries` pattern did not match any file.
因为路径设置有误所以找不到文件。我试验有效的解决方案就是设置模糊匹配:spec.source_files = 'DriverRecordSoundKit/**/*.{h,m}'
。你真要一个个去匹配,你会发现有时候即使你认为设置正确了,它也找不到.....
b、Prefix.pch
- ERROR | [iOS] unknown: Encountered an unknown error (No such file or directory @ rb_sysopen - /private/var/folders/2j/53b9tdz551l0x8mjtg3zhv4r0000gn/T/CocoaPods-Lint-20201117-15842-kud7vb-DriverRecordSoundKit/Pods/DriverRecordSoundKit/DriverRecordSoundKit/RNCryptor-Prefix.pch) during validation.
目前得出的结论,pch
在pod
库中,完全就是绊脚石般的存在,亲测无论你怎么玩,只要pch
存在,这个问题就会报。查看了很多第三方pod
,发现压根不使用pch
这玩意。每次error
后的note
也都是提示pch
里的import
文件not found
。总之pch
没有作用。
c、missing required architecture i386
- NOTE | [iOS] xcodebuild: ld: warning: ignoring file DriverRecordSoundKit/DriverRecordSoundKit/ConvertMP3/libmp3lame.a, missing required architecture i386 in file DriverRecordSoundKit/DriverRecordSoundKit/ConvertMP3/libmp3lame.a (4 slices)
这个就太坑了。眼看离胜利只剩最后一步,你给我报个啥玩意?遍查无解。分析这个错误,缺少了i386
架构的东西。查看一下这个框架支持哪些架构,发现确实没有 i386。
xiejiapei@xiejiapeis-iMac DriverRecordSoundKit % lipo -info /Users/xiejiapei/Desktop/DriverRecordSoundKit/DriverRecordSoundKit/SupportingFiles/libmp3lame.a
Architectures in the fat file: /Users/xiejiapei/Desktop/DriverRecordSoundKit/DriverRecordSoundKit/SupportingFiles/libmp3lame.a are: armv7 armv7s x86_64 arm64
查看这个框架的源文,发现做了个版本号的判断,低版本生成i386,高版本生成x86_64,所以这个答案是无解的。
PLATFORM="iPhoneSimulator"
if [ "$ARCH" = "x86_64" ]
then
SIMULATOR="-mios-simulator-version-min=7.0"
HOST=x86_64-apple-darwin
else
SIMULATOR="-mios-simulator-version-min=5.0"
HOST=i386-apple-darwin
fi
i386
x86_64
在网上找到一份支持i386的框架尝试了一下,发现的确出现了 i386 ,但是带入到项目后发现也是无效的,仍然报了之前的错误。不过它只是个警告,就不去管它了,之前以为是它影响到了linker command failed
才煞费苦心。
Architectures in the fat file: /Users/xiejiapei/Downloads/libmp3lame/libmp3lame.a are: armv6 armv7 i386 armv7s arm64
i386
d、Info.plist
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
plist
可以作为资源文件保存下来。
spec.resources = "DriverRecordSoundKit/**/*.{plist,modulemap}"
使用方式
NSString *filePath = [[NSBundle bundleForClass:[DriverRecord class]] pathForResource:@"Themes" ofType:@"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:filePath];
e、linker command failed
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- NOTE | [iOS] xcodebuild: clang: error: linker command failed with exit code 1 (use -v to see invocation)
[!] The spec did not pass validation, due to 1 error.
我遇到的玩命的错误,真的解答不出来。不过有几个心得。
1、.a
文件的存放位置需要放到Classes
文件夹下,放到其他地方不生效。
2、.a
文件放入后需要通过pod install
安装到项目中,然后再添加到此处
3、需要添加到DriverRecordSoundKit.podspec
文件中,语法比较诡异,你按照目录添加,它却说找不到,还是用模糊匹配吧。添加单个文件的话用的是s.ios.vendored_library
,而不是复数那个语法。
s.ios.vendored_library = 'DriverRecordSoundKit/Classes/**/*.a'
这个问题导致我无法上传录音库,等以后问到解决方案后再添加吧。
更新
需要把项目中遇到的各种系统库和第三方库全部分离出来进行添加,否则就会出现链接出错的问题。
s.vendored_libraries = 'DriverRecordSoundKit/Classes/**/*.a'
s.frameworks = "AVFoundation", "Foundation", "Security"
s.dependency 'RNCryptor-objc'
四、python3.7
1、安装 python3.7
- 网上下载
Python 3.7
Mac版的安装包,下载后一步步点击下一步进行安装。 - 在终端输入
open ~/.bash_profile
,在文件中添加以下语句配置环境。
export PATH=$PATH:/Library/Frameworks/Python.framework/Versions/3.7/bin/pip3.7
alias pip="/Library/Frameworks/Python.framework/Versions/3.7/bin/pip3.7"
alias python="/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7"
- 点击
save
进行保存,然后关闭弹出的文件。 - 在终端继续输入
source .bash_profile
加载刚才修改过的环境文件。 - 输入
python
查看是否安装成功以及版本号。
Python 3.7.9 (v3.7.9:13c94747c7, Aug 15 2020, 01:31:08)
Type "help", "copyright", "credits" or "license" for more information.
>>>
- 输入
exit()
退出版本号查询。 - 输入
help()
查询帮助命令,然后在其中输入module
查询已经安装好的模块,通过这个方式可以帮我们排除模块尚未安装的错误。当安装成功后还显示未安装,进入module
查询后发现已经存在了,则重启终端即可。
2、使用 python3.7
//运行文件
python3 mainServer.py
//安装缺失模块
pip3 install flask
网友评论