Link 1

Link 2

Link 3

Xcode engineering structure

Target

  • The smallest compilable unit in the Target project that specifies the product to compile, takes the source code as input based on Build Phases and Build Settings, and outputs the compiled output.

  • A project can contain one or more targets, and each target can produce a product.

  • A target and its resulting product can be associated with other targets.

Project-targets carrier

  • A Project is an independent Xcode Project that acts as a resource manager for one or more Targets. The resources a Project manages come from the Targets it contains.

  • The Project itself cannot be compiled, but it contains all the elements used to compile the Product and helps us organize the relationships between those elements.

  • The Project defines a default compilation option for included Targets. If Target has its own configuration, the Project default is overridden.

  • Projects can embed other projects as dependencies;

The Workspace – container

  • Workspace does not participate in any compilation linking process and is only used to manage Projects at the same level, typically containing multiple Projects

  • By default, projects in a workspace are compiled in the same workspace build directory, and files can be referenced to each other.

  • The Proejct file in the same Workspace is visible by default to other projects,

  • An Xcode Project can be included in multiple different Workspace because each Project has its own Identity, which defaults to Project Name.

Scheme

  • Scheme is an abstraction of the Build process that describes what Build Configurations Xcode should use, what tasks it performs, environment parameters, etc., to Build the Target we want.

  • There are six main processes in Scheme: Build, Run, Test, Profile, Analyze, and Archive. All of our operations on Target are included, and each procedure can be configured separately.

CocoaPods

CocoaPods takes advantage of Xcode’s project structure by introducing pods. project as an intermediate layer, transferring all the Pods dependencies from the main project to Pods.project, and finally transferring Pod. project as the main project dependencies.

1. The Pod command

pod install

  • Use this command the first time a project adds or deletes aPod from cocoaPods or Podfile.

  • Running Pod Install for the first time generates the podfile.lock file, along with the.xcworkspace and Pods directories.

  • When you run Pod Install to download and install a new pod, it writes the installed version for each pod in the podfile. lock file, which tracks and locks the installed version of each pod.

  • Run Pod Install, which resolves only the pod dependency libraries not listed in podfile.lock.

pod outdated

  • View the status and packages of all references to current and latest versions of third parties in the current projectInclude existing versions of podfile.lock

pod update

  • When pod update PODNAME is specified, CocoaPods will try to find the latest POD version of PODNAME and ignore existing versions in podfile. lock

  • If you do not specify a pod library, the CocoaPods will update all the pods in your Podfile to the latest version.

pod repo update

Update pod resource directory (master). Simply put, if a third party library releases the latest version, if you do not perform pod repo update, your local directory will not know that the latest version is available, and you will always rely on your local resource directory, and you will never get the latest version of the library.

The default pod repo update, however, is a pod repo update that pulls the latest remote directory and updates the POD again based on the resources in the directory.

So if you don’t need to update the remote source, you need to execute pod repo update –no-repo-update

pod repo

Delete if there are trunk sources

pod repo remove trunk
Copy the code

View the local source POD Repo List

artsy
- Type: git (master)
- URL:  https://github.com/Artsy/Specs.git
- Path: /Users/wangpengfei/.cocoapods/repos/artsy

cocoapods
- Type: git (master)
- URL:  https://github.com/CocoaPods/Specs.git
- Path: /Users/wangpengfei/.cocoapods/repos/cocoapods

maste
- Type: git (master)
- URL:  https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git
- Path: /Users/wangpengfei/.cocoapods/repos/maste

trunk
- Type: CDN
- URL:  https://cdn.cocoapods.org/
- Path: /Users/wangpengfei/.cocoapods/repos/trunk

4 repos
Copy the code

pod env

View the pod environment information

1. Stack CocoaPods: 1.10.1 Ruby: Ruby 2.6.3 P62 (2019-04-16 Revision 67580) [universal.x86_64-darwin20] 3.0.3 Host: macOS 11.0.1 (20B50) Xcode: 12.4 (12D4e) . / System/Library/Frameworks/Ruby framework Versions / 2.6 / usr/lib/Repositories: artsy - git - https://github.com/Artsy/Specs.git @ 55b2a0e46468586d3d93cd77a78dfe12684aca54 cocoapods - git - https://github.com/CocoaPods/Specs.git @ 11fa1b295dbb4a90f4d66d6a5eedb9afb1b96b5e maste - git - https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git @ a0abf73604cb65bd66eb158d5aac5bc3366927b5 trunk - CDN - https://cdn.cocoapods.org/ 2. Installation Source Executable Path: /usr/local/bin/plugins: 1.0.4 Plugins: 1.0.0 cocoapods-deintegrate: 1.0.0 cocoapods-stats: 1.1.0 cocoapods-trunk: 1.5.0 cocoapods-try: 1.2.0Copy the code

2. Podfile

Vim text editor

Open podFile --> Open podfile vim podfile --> Create podfile and use vim to write :w --> Save :w! --> Forcibly save :q --> Exit :q! --> Save and exit :wq --> save and exit :x --> save and exitCopy the code

Podfile writing

Simple notation
Target 'EWDemo' pod 'YYModel' pod 'AFNetworking', '~> 4.0.1'Copy the code
longhand
# below two lines indicate the dependent libraries is the source address of the source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/Artsy/Specs.git # Ios, version 9.0 :ios, '9.0' # Ignore all warnings (good news for ocD) # Inhibit_all_warnings! # MyAppTests # OCMock Target 'MyApp' do pod 'AFNetworking', '~> 3.0' target 'MyAppTests' do inherit! :search_paths pod 'OCMock', '~> 2.0.1' end end # But the generated project has not written to disk "to perform the operation. When post_install do | installer | installer. Pods_project. The targets. Each do | target | puts "#{target.name}" end endCopy the code

Pod specifies project dependencies

The dependency specification is a combination of the name of the Pod and an optional version.

pod 'YYModel' 
Copy the code

If you want a version of a specific dependent library, you need to write the specific version number behind it

Pod 'Objection', '0.9'Copy the code

Specify a version range if necessary

> 0.1 Any version later than 0.1 (excluding 0.1) >= 0.1 Any version later than 0.1 (including 0.1) < 0.1 Any version earlier than 0.1 (excluding 0.1) <= 0.1 Any version earlier than 0.1 (including 0.1) ~> 0.1.2 version 0.1.2 to 0.2, excluding 0.2.Copy the code

Build configuraton Compiles the configuration

By default, dependencies are installed in build Configuration for all targets. Dependencies can only be enabled in a given Build Configuration for debugging or other reasons. The following notation indicates that configuration is enabled only in Debug and Beta mode

pod 'PonyDebugger', :configuration => 'Debug'
Copy the code

or

pod 'PonyDebugger', :configurations => ['Debug', 'Beta']

Copy the code

SubSpecs

Normally we’ll use the name of the dependency library to import it, and cocoapods will install all the content of the dependency library by default. We can also specify to install a submodule of a specific dependent library.

# install pod 'QueryKit/Attribute' from the QueryKit library :subspecs => ['Attribute', 'QuerySet']Copy the code

Using local files

If we want to import one of our local libraries, we can specify the dependency library address as follows

pod 'AFNetworking', :path => '~/Documents/AFNetworking'
Copy the code

Using external files

Podspecs can be imported from the address of another source library

pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
Copy the code

target

Define the pod target (the target in the Xcode project) and specify the scope of dependencies within the given block. By default, target contains dependencies defined outside the block, unless you specify that inherit is not used! To inherit (referring to inheritance in nested blocks)

  • A single target
target 'ZipApp' do 
  pod 'SSZipArchive'
end
Copy the code
  • MyApp only introduces the AFNetworking library. MyAppTests also inherits the AFNetworking library from MyApp when it introduces OCMock
Target 'MyApp' do pod ', '~> 3.0' target 'MyAppTests' do inherit! :search_paths pod 'OCMock', '~> 2.0.1' end endCopy the code
  • A target block contains multiple nested subblocks
Target 'ShowsApp' do # ShowsApp only introduces ShowsKit pod 'ShowsKit' # ShowTVAuth Target 'ShowsTV' do pod 'ShowTVAuth' end # introduces Specta and Expecta as well as ShowsKit target 'ShowsTests' do inherit! :search_paths pod 'Specta' pod 'Expecta' end endCopy the code
Abstract target

Define a new abstract target that can be easily used for target dependency inheritance

  • Simple notation
abstract_target 'Networking' do

    pod 'AlamoFire' 
    
    target 'Networking App 1' 
    target 'Networking App 2'
    
end
Copy the code
  • Define an Abstract_target that contains multiple targets
# note: ShowsKit abstract_target 'Shows' do pod 'ShowsKit' # ShowsiOS Target 'ShowsiOS' do pod 'ShowWebAuth' end # ShowsTV Target 'ShowTVAuth' do pod 'ShowTVAuth' end # ShowsTests Target introduces the Specta and Expecta libraries ShowsKit target 'ShowsTests' do inherit! :search_paths pod 'Specta' pod 'Expecta' end endCopy the code
abstract! And inherit!

abstract! Indicates that the current Target is abstract and therefore does not directly link Xcode Target Inherit to set the current Target inheritance mode

  • The :complete target inherits all actions from the parent node.
  • The: None target does not inherit any behavior from its parent node.
  • The :search_paths target inherits only the search paths of the parent class.
target 'App' do
    target 'AppTests' do
       inherit! search_paths
    
    end
end

Copy the code

Target Configuration

platform

Platform Specifies the platform for which the statement library should be created. The default platform version configuration provided by CocoaPods.

IOS ->4.3 OS X->10.6 tvOS->9.0 watchOS->2.0 If the platform and version are specified, platform: iOS, '4.0' platform: iOSCopy the code
project

If no project is specified, the project specified by target’s parent target is used as the target by default. If neither target specifies the target, the project in the same directory as Podefile is used.

It is also possible to specify whether these Settings take effect in release or debug mode. To do this, you must specify a name associated with :release/:debuge

Target 'MyGPSApp' do project 'FastGPS'... Target 'MyNotesApp' do project 'FastNotes' can only be referenced in the FastNotes project... Project' TestProject', 'Mac App Store' => :release, 'Test' => :debugCopy the code
inheib_all_warnings!

inhibit_all_warnings! Mask all warnings from cocoapods dependent libraries. It can be defined globally, within a sub-target, or specify a library:

# Hide SSZipArchive warnings without hiding ShowTVAuth warnings Pod 'SSZipArchive', :inhibit_warnings => true pod 'ShowTVAuth', :inhibit_warnings => falseCopy the code
user_frameworks!

By specifying use_frameworks! Require that you generate a framework rather than a static library. If you use use_frameworks! This command will generate Frameworks that depend on libraries in the Frameworks directory of the Pods project if use_frameworks is not used! The command will generate a static library of.a in the Products directory under the Pods project

Workspace

By default, we don’t need to specify it, just use the same project name as the Podfile directory. If you want to specify a different name than the project name, you can do so

Source

Source is the source of the specified POD. If you do not specify source, CocoaPods official source is used by default. (Default Settings are recommended)

# CocoaPods Master Repository using other source address source 'https://github.com/artsy/Specs.git' official # using the default address (the default) source 'https://github.com/CocoaPods/Specs.git'Copy the code

Add the master source

cd ~/.cocoapods/repos pod repo remove master git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git The master adds the following to the first line of the project's Podfile (or automatically without pod update) :  source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'Copy the code

def

You can declare a Pod collection by using the def command

def 'CustomPods'
   pod 'IQKeyboardManagerSwift'
end 
Copy the code

It can then be introduced at the targget where it needs to be introduced

target 'MyTarget' do
    customPods
end 
Copy the code

3. Podspec file

Specification describes a version of the Pod library that includes details about where to get the source code, what files to use, build Settings to apply, and other common metadata such as name, version, and description

3.1 create Podspec

  • pod lib create name

Create a component library from the Github template, and the resulting file contains a Podspec file that has a lot of content.

  • pod spec create name

Create a Podspec template file directly.

Pod: : Spec. New do | Spec # | - - - - - the Spec Metadata -- --, Spec. Name = "EWDemo # library name" Spec. Version = "0.0.1" # version Spec. The summary Description = << -desc DESC spec.homepage = "http://EXAMPLE/EWDemo" # homepage URL # -- Spec License -- Spec. License = "MIT" # License # Spec. License = {:type => "MIT", :file => "FILE_LICENSE"} # -- Author Metadata -- "[email protected]" } # spec.authors = { "wangpengfei" => "[email protected]" } # spec.social_media_url = "Https://twitter.com/wangpengfei" # -- -- -- Platform Specifics -- - # spec. Platform = : ios # spec. Platform = : ios, "5.0" # When using multiple platforms # spec.ios. Deployment_target = "5.0" # spec.osx.deployment_target = "10.7" # Spec.watchos. deployment_target = "2.0" # spec.tvos.deployment_target = "9.0" # -- Source Location -- # Retrieves the Location of the repository spec.source = { :git => "http://EXAMPLE/EWDemo.git", : tag = > "# {spec. Version}}" = = = = = = = = = = = = = = = = = = = = = = = = = = = = line = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # -- -- -- - the Source Code -- -- - # # For source files # giving a folder will include any swift, h, m, mm, c & cpp files. # For header files it will include any header in the folder. # Not including the public_header_files will  make all headers public. spec.source_files = "Classes", "Classes / / *. * * {h, m}" spec. Exclude_files = "Classes/Exclude" # spec. Public_header_files = "Classes / / *. * * h" # -- -- -- - Resources -- # # A list of Resources included with the Pod. These are copied into the # target bundle with A build phase script. Anything else will be cleaned. # You can preserve files from being cleaned, please don't preserve # non-essential files like tests, examples and documentation. # spec.resource = "icon.png" # spec.resources = "Resources/*.png" # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" = = = = = = = = = = = = = = = = = = = = = = = = = = = = line = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # - - - - - Project Linking - - - - - # Frameworks = "SomeFramework" # spec. Frameworks = "SomeFramework" # spec. Frameworks = "SomeFramework" Library = "iconv" # spec.libraries = "iconv", "Xml2" # -- Project Settings -- # # spec. Requires_arc = true # spec. Xcconfig = {"HEADER_SEARCH_PATHS" => $(SDKROOT)/usr/include/libxml2"} # spec.dependency "JSONKit", "~> 1.4" endCopy the code

3.2 the File patterns

  • Local private library configuration
Pod: : Spec. New do | Spec | basic Settings Spec. / / local private library name = "EWCom" Spec. Version = "0.0.1" Spec. The summary = "this is a test briefly" Spec. Homepage =  "https://github.com/WFregister/TestDemo" spec.author = { "wangfei" => "[email protected]" } spec.source = { :git => "", :tag => "#{spec.version}"} # frame resource path: the path can point to a remote code base, or to a local project: Git => "XXXX", :tag => "1.0.0"} Source_files = 'EWCom/**/*.{h,m}' end {:path => 'EWCom',} // The local private library must set at least one resource # file flat folder and allCopy the code
  • Match all files
-c * matches all files starting with C - * C matches all files ending with C -c matches all files containing C (including beginning and end) spec.source_files = 'Classes/**/*.{h,m}' spec.source_files = 'Classes/**/*.{h,m}', 'More_Classes/**/*.{h,m}'Copy the code
  • The source file to include
Public_header_files File schema column spec.public_header_files = 'Headers/Public/*.h' private_header_files is used to mark the list of private file schemas spec.private_header_files = 'Headers/Private/*.h'Copy the code
  • resource_bundels

In order to build Pod as a static library, it is strongly recommended to use this property to manage resource files because name conflicts can occur using the Resources property


spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }

spec.resource_bundles = {
    'MapBox' => ['MapView/Map/Resources/*.png'],
    'MapBoxOtherResources' => ['MapView/Map/OtherResources/*.png']
  }

Copy the code
  • resources

To build Pod as a static library, the official recommendation is to use resource_bundle because name conflicts can occur using the resources property.

spec.resource = 'Resources/HockeySDK.bundle'
spec.resources = ['Images/*.png', 'Sounds/*']
Copy the code

3.3 Loading resource Files

When not using use_frameworks!

3.3.1 use the resource
spec.resource  = spec.resource = 'EWCom/Resource/*'
Copy the code

View product Bundle content, image resources are directly in the main Bundle,

UIImage *iamge = [UIImage imageNamed:@"yin.jpg"];
Copy the code

Or create a bundle directly in the project. You can find the corresponding bundle directory by passing in the class type

- (UIImage*)getImageWithClass:(id)obj{NSBundle *bundle = [NSBundle bundleForClass:[obj class]]; NSURL *bundleURL = [bundle URLForResource:@"EWCom" withExtension:@"bundle"]; NSBundle *resourceBundle = [NSBundle bundleWithURL:bundleURL]; NSInteger scale = [UIScreen mainScreen] scale]; // Full path NSString *path = [NSString stringWithFormat:@"%@%zdx.png",name,scale]; UIImage *image = [UIImage imageWithContentsOfFile:[bundle pathForResource:imgName ofType:nil]; return image; }Copy the code
3.3.2 rainfall distribution on 10-12 use resource_bundles
  spec.resource_bundles  = {'EWCom' => 'EWCom/Resource/*'}
Copy the code

View the product Bundle content. Image resources are packaged into bundles and placed under the main Bundle

Image loading mode

- (UIImage*)getImageWithName:(NSString*)name{NSURL *associateBundleURL = [NSBundle mainBundle] URLForResource:@"EWCom" withExtension:@"bundle"]; NSBundle *bundle = [NSBundle bundleWithURL:associateBundleURL]; NSInteger scale = [UIScreen mainScreen] scale]; // Full path NSString *imgName = [NSString stringWithFormat:@"%@%zdx.png",name,scale]; UIImage *image = [UIImage imageWithContentsOfFile:[bundle pathForResource:imgName ofType:nil]; return image; }Copy the code