系统: Mac OS 10.15.2, XCode 11.3,swift 5.0
写作时间:2019-12-23

1. 说明

开发iOS App,基本上没有从零开始构建。因为系统以及提供了很多Framework,比如UIKit, Foundation, WebKit,MapKit等,GitHub上也有很多开源的Framework,Alamofire, Kingfisher等。

动态库与静态库的区别。

  1. Static library - 代码在编译时链接linked, 以后就不会再发生变化.

但是, iOS static libraries不允许包含images/assets (只有代码). 曲线救国的方式是,用一个bundle去加入images/assets .

  1. Dynamic library - 代码或者assets在运行时runtime才链接 linked,也就是里面的内容会发生变化.

但是, 只有Apple官方才允许为iOS创建dynamic libraries. 如果你的项目有动态库,则App会审核失败.

  1. Framework - 编译后的代码实现一个任务… 所以Framework, 可以包含字符串,图片资源文件,storyboard,static frameworkdynamic framework, 或者其它Framework, 并且可以分版本管理.(iOS 8以后允许创建)

此文创建的Framework依赖了第三方的Framework,比如Alamofire。
从零开始创建没有依赖的Framework请参考 – 创建CocoaPods的Framework Swift组件化之路(上)

2. 工程代码下载

https://github.com/zgpeace/IceCreamShopFramework
这里包含

  1. 开始的项目: IceCreamShop_Starter
  2. 完成的项目: IceCreamShop_Finisher
  3. Framework: Libraries/RWPickFlavor

3. 创建Framework

File > new > project > Framework & Library > Framework

下一步, Product Name写为RWPickFlavor, 保存到新建的Libraries文件夹里面

新建Podfile文件

cd ~/yourProjectPath/Libraries/RWPickFlavor
pod init
open -a Xcode Podfile

Podfile内容填充如下

platform :ios, '12.0'target 'RWPickFlavor' dopod 'Alamofire', '~> 4.7'pod 'MBProgressHUD', '~> 1.1.0', :modular_headers => true
end

这样子组件就有了第三方Framework的依赖Alamofire
MBProgressHUD

4. Swift Static Library

4.1 CocoaPods版本小于1.5.0, CocoaPods不能使用static libraries. 如果pod包含了Swift代码,需要在Podfile中标注 use_frameworks!. CocoaPods 在1.5.0以后, CocoaPods就可以用静态库static libraries!

如果在Podfile省略了use_frameworks! , CocoaPods 将用静态库static libraries代替Framework. 你的 Objective-C依赖需要以module的方式集成寄来, 但是. MBProgressHUDObjective-C 不支持modules的依赖. 幸运的是, 在MBProgressHUD依赖的后面,增加脚本 :modular_headers => true, CocoaPods 会添加 module支持.

4.2 pod安装依赖库

pod install

4.3 打开新工程

open RWPickflavor.xcworkspace

XCode打开的工程视图

4.4 从工程IceCreamShop-Stater拷贝下面5个文件夹到RWPickflavor Framework里面。(文件夹:Categories, Controllers, Models, Views
, Resources)

RWPickflavor在文件夹下显示如下:

4.5 接着,打开工程RWPickFlavor.xcworkspace,选择File ▸ Add Files to “RWPickFlavor”… 把新加的5个文件夹加入到工程,显示如下:

4.6 打开RWPickFlavor中的Images.xcassets, 删除 AppIconlogo images。

4.7 工程RWPickFlavor xcworkspace, 需要确认Main.storyboard中的对象链接是正确的. 确认下面3个对象的链接:

  1. Choose Your Flavor
  2. Ice Cream View
  3. Pick Flavor Data Source

    因为拷贝storyboard到不同的工程project, 你需要确认上面的对象的Module都设置为CocoaPod的工程RWPickFlavor. 记得保存Command-S.

5. 工程IceCreamShop-Stater移除多余文件

  1. 在文件夹中IceCreamShop-Stater打开工程IceCreamShop.xcworkspace, 删除下面4个文件夹
  • Categories
  • Controllers
  • Models
  • Views
  1. 打开Info.plist文件,找到分组Supporting Files group, 删除行Main storyboard file base name

  2. 打开工程中中的Images.xcassets, 删除 background images。

  3. 运行工程,显示的是一个黑屏。

创建Pod的最困难的部分已经完成!恭喜!

6. 创建Github仓库

  1. 创建一个新的仓库给Framework用

    仓库名字为RWPickFlavor,笔者新建的仓库链接如下:
    https://github.com/zgpeace/RWPickFlavor

  2. 新建另一个仓库给Podspec用,名字命名为RWPodSpecs,并勾选初始化README。 CocoaPods要求pod specs repo至少有一个提交,否则不工作.
    链接如下:
    https://github.com/zgpeace/RWPodSpecs

7. 设置Podspec

如果没有Podspec, RWPickFlavor 只是一堆文件. PodspecCocoaPod的描述信息. Podspec包括pod的名字,版本,Git下载地址URL.

你需要为RWPickFlavor创建创建RWPickFlavor.podspec. 执行如下命令:

cd ~/yourProjectPath/Libraries/RWPickFlavor
pod spec create RWPickFlavor
open -a Xcode RWPickFlavor.podspec

RWPickFlavor.podspec里面的内容,替换为:

Pod::Spec.new do |s|# 1
s.platform = :ios
s.ios.deployment_target = '12.0'
s.name = "RWPickFlavor"
s.summary = "RWPickFlavor lets a user select an ice cream flavor."
s.requires_arc = true# 2
s.version = "0.1.0"# 3
s.license = { :type => "MIT", :file => "LICENSE" }# 4 - Replace with your name and e-mail address
s.author = { "Keegan Rush" => "keeganrush@gmail.com" }# 5 - Replace this URL with your own GitHub page's URL (from the address bar)
s.homepage = "https://github.com/TheCodedSelf/RWPickFlavor"# 6 - Replace this URL with your own Git URL from "Quick Setup"
s.source = { :git => "https://github.com/TheCodedSelf/RWPickFlavor.git", :tag => "#{s.version}" }# 7
s.framework = "UIKit"
s.dependency 'Alamofire', '~> 4.7'
s.dependency 'MBProgressHUD', '~> 1.1.0'# 8
s.source_files = "RWPickFlavor/**/*.{swift}"# 9
s.resources = "RWPickFlavor/**/*.{png,jpeg,jpg,storyboard,xib,xcassets}"# 10
s.swift_version = "4.2"end

8. 创建许可证License

像其它pod, 你需要创建LICENSE许可证文件.

比如拷贝MIT License 的内容, 并保存为文件名为LICENSE — 没有扩展名 — 到路径~/yourProjectPath/Libraries/RWPickFlavor. 比替换内容里面的年份[year] 和 名字[fullname] !

Choose a License 这是一个特别好的网站,帮助你如何选择一个适合你的开源open-source license.

9. 推送到Git

把Pod推送到远程git,替换掉 [Your RWPickFlavor Git URL]为你的git地址(比如笔者的https://github.com/zgpeace/RWPickFlavor).

cd ~/Documents/Libraries/RWPickFlavor
git init
git add .
git commit -m "Initial commit"
git tag 0.1.0
git remote add origin [Your RWPickFlavor Git URL]
git push -u origin master --tags

恭喜你,完成了你的第一个有依赖的Framework。

Last one more thing…

10. 应用你新建的CocoaPod

首先需要把你的Podspec增加到私有仓库private specs repo; 这个让CocoaPods找到你安装的pod. 幸运的是, 你已经创建了为Podspec创建了Git 仓库.

在RWPickFlavor路径下,输入一下命令。替换掉[Your RWPodSpecs Git URL]为你的Podspec的路径(比如笔者的为:https://github.com/zgpeace/RWPodSpecs):

pod repo add RWPodSpecs [Your RWPodSpecs Git URL]
pod repo push RWPodSpecs RWPickFlavor.podspec

上面标示创建了本地的RWPodSpecs 保存在你机器的路径~/.cocoapods, 并把RWPickFlavor.podspec推送到了里面.

最后在Starter的工程里面,替换掉Podfile的内容如下:

platform :ios, '12.0'source 'https://github.com/CocoaPods/Specs.git'
source '[Your RWPodSpecs Git URL Goes Here]'target 'IceCreamShop' dopod 'RWPickFlavor', '~> 0.1.0'pod 'MBProgressHUD', '~> 1.1.0', :modular_headers => true
end

确保替换掉[Your RWPodSpecs Git URL Goes Here] 为你的RWPodSpecs的Git地址(比如笔者的为:https://github.com/zgpeace/RWPodSpecs). 你不需要包含AlamofirePodfile, 以为依赖以及配置好在RWPickFlavor.podspec. 你需要增加一行给MBProgressHUD,这样子可以增加配置信息:modular_headers => .

运行

pod install

替换掉AppDelegate.swift的内容如下:

import UIKit
import RWPickFlavor@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {// MARK: Instance Variablesvar window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {window = UIWindow(frame: UIScreen.main.bounds)window?.rootViewController = createRootViewController()window?.makeKeyAndVisible()return true}func createRootViewController() -> UIViewController {let bundle = Bundle(for: PickFlavorViewController.self)let storyboard = UIStoryboard(name: "Main", bundle: bundle)return storyboard.instantiateInitialViewController() ?? UIViewController()}}

运行的时候发现错误,重复的Images.xcassets, XCode 10 以后不能有重复的内容,要不删掉项目的,或者File > Workspace Setting > Build System > Legacy Build System.

最终运行起来:

参考

https://www.raywenderlich.com/5823-how-to-create-a-cocoapod-in-swift

https://stackoverflow.com/questions/15331056/library-static-dynamic-or-framework-project-inside-another-project

https://www.vadimbulavin.com/static-dynamic-frameworks-and-libraries/

https://stackoverflow.com/questions/50718018/xcode-10-error-multiple-commands-produce

创建CocoaPods的Framework Swift组件化之路(下)相关推荐

  1. 百度App Objective-C/Swift 组件化混编之路(一)

    作者丨郭金.陈佳 来源丨百度App技术 一. 背景 1.1 Swift 发展历史 2010 年 7 月,克里斯(Chris Lattner)开始设计 Swift.完成基础架构后,克里斯带领开发小组陆续 ...

  2. 百度App Objective-C/Swift 组件化混编之路(二)- 工程化

    作者丨张渝.郭金 来源丨百度App技术 前文<百度App Objective-C/Swift 组件化混编之路>已经介绍了百度App 引入 Swift 的影响面评估以及落地的实施步骤,本文主 ...

  3. swift 组件化_打造完备的iOS组件化方案:如何面向接口进行模块解耦?

    作者 | 黑超熊猫zuik,一个修行中的 iOS 开发,喜欢搞点别人没搞过的东西,钻研过逆向工程.VIPER 架构和组件化. 关于组件化的探讨已经有不少了,在之前的文章 iOS VIPER架构实践(三 ...

  4. android国籍组件,android组件化之路

    问题:实际业务变化快,而工程内各个功能模块耦合度太高,不能对功能模块进行快速方便地拆分或组装.团队共同开发中,可能一个文件同时被多人修改,导致每次更新提交代码都需要消耗大量时间去merge代码.每次修 ...

  5. 组件化之路 - ViewModel一知半解

    新的一年,优先把欠账补齐,关于Jetpack下Lifecycle.ViewModel.LiveData组件库,以及ViewModel+LiveData项目实践,如今也只差ViewModel还没有记录了 ...

  6. 蘑菇街App的组件化之路·续

    原文:http://limboy.me/ios/2016/03/14/mgj-components-continued.html 蘑菇街 App 的组件化之路·续 前几天在「移动学习分享群」分享了关于 ...

  7. swift 组件化_京东商城订单模块基于 Swift 的改造方案与实践

    ABI Stability & Module Stability 以及Swift优势 2019年Swift 5发布,标志这门语言迎来了一个重大的里程碑.与之前的版本相比除了一些基础语法的改变, ...

  8. 单文件组件的组件传值_移动端组件化架构(下)

    我的组件化方案 对于项目架构来说,一定要建立于业务之上来设计架构.不同的项目业务不同,组件化方案的设计也会不同,应该设计最适合公司业务的架构. 架构设计 以我之前公司项目为例,项目是一个地图导航应用, ...

  9. 【超强干货】蘑菇街App的组件化之路

    本文为『移动前线』群在3月10日的分享总结整理而成,转载请注明来自『移动开发前线』公众号. 嘉宾介绍 蘑菇街李忠(花名银时,网名 limboy),多年客户端开发经验,目前主要负责移动端基础架构设计及核 ...

  10. 蘑菇街 App 的组件化之路

    在组件化之前,蘑菇街 App 的代码都是在一个工程里开发的,在人比较少,业务发展不是很快的时候,这样是比较合适的,能一定程度地保证开发效率. 慢慢地代码量多了起来,开发人员也多了起来,业务发展也快了起 ...

最新文章

  1. 物联网技术概论的课程编号_课程 物联网应用实战 7月班仅剩3个席位
  2. python五十一:动态导入模块,通过字符串导入模块
  3. Python中随机森林的实现与解释
  4. git submoule 更新_微软Surface Duo双屏手机键盘更新:支持分体式输入
  5. python慢在哪里_求大神分析一下我的python脚本慢在哪里?
  6. write up杂项:想蹭网先解开密码
  7. emq auth mysql_EMQ X 认证鉴权(一)——基于 MySQL 的 MQTT 连接认证
  8. bat 两个文本字符替换_Excel中最全最实用的文本函数公式大全
  9. 互联网岗位介绍和成长
  10. JDBC 与ODBC的区别
  11. sp_help 查看表结构 alter column修改字段长度
  12. 硬件厂商 Linux社区 代码,Linux企业版需加强的10个方面
  13. qj71c24n通讯实例_通信模块QJ71C24N应用篇手册三菱QJ71C24N用户手册 - 广州凌控
  14. protoc安装配置
  15. 暗影精灵3 PLUS 安装黑苹果
  16. python调用virustota接口api实现上传文件返回查毒结果
  17. [渝粤教育] 徐州工业职业技术学院 药物分离技术 参考 资料
  18. linux上的两种可执行程序
  19. ISO三体系,招投标企业认证最多的资质
  20. 对一个数组排序之后求相邻数的最大差值

热门文章

  1. linux查看端口出现unix,linux查看端口被占用状况
  2. 第一个Maven工程的目录结构和文件内容及联网问题
  3. 常量、变量;基本数据类型;input()、if、while、break、continue
  4. Linux 配置mail发送邮件
  5. 广东电网公司大数据平台初步建成
  6. 图文混排的几种实现方案
  7. 三目运算符?:结合性
  8. OPNFV发布首个版本Arno
  9. MOTO 360连接手机新手图文教程
  10. php网页制作头部和尾部,用phpcms如何将静态页面制作成企业网站,头部加尾部