美文网首页iOS技术点iOS开发
IOS基础:Git与CocoaPods

IOS基础:Git与CocoaPods

作者: 时光啊混蛋_97boy | 来源:发表于2020-10-19 18:24 被阅读0次

    原创:知识点总结性文章
    创作不易,请珍惜,之后会持续更新,不断完善
    个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的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服务 器 ,其中选择 Remoteorigin/master
    • 派生与Git中的分支很像,可以把它理解为代码库级别的分支,把Fork代码库派生到当前账户下面了
    • 点击Transfer按钮,输入要转移的代码库和新的拥有者
    • 组织中会有管理员,他可以管理代码库,对代码库重新命名 、 删除和转移代码库等
    • 普通成员对代码库进行接受推送请求、合并推送
    c、图形界面辅助工具sourtree
    sourtree sourtree
    d、SSH密钥
    1. 查看是否已经有了ssh密钥:cd ~/.ssh,如果没有密钥则不会有此文件夹,有则备份后删除
    2. 生成密钥:按3个回车,密码为空。最后得到了两个文件:id_rsaid_rsa.pub
    3. 辅助串添加到GitHub中的git.lab框里
    4. 修改sourtreeSSH方式而不是HTTP
    SSH密钥
    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 之后,你会发现此处需要填写 AccountToken。其中 AccountGitHub 用户名,Token 则是一个特殊的许可,它允许 Xcode 使用你的 GitHub 帐号管理你的 Remote Repository 远程仓库。

    进入 GitHub 设置页面,点击右上角的「Generate new token」即可生成一串许可数字,将这串数字复制回到 Xcode 登录界面的 Token 文本框中,并点击「Sign In」登录即可完成 GitHub 帐号的设置。

    Generate New Token

    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
    1. 打开terminal (终端)
    2. 输入指令: cd '项目目录'
    3. 输入指令: vim .gitignore
    4. 把 附文代码copy到终端
    5. esc 键 ,输入指令:wq (指令意思:保存并返回上一层)
    6. 此时,可以输入指令sudo ls查看目录下是否存在gitignore,有则表示成功
    7. 如果之前没有提交过第三方到远端,则按照正常情况,commit一下再push到远端就完成了
    8. 如果之前提交过得话,则输入指令 git rm -r Pods,然后再comit,再push
    9. 重新clone一份这个项目到本地,你会发现这个项目中没有了Pods这个文件夹,运行项目也会报错。
    10. 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搜索

    cocoapod原理

    CocoaPods是帮我们管理第三方和自己的库,它本身也是一个.xcodeproj工程。只不过,它是专门管理第三方和自己的库的工程,而它的工作原理就是:你把.podspec文件制作好,然后trunk push 给它,它再把.podspec文件保存为.podspec.json文件放到GitHub,你需要的话,它通过这个.podspec.jsonGitHub上对应的开源库的文件下载下来,放到你的工程里。

    cocoapod原理

    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文件下的该文件马上会爆红表示不存在该文件了。

    XJPCategoryKit的工程目录

    有个小技巧,直接pod install就可以更新工程目录。

    DriverRecordSoundKit的工程目录

    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查看详细的ERRORWARING提示,根据提示依次解决

    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工具来管理远程仓库

    远程仓库的URL 克隆到Sourcetree

    Sourcetree工具上从main分支切换到master分支,在远程仓库中不好进行这个操作,而在Sourcetree工具中切换和合并分支的操作却很容易进行。

    从main切换到master分支

    接下来在Sourcetree工具上删除掉远程仓库中无用的main分支,发现出错了

    删除main分支出错

    这是因为我们的远程仓库默认的分支仍然是main分支,拒绝删除,所以需要到远程仓库中修改默认分支,修完完毕之后,不要忘记点击旁边的 update 按钮,update一下才能生效。

    修改默认分支为master

    之后就成功删除掉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.
    

    目前得出的结论,pchpod库中,完全就是绊脚石般的存在,亲测无论你怎么玩,只要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安装到项目中,然后再添加到此处

    添加.a文件

    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

    1. 网上下载Python 3.7Mac版的安装包,下载后一步步点击下一步进行安装。
    2. 在终端输入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"
    
    1. 点击save进行保存,然后关闭弹出的文件。
    2. 在终端继续输入source .bash_profile加载刚才修改过的环境文件。
    3. 输入python查看是否安装成功以及版本号。
    Python 3.7.9 (v3.7.9:13c94747c7, Aug 15 2020, 01:31:08) 
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    
    1. 输入exit()退出版本号查询。
    2. 输入help()查询帮助命令,然后在其中输入module查询已经安装好的模块,通过这个方式可以帮我们排除模块尚未安装的错误。当安装成功后还显示未安装,进入module查询后发现已经存在了,则重启终端即可。

    2、使用 python3.7

    //运行文件
    python3 mainServer.py
    
    //安装缺失模块
    pip3 install flask    
    

    参考文献

    iOS组件化方案与实践:创建cocoapod私有库详细步骤
    使用CocoaPods管理iOS库---制作pod篇

    相关文章

      网友评论

        本文标题:IOS基础:Git与CocoaPods

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