CocoaPods introduction

CocoaPods is a dependency management tool for developing third-party libraries for OS X and iOS applications. With CocoaPods, you can define your own dependencies (called Pods), and it’s easy to version third-party libraries over time and throughout your development environment.

The idea behind CocoaPods falls into two main categories. First, there is a lot involved in introducing third-party code into a project. For beginning Objective-C developers, the configuration of project files can be frustrating. There are a number of human errors that can occur when configuring build Phases and Linker Flags. CocoaPods simplifies this by automatically configuring compilation options.

Second, you can easily find new third-party libraries through CocoaPods. Of course, this does not mean that you can simply throw together an application from libraries provided by others. What it does is it allows you to find libraries that are really good to use to shorten our development cycles and improve the quality of our software.

Core components

CocoaPods is written in Ruby and consists of several Ruby packages (gems). The most important gems in parsing integration are: (Yes, CocoaPods is a dependency management tool — built with dependency management!) .

CocoaPods is an ObjC dependency management tool, which itself is built using Ruby’s dependency management gems.

CocoaPods/CocoaPod This is a user-facing component that is activated whenever a POD command is executed. This component includes all of the functionality involved in using CocoaPods, and can also perform tasks by calling all of the other Gems.

The Core component provides support for processing files associated with CocoaPods, mainly podfiles and Podspecs.

The gem component CocoaPods/Xcodeproj is responsible for the integration of all project files. It can create and modify.xcodeProj and.xcworkspace files. It can also be used as a separate gem package. If you want to write a script that can easily modify a project file, you can use this gem.

Ruby overview

Ruby’s syntax is expressive and flexible enough to quickly implement your needs. Here are some Ruby features related to CocoaPods.

methods

The easy way

def method_name (var1=value1, var2=value2)
  expr..
end
Copy the code

Methods in Ruby start with ‘def’ and end with ‘end’. We can set default values for arguments, and use the default values if the method is called without passing the required arguments, such as value1 and value2 in the above example.

Ruby code can omit parentheses when calling methods.

Variable number of arguments

def sample (*test)
  puts "The number of arguments is #{test.length}"
  for i in0... test.length puts#{test[I]}
  end
end
sample "Zara"."6"."F"
Copy the code

The output of the above example is:

The parameter number is 3. The parameter value is Zara. The parameter value is 6Copy the code

Data type –Hash

A Hash is a set of key-value pairs like “key” => “value”. A Hash is similar to an array, except that its index (or “key”) is not limited to numbers. The index of a Hash can be almost any object.

Hash is similar to arrays, but with one important difference: the elements of a Hash are in no particular order. If order is important, use arrays.

pod 'SwViewCapture', :git=>'[email protected]:startry/SwViewCapture.git', :branch=>'master'
Copy the code
def pod(name = nil, *requirements)
  unless name
	raise StandardError, 'A dependency requires a name.'
  end

  current_target_definition.store_pod(name, *requirements)
end
Copy the code

The argument that follows the pod method is a Hash object, written as a key-value

{
  ":git": "[email protected]:startry/SwViewCapture.git".":branch": "'master'"
}
Copy the code

block

Ruby’s support for the functional programming paradigm is through blocks. Blocks in Ruby are also objects, and all blocks are instances of Proc classes, that is, all blocks can be passed as arguments and returned.

Construct a method to pass a block argument

def target(name, &proc)
  definition = TargetDefinition.new(name, parent)
  proc.call() if proc
end
Copy the code

In addition to declaring a block argument passed in as an argument, you can use the yield keyword in Ruby to represent a call block.

Yield is primarily used for implicit block callbacks. Ruby methods may not declare a block by default, but may use yield callbacks internally. Yield will call an external block, block_given? Used to determine whether the current method passed a block.

def target(name)
  definition = TargetDefinition.new(name, parent)
  yield if block_given?
end
Copy the code

The part between do and end in Ruby is called a block, which can also be written as {.. }

So the target method can be called like this:

target('PodSample') {
  pod('SDWebImage'.'~ > 4.4.2')}Copy the code

It can also be called using our usual form:

target('PodSample') do
  pod('SDWebImage'.'~ > 4.4.2')
end
Copy the code

eval

The final feature is Eval, which dates back decades to Lisp. Eval blurs the boundary between code and data. Eval is also used in iOS development to execute JAVASCRIPT code.

 eval "1 plus 2 times 3"= > 7Copy the code

When we perform podfile-related operations, such as the common install and Update operations, we use Eval to execute the “code” in the Podfile in context.

Podfile&Podfile. Lock the parsing

Podfile

After introducing ruby’s language features, you should have no problem understanding podfiles.

CocoaPods internally defines configuration methods that convert method parameters into properties of internal Hash variables.

def source(url)
    $hash_value['source'] = url
end

def target(target)
    $hash_value['target'] = target
end

def pod(pod)
    pods = $hash_value['pods']
    pods = [] if pods == nil
    pods << pod
    $hash_value['pods'] = pods
end
Copy the code

Here’s what happens when CocoaPods parses podfiles.

Executing eval(Podfile.content) generates an object of the Podfile class, which has two important properties:

  1. One is Hashinternal_HashSave some global configuration, such assource.workspace.
  2. The other one isTargetDefinitionOf the classroot_target_definitionsObject,TargetDefinitionClasses have connections between parent and children, throughroot_target_definitionsThe Podfile object can iterate through all declared filestargetObject,targetThe object holds all arguments to the block passed to the target method.

Podfile.lock

The podfile. lock file is written in the data description language YAML(YAML Ain’t Markup). YAML(YAML Ain’t Markup) is a compact, data-centric, non-markup language that uses whitespace, indentation, and lines to organize data, making presentation concise and readable. Internally, CocoaPods hashes podfile. lock files for querying parameter data and comparing them to the parameters in Podfile files.

Cocoapods supports both Ruby podfiles and YAML podfiles.

PODS:
  - AFNetworking (3.1.0) :
    - AFNetworking/NSURLSession (= 3.1. 0)
    - AFNetworking/Reachability (= 3.1. 0)

DEPENDENCIES:
  - AFNetworking (= 3.1. 0)

SPEC REPOS:
  https://github.com/cocoapods/specs.git:
    - AFNetworking

SPEC CHECKSUMS:
  AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67

PODFILE CHECKSUM: a06ca71d7960a7bf4f294d3ad147e0e67528a467

COCOAPODS: 1.53.
Copy the code
{
    "PODS":[
        {
            "AFNetworking (3.1.0)": ["AFNetworking/NSURLSession (= 3.1.0)"."AFNetworking/Reachability (= 3.1.0)"]}],"DEPENDENCIES": ["AFNetworking (= 3.1.0)"]."SPEC REPOS": {"https://github.com/cocoapods/specs.git": ["AFNetworking"]},"SPEC CHECKSUMS": {"AFNetworking":"5e0e199f73d8626b11e79750991f5d173d1f8b67"
    },
    "PODFILE CHECKSUM":"a06ca71d7960a7bf4f294d3ad147e0e67528a467"."COCOAPODS":"1.5.3"
}
Copy the code

In general, ruby podfile parsing is all about calling methods to convert various parameter configurations to Hash data, which is much easier to convert in YAML form, which itself is key-value data.

What does CocoaPods do? Pod Install and POD Update