Podfile中涉及的Ruby基本语法
背景
最近在适配 XCode11.3时经常需要改Podfile,但是仅仅停留在依样画葫芦的阶段,只知道形式,不知道为什么要这么写,于是简单研究一下 Podfile 涉及的语法。
Podfile 的本质是什么
Podfile 其实是简写的 Ruby 代码,Cocoapods从Podfile读取数据,然后使用 eval 直接将文件中的内容当做 Ruby 代码来执行,安装对应的三方库和一些配置的操作
Podfile
在这用我们工程中的 Podfile 举例,解释一下具体内容
project 'jayanzi.xcodeproj'
platform :ios, '9.3'
inhibit_all_warnings!
post_install do |installer|
# 需要指定编译版本的第三方的名称
myTargets = ['RxASDataSources']
installer.pods_project.targets.each do |target|
if myTargets.include? target.name
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.0'
end
end
end
end
# Pod 私有库
source 'https://github.com/Eaffy/react-native-specs.git'
target ‘jayanzi' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'Then'
pod 'UMCCommon', '~> 2.1.1'
pod 'UMCSecurityPlugins'
pod 'UMCAnalytics'
pod 'RNReanimated', :git => 'https://github.com/software-mansion/react-native-reanimated.git'
target 'jayanziTests' do
inherit! :search_paths
# Pods for testing
end
target ‘jayanziUITests' do
inherit! :search_paths
# Pods for testing
end
end
Ruby 语法
在开始解析前,先介绍几个必备的 Ruby 语法
- 井号#后表示注释
- 数据类型
Number: 239
String: "apple"
Bool: true false
Symbols: :name #(包含前边的:)可以简单理解成不变的字符串
Hash: {:name => “JaYanZi”} #字典
Array: [1, 2, 3] #元素可以不同类型 [1, “two”, :three, {:name => 4 }]
- 赋值不需要类型声明
name = "JaYanZi"
- 命名规范
常量: 全部大写CONST_VAR
变量: 小写字母apple
class module
: 首字母大写 驼峰
方法名:小写字母开头,可以移? = !结尾 - 变量
类变量@@name
实例变量@name
普通变量name
全局变量$name
- 字符串插值
“hi, #{name}”
- 条件语句
if conditional [then]
code
elsif conditional [then]# 比 elseif 少个 e
code
else
code
end
case expr0
when expr1, expr2 [then]
code
when expr3 [then]
code
else
code
end
- 方法
class Apple
# 类方法
def Apple.name
“apple”
end
# 实例方法
def color
“red”
end
end
-
Ruby 的简写
i. 方法调用的最外层可以省略
ii. 函数的最后一行代码默认是返回值
iii. Hash最外层的{}可以省略(如果是最后一个参数,除去 block)
iV. block 简写
Apples.all.map { |apple| apple.name }
等价于
Apples.all.map{ &:name }
- 双冒号:: 表示 class 的常量或命名空间
class Fruit
class Apple
COLOR = ‘red’
end
end
Apple::COLOR
Fruit::Apple
- do end 基本上等于{}
示例代码解析
project
project 'jayanzi.xcodeproj'
Ruby 中方法调用可以省略小括号,这行代码实际上是一个函数调用,相当于
project('jayanzi.xcodeproj')
翻查源码,project 这个函数定义在 dsl.rb 中。
def project(path, build_configurations = {})
current_target_definition.user_project_path = path
current_target_definition.build_configurations = build_configurations
end
同样的
platform :ios, '9.3'
调用platform(name, target = nil)
,:ios 是一个 Symbols 类型的参数
inhibit_all_warnings!
调用inhibit_all_warnings!
,其中!是函数名的一部分,调用省去了小括号
source 'https://github.com/Eaffy/react-native-specs.git'
调用source(source)
,source 类型为[String]
post_install
post_install do |installer|
# 需要指定编译版本的第三方的名称
myTargets = ['RxASDataSources']
installer.pods_project.targets.each do |target|
if myTargets.include? target.name
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.0'
end
end
end
end
同样是调用了函数
def post_install(&block)
raise Informative, 'Specifying multiple `post_install` hooks is unsupported.' if @post_install_callback
@post_install_callback = block
end
该函数允许你用代码修改生成 Xcode,block 会回调一个Pod::Installer,也就是使用中的installer。
target
target ‘jayanzi' do
...
end
调用了def target(name, options = nil)
,name的值为'jayanzi',option为默认值,do...end 相当于{},do...end 中间的为 block,该函数通过block_given?获得 block,执行其中的代码。
pod
pod 'Then'
pod 'UMCCommon', '~> 2.1.1'
pod 'RNReanimated', :git => 'https://github.com/software-mansion/react-native-reanimated.git'
调用def pod(name = nil, *requirements)
,第一个参数是依赖的名,Ruby 中,假如最后一个参数,名字前面带星号 *,就表示可以传递不定参数。个数也可以不定。
pod 'RNReanimated', :git => 'https://github.com/software-mansion/react-native-reanimated.git'
第二个参数实际上是一个 hash,由于是最后一个参数,可以省略{},完整的应该为
pod('RNReanimated', {:git => 'https://github.com/software-mansion/react-native-reanimated.git'})