Series of articles:OC Basic principle series.OC Basic knowledge series.Swift bottom exploration series.IOS Advanced advanced series

preface

Recently to optimize the project, incidentally write some of the daily development will be used in the middle and advanced development skills. This article covers the following three topics: multi-environment configuration, Mach-O and linker, and Symbol.

Multi-environment Configuration

When it comes to multi-environment configuration, let’s talk about a few conceptsHere’s what’s in the red box:

  • 1.Project: contains all the code, resource files, and information of the Project.
  • 2.Target: The specific build of the specified code and resource files.
  • 3.Scheme: Configures the environment for the specified Target.

We create the project, the project defaultsTwo environments: Debug and ReleaseWe’ll have it during developmentTwo or more server environments.Each environment has a different addressRough writing is as follows:There are only two environments.Can'tTo adapt toMany environmentalBelow, we introduce several multi-environment configuration methods

Targets Configures multiple environments

  • 1. We can create multiple Targets in Targets

At this point, we just copy a Target, no new code is generated, even if we copy a set of configuration, run without error

  • 2. Let’s change the Bundle Id

  • 3. Modify the info. plist file

After these modifications, you’ll find that there areTwo items can be selected, respectively, you will find that there areTwo App

Through this we can configure different ICONS to be distinguished

  • 4. Set the macro

We canAccording to project SettingsSelf correspondingThe macro Once configured, you can use it in your project

conclusion

This multi-environment configuration has several disadvantages:

  • 1. Will existMultiple info.plist files
  • 2. More environmentThe configuration will be messy

Here’s a better way to do it

Configurations Multiple environment Configurations

We know that in Scheme we can choose the environmentThat can add a new environment, add the following location:

It corresponds one to one with Scheme above

If you look at Scheme after the addition, you will see that there is an added Test[Question] :Every time we run the project, we have to switch the environment in the Scheme above, which is very inconvenient, so what is the solution to this problem

  • 1. Create a Scheme

  • 2. Click + in the lower left corner to create the desired environment name

  • 3. After you close the page and look at the project, you will see that you have created the environment

  • 4. Associate the Scheme and Configurations that you create

  • 5. Bind to the server environment
    • 1. Create user-defined in the Build Settings of the project and name it HOST_URL

    • 2. Configure different urls for different HOST_URL environments

    • 3. The configuration is performed in info.plist and is nearly exposed

    • 4. Use it in projects

    • 5. Verify

conclusion

However, this method is still not perfect, because the project needs to use Cocoapods to manage the third party. In this case, it is quite tedious to use the above method to set the Build Settings. Is there a way to centrally manage the Build Settings? Here’s another way to do it

.xcConfig Multi-environment configuration

The initial xcconfig.

In the use ofCocoapods manages third partiesIn fact, it isManage through the.xcconfig fileCreate cocoapods wellautomaticHelp us according to circumstancesGenerate the.xcconfig file

The contents of the. Xcconfig file exist in key-value format. The Key Value is on the left of ‘=’ and the Value Value is on the right

In the projectDifferent environmentandDifferent.xcconfig bindings

Configure your own.xcconfig file

  • 1. Create a Config file and create an. Xcconfig file in the file

Note the naming rules: folder name of the.xcconfig file + project name +. Name of the environment

  • 2. Configure the created. Xcconfig file based on the project environment

Using xcconfig.

We also want to set different request addresses for different environments, which can be set in.xcconfig

  • 1. Create and set the. Xcconfig content

  • 2. Set the PList file

  • 3. Use in the project

  • 4. Verify

conclusion

This setup is a bit simpler than the one above, but there’s more to the.xcConfig file. Let’s extend it

. Xcconfig extension

We introduced it aboveSimple configuration URL.. Xcconfig fileCan beTo configure the Build SettingsThe inside of thecontentFor example, we usuallyConfigure dynamic libraries, static librariesIs configured toOther Link FlagsThrough the.xcconfigWe canDirect configurationFor example, we configure AFN

  • 1. Write the following code in. Xcconfig

  • 2. Build and check it outOther Link FlagsFind that the write has been configured

And we know from the above operation,Build SettingsAll of theconfigurationCan beThrough xcconfig.A filemanagement. Let’s explain the contents of.xcconfig:OTHER_LDFLAGS is an abbreviation in Build SettingsWhat are the abbreviations for other Settings?

Recommended address:Xcode Build Settings

On the left is the corresponding Build Settings Key name and on the right is the corresponding abbreviation

Let’s say we want to configureHeader Search Paths“, then Search for “Header Search Paths” on the web page.HEADER_SEARCH_PATHS We’re going to configure it in.xcconfigLet’s Build the project

. Xcconfig conflict

Problem a

Our project will be approvedCocoapods manages third partiesWhen I first introduced dot xcconfig, I saidpodsWill automatically help usGenerate the.xcconfig fileThat will be in the project at this pointFour. Xccongig files We found thatAn environmentonlyConfigure an.xcconfig fileSo what can we do to make itSelf-written and Pods-generated works?

  • Testc is to be updated by adding a Podfile

Found a warning, warning means that CocoaPods are set but you have set other.xcconfig files in the project, so the.xcconfig files for Pods will not take effect, we need to resolve this conflict

  • There is one keyincludeIt can introduce other files to makeThe imported file takes effect

The error above shows the.xcconfig path generated by the Pods:”Target Support Files/Pods-TestOC/Pods-TestOC.debug.xcconfig“, we import into our.xcconfig file

  • An error occurs when the project is run

An error was reported that the.xcconfig generated by Pods could not be found. We looked at the.xcconfig file generated by Pods and found that its root directory was Pods

Therefore, change the path to the following:

Run the project again and you’ll be fine

  • Checking to see if the Pods send a warning

We found that Debug mode no longer generates warnings, but Release will also generate warnings because our.xcconfig under Release is not configured

Question 2

We seeXcconfig generated by PodsThere will beOTHER_LDFLAGS, weI wrote it myself. XcconfigIn theThere is also a OTHER_LDFLAGSLet’s go back to the projectOther Link FlagsAnd found thatPodsThe generatedXcconfig does not take effect“So how do we make what we write and what our Pods produce work?

  • useinheritedTo inheritance

  • Run the project

  • validation

Let’s delete AFN and call it in VC

conclusion

We configure the project through.xcConfig, and we can manage it through.xcConfig +Scheme, which saves both time and trouble

Mach-o and the linker

The Mach – O first

Mach-o (Mach Object) is the file format for storing programs and libraries in macOS, iOS, and iPadOS. The system uses the Application Binary Interface (ABI) to run files in this format.

The Mach-O format is used to replace the A.out format of BSD systems. The Mach-O file format preserves machine code and data generated during compilation and linking, thus providing a single file format for statically linked and dynamically linked code.

Find the Mach-O file for your project

When we run the project, the project will generate an.app fileWhen we find the.app file, we’ll display the package contents, and we’ll have an executable file insideOur executable file call process is roughly as follows:

  • 1. CallforkFunction to create aprocess
  • 2. CallexecveOr its derivatives, which are loaded on that process and execute ourMach-OFile when we callexecve(program loader), the kernel is actually doing the following:
    • 1. Load the file to the memory
    • 2. Start analyzingMach-OIn themach_headerTo confirm that it is validMach-Ofile

Analyze the Mach-O file

There are two ways to view an executable:

  • 1. ByMachOViewThat’s what we call rotten apples
  • 2. Run the following command:objdump --macho --private-headers

Macho = macho + binary = macho + binary = mach-o

  • Why is the entry to the project main

Because the project entry is already specified in Mach-O

The red box is the designated entrance, and we can also change the designated entrance to achieve the purpose of changing the entrance

We can still get throughMach-OYou can see someLoad system-dependent libraries We found thisThe file shows a lot of things that you don't needWe need to simplify it a little bitMach-o is a read-write file, soYou can write a file that reads Mach-OCome,Remove the unnecessary(How to write the following article in the said)

Let’s read the above mach-O file again using the read Mach-O file we wrote

It was found that a lot of things were missing, and this proved once again that Mach-O was readable and writable

The linker

The nature of links

In the project, the.o file (also known as the object file) is generated during compilation, as shown below:

An object file is a file that puts the code that we’re writing in the right place, the global variables that we’re writing, the code that we’re writing, the global symbols that we’re writing, and they’re sorted according to different features during compilation.

There can be multiple. O files in a project, and the essence of linking is to combine multiple object files into a single file.

See the sign

A project with many.m and.h files will generate many.O files during compilation, so can we change the information exposed to the outside world during merging?

To answer this question, we need to look at the symbol table. Here are a few concepts:

  • 1.Symbol Table is used to store symbols.
  • 2.String Table: is the name used to hold the symbol.
  • 3.I have an Indirect Symbol Table. Save the external symbols used. To be more precise, use the external dynamic library notation. Is a subset of Symbol Table.

Creating a Debug Demo

We first set up a project, so that the symbol information to be printed can be directly displayed in the terminal, which is convenient for us to debug later. This first involves private keys and redirects

  • We are nowBuild PhasescreateRun ScriptThis will print information at run time

  • The new terminal

The red box identifies the terminal, type tty, and it will print something like a link, and this is the location of the terminal

  • Then we copy the above information intoRun ScriptOn the print, yesPrint the address for redirection

The code means that the printed message is redirected to the terminal

  • Compile the code

You can see that the terminal prints the information that we just entered

Question 1: How to make Xcode line the code we need

  • And that’s where we’re going to use what we talked about earlier. Xcconfig fileTake urls as an example

  • changesRun Scriptinstruction

  • Compile the code

The address that we configured on the.xcconfig is printed out

Print from a script

  • Have a script written here (see article on how to write scripts below), post the important parts

This script needs three arguments: CMD, CMD_FLAG, TTY, and we need to assign values to these three arguments in.xcconfig

  • Assign in.xcconfig

-pa in CMD_FLAG means: -p means no sorting, and -a means display all symbols, including debugging symbols

  • To change theRun ScriptCommand to execute the script we wrote

SRCROOT: indicates the current code path

  • Once configured, compile

I found it printed

  • Optimize and rewrite the.xcconfig content

Running it again will still be successful

Wrote last

The article is more fine, write more tired, may not write so fine! Scripting will be covered in the middle of this article, and scripting syntax will be discussed later. This part of the article will be used in the actual development, the article is not finished, the next article will continue to talk about this part. I hope we can communicate more and make progress together