Create by xinyuan 2020/06/12

  • Preamble: We often create our own private libraries, however we often use a command linepod lib create ***, this article is a simple introduction to his part of the source code.

A simple understanding of the steps

  • 1. When we type at the terminalpod lib create ***After, this screen will appear
    Content of the terminal

    Normally we would just snap down and produce the file we want, that’s our normal routine, and when we pause and look at the prompt, we see that it has executed a clone. That’s right. He’s just downloading the remote code and doing a bunch of things.

Cloning`https://github.com/CocoaPods/pod-template.git` into `Demo`
Copy the code
  • 2. File directory structure

    File directory

    From this structure, the most important ones are the ones inside the setuprubyThe script. It’s only because he handles iOS, Swift, and Mac that there are so many scripts.

  • 3. Demo project

    The demo project

    The usual ones are simply modified using scripts from existing demo projects

Two, part of the code display

  • 1, TemplateConfigurator. Rb
# Here is a main method, mainly here to do the language distinction and which demo method to use. Messagebank.rb this file is mainly for some prompt processing classes printed on the terminal
def run
      @message_bank.welcome_message

      platform = self.ask_with_answers("What platform do you want to use?"["iOS"."macOS"]).to_sym
	  The script used to make the call is different because the code is different in different languages
      case platform
        when :macos
          ConfigureMacOSSwift.perform(configurator: self)
        when :ios
          framework = self.ask_with_answers("What language do you want to use?"["Swift"."ObjC"]).to_sym
          case framework
            when :swift
              ConfigureSwift.perform(configurator: self)
			  Perform (ConfigureIOS); perform (ConfigureIOS)
            when :objc
              ConfigureIOS.perform(configurator: self)
          end
      end.end
Copy the code
  • 2, ConfigureiOS. Rb
module Pod

  class ConfigureIOS
    attr_reader :configurator

    def self.perform(options)
      new(options).perform
    end

    def initialize(options)
      @configurator = options.fetch(:configurator)
    end

    def perform
	# Select some options, which will be displayed on the command line if we follow pod Lib create
      keep_demo = configurator.ask_with_answers("Would you like to include a demo application with your library"["Yes"."No"]).to_sym

      framework = configurator.ask_with_answers("Which testing frameworks will you use"["Specta"."Kiwi"."None"]).to_sym
      case framework
        when :specta
          configurator.add_pod_to_podfile "Specta"
          configurator.add_pod_to_podfile "Expecta"

          configurator.add_line_to_pch "@import Specta;"
          configurator.add_line_to_pch "@import Expecta;"

          configurator.set_test_framework("specta"."m"."ios")

        when :kiwi
          configurator.add_pod_to_podfile "Kiwi"
          configurator.add_line_to_pch "@import Kiwi;"
          configurator.set_test_framework("kiwi"."m"."ios")

        when :none
          configurator.set_test_framework("xctest"."m"."ios")
      end

      snapshots = configurator.ask_with_answers("Would you like to do view based testing"["Yes"."No"]).to_sym
      case snapshots
        when :yes
          configurator.add_pod_to_podfile "FBSnapshotTestCase"
          configurator.add_line_to_pch "@import FBSnapshotTestCase;"

          if keep_demo == :no
              puts " Putting demo application back in, you cannot do view tests without a host application."
              keep_demo = :yes
          end

          if framework == :specta
              configurator.add_pod_to_podfile "Expecta+Snapshots"
              configurator.add_line_to_pch "@import Expecta_Snapshots;"
          end
      end

      prefix = nil

      loop do
        prefix = configurator.ask("What is your class prefix").upcase

        if prefix.include? (' ')
          puts 'Your class prefix cannot contain spaces.'.red
        else
          break
        end
      end
	  
	  # Here, you need to use the project worker. rb file to modify the demo project. Here, we mainly tell part of the information passed, and then run convenient call.
      Pod::ProjectManipulator.new({
        :configurator => @configurator,
        :xcodeproj_path= >"templates/ios/Example/PROJECT.xcodeproj".:platform= >:ios.:remove_demo_project => (keep_demo == :no),
        :prefix => prefix
      }).run

      # There has to be a single file in the Classes dir
      # or a framework won't be created, which is now default
      `touch Pod/Classes/ReplaceMe.m`

      `mv ./templates/ios/* ./`

      # remove podspec for osx
      `rm ./NAME-osx.podspec`
    end
  end

end

Copy the code
  • 3, ProjectManipulator. Rb
# Here is mainly used xcodeProj component, modify xcode file, here should be the essence, here is involved in the use of XcodeProj.
def run
      @string_replacements = {
        "PROJECT_OWNER" => @configurator.user_name,
        "TODAYS_DATE" => @configurator.date,
        "TODAYS_YEAR" => @configurator.year,
        "PROJECT" => @configurator.pod_name,
        "CPD" => @prefix
      }
	  # This method is to get the project file, and then read and replace the contents of the file
      replace_internal_project_settings

      @project = Xcodeproj::Project.open(@xcodeproj_path)
	  Podspec, readme. md, LICENSE file
      add_podspec_metadata
	  # remove the demo project and rewrite the Podfile
      remove_demo_project if @remove_demo_target
      @project.save
	  For example, you can see that the following is the CPDAppDelegate class name in the demo. It would be nice if we could change this
	  # unless @remove_demo_target
      # # change app file prefixes
      # ["CPDAppDelegate.h", "CPDAppDelegate.m", "CPDViewController.h", "CPDViewController.m"].each do |file|
      # before = project_folder + "/PROJECT/" + file
      # next unless File.exists? before

      # after = project_folder + "/PROJECT/" + file.gsub("CPD", prefix)
      # File.rename before, after
      # end

      # # rename project related files
      # ["PROJECT-Info.plist", "PROJECT-Prefix.pch", "PROJECT.entitlements"].each do |file|
      # before = project_folder + "/PROJECT/" + file
      # next unless File.exists? before

      #     after = project_folder + "/PROJECT/" + file.gsub("PROJECT", @configurator.pod_name)
      # File.rename before, after
      # end
      # end
      rename_files
	  # Change the folder name
      rename_project_folder
    end
	# Here part of the detail code can try to run to see the implementation
Copy the code
  • 4, TemplateConfigurator. Rb
def run.After the project is processed, it will return to the TemplateConfigurator class to run some public methods
	  
	  # POD_LICENSE, pod_readme. md, name. podspec,.travis. Yml configuration changes, such as user NAME time, etc
      replace_variables_in_files
	  # Remove files that are not used after cloning "./**/.gitkeep", "configure", "_CONFIGURE.rb", "README.md", "LICENSE", "templates", "setup", "CODE_OF_CONDUCT.md"
      clean_template_files
	  # Replace readme. md, LICENSE, and new. Podspec
      rename_template_files
      add_pods_to_podfile
      customise_prefix
      rename_classes_folder
      ensure_carthage_compatibility
      reinitialize_git_repo
      run_pod_install

      @message_bank.farewell_message
    end
	# Here part of the detail code can try to run to see the implementation
Copy the code

Third, concluding remarks

Following this demo from Cocoapods, we should also be able to implement a script that will go through partial configuration and immediately produce a project with basic configuration. The main modification should be the projectproject.rb file. Since the demo project used by Cocoapods is of an older version, it should be noted that some variables still exist during the replacement process. For example, the scheme you see for the rename_files method in projectproject.rb is not currently available for new projects. It is also important to note that he is modifying the existing demo, not creating it.

scheme_path = project_folder + "/PROJECT.xcodeproj/xcshareddata/xcschemes/"
Copy the code