Xcode -- create your own Framework, xcodeframework

Source: Internet
Author: User

Xcode -- create your own Framework, xcodeframework

(Note: The following content is based on Xcode7.2.1. The versions are different and the interface content may be different !)

If you want to share your developed controls with others, you can directly provide source code files. However, this method is not very elegant. It exposes all the implementation details, and these implementations may not be open-source. In addition, developers may not want to see all your code, because they may just want to implant part of your beautiful Code into their own applications.

Another method is to compile your code into a static library and add other developers to your project. However, it is inconvenient to publish all public header files.

You need a simple method to compile your code. This method should make your code easy to share and reuse in multiple projects. What you need is a way to package your static library and put all the header files in one unit, so that you can immediately add them to your project and use them.

Fortunately, this is the problem to be solved in this tutorial. You will learn how to create and use the Framework to solve this headache. OS X perfectly supports this because Xcode provides a project template that contains default Build targets and files that can accommodate resources such as images, sounds, and fonts. You can create a Framework for iOS, but this is a complicated manual activity. If you follow the tutorial, you will learn how to step through the roadblock and complete the creation of the Framework smoothly.

What is Framework?

Framework is a collection of resources. It includes the static library and its header file into a structure, allowing Xcode to easily include it into your project.

On OS X, a dynamic link framework may be created. Through dynamic connection, the framework can be updated without application reconnection. During runtime, a copy of the code in the library is shared and can be used throughout the project. Therefore, this reduces memory consumption and improves system performance. As you can see, this is a powerful feature.

On iOS, you cannot add custom frameworks to the system in this way. Therefore, the only dynamic-link framework is provided by Apple.

Create a static library project

Open Xcode, click File-New-Project, and select iOS-Framework and Library-Cocoa Touch Static Library to create a Static Library Project.

Name the project as the static database name you want to create (I will name it with ZYResource), and save the project to an empty directory.

A static library project consists of header files and implementation files, which are compiled into the library itself.

To facilitate other developers to use your library and framework, you will perform some operations so that they only need to import a header file to access all the classes you want to publish.

When you create a static library project, Xcode automatically adds ZYResource. h and ZYResource. m. You do not need to implement the file, so right-click ZYResource. m and choose delete to delete it to the waste bin.

Import the header file of UIKit, which is required to create a library. When you create different composition classes, you will add them to this file to ensure that they can be obtained by the database users.

The project you build depends on UIKit. However, the static library project of Xcode is not automatically connected to UIKit. To solve this problem, you must add the UIKit as the dependent Library to the project.

In the project navigation bar, select the project name, and then select the ZYResource target in the central panel.

Click BuildPhases, expand the Link Binary with Libraries section, click + to add a new framework, find UIKit. framework, and click add.

Open ZYResource. h and replace all content:

Next, you need to add a new phase in the build column to include all the header files and place them somewhere the compiler can get them. Then, you will copy these to your framework.

On the Build Phases page of Xcode, select Editor-Add Build Phase-Add Headers Build Phase.

Note: If you find that the menu items found above are gray (not clickable), click the white area of the Build Phases interface below to get the focus of Xcode applications, and then try again.

Drag ZYResource. h from the project navigation bar to the Public section under Headers of the central panel. This step ensures that any user using your library can obtain this header file.

Note: Obviously, all header files contained in your public header files must be made public, which is very important. Otherwise, the developer will get a compilation error when using your library.

If Xcode cannot read the header file you forgot to set as public when reading the public header file, it is so frustrating.

Now that you have set up your project, it is time to add some features to your library. The key of this tutorial is to teach you how to create a framework,

Instead of building a UI control, drag the file to be imported into the Framework from the Finder to the project directory under Xcode.

Select Copy items info needed and click the selection box below to ensure that the ZYResource static library target is selected.

By default, this step adds the implementation file to the compilation list and the header file to the Project Group. This means they are currently private

Note: The names of the three groups may confuse you. Public is what you expect, and header files under Private can still be exposed,

Therefore, the name may be misleading. The irony is that the header file under the Project is "private" for your Project. Therefore, you will want more header files or Public files, or under the Project.

Now, you need to share the control header file (here I use UICombox. h). There are several ways to achieve this. First, drag the header file from the Project column to the Public column on the Headers panel.

Alternatively, you may find that the simpler method is to edit the file and change the Membership under the Target membership panel. This option is more convenient, allowing you to add files and expand your library.

Note: If you are constantly adding new classes to the library, remember to update the relationship between these classes (membership) in time to make as few classes as possible public, make sure that other non-public header files are under the Project.

In addition, do not include images in the dragged files or folders. The static library does not contain images, and the images must be processed later.

Another thing you need to do for the header file of your control is to add it to the master header file ZYResource. h of the library.

With the help of this header file, developers only need to import a header file to use your library, Just like you use UIKit, just import <UIKit/UIKit. h>, instead of selecting an imported part as needed.

Configure Build Settings

It is very close to building this project and creating a static library. However, some configurations must be implemented first to make our database more user-friendly.

First, you need to provide a directory name to indicate where you will store the copied public header file. This ensures that you can locate the header file when using the static library.

In the project navigation bar, click the project name, select the ZYResource static library target, select the Build Setting column, and search for the public header,

Double-click Public Headers Folder Path. In the displayed view, type the following content: include/$ (PROJECT_NAME)

You will see this directory later.

Now you need to change some other settings, especially those that are left behind in the binary library. The Compiler provides you with an option,

To eliminate Invalid code: code that will never be executed. Of course, you can also remove some debug symbols, such as some function names or other debug-related details.

Because you are creating a framework for others to use, it is best to disable these functions (Invalid code and debug symbols ),

This allows you to select a part that is advantageous to your project. As before, use the search box to change the following settings:

  • Dead Code Stripping is set to NO

  • Strip Debug Symbol During Copy is set to NO (in my current version, the default value is NO. You only need to confirm it once)

  • Set Strip Style to Non-Global Symbols

Compile and run, so far there is nothing to see, but it is good to ensure that the project can be successfully built without errors and alarms.

Select the target iOS Device and press command + B to compile. Once the compilation succeeds, the libZYResource. a file in the Product directory in the project navigation bar will change from red to black,

Indicates that the file already exists. Right-click libZYResource. a and choose Show in Finder.

In this directory, you will see the static library, libZYResource. a, and other directories you specified for the header file. Note that, as you expected, the header files set as public can be seen here.

Create a Dependent Development Project

It is extremely difficult to develop a UI control library for iOS without being able to see the real results, which is a problem we are facing now.

No one expects you to open a UI control with your eyes closed, so you will create a new Xcode project in this part, which depends on the library you just created.

This means that you can use the sample app to create a framework. Of course, this part of code will be completely separated from the library itself, and the structure will be very clear.

Select File-Close Project to Close the previous static library Project, and use File-New-Project to create a New Project,

Select iOS-Application-Single View Application, name the new project ZTResource, and save the project to the same directory as the previous ZYResource.

Add the ZYResource dependency library and drag ZYResource. xcodeproj from the Finder to the ZTResource group in Xcode.

Now you can navigate to the library project in your project, which is very good, because it means you can edit the code in the library, run the sample project to test your changes.

Note: you cannot open the same project in two Xcode windows at the same time. If you find that you cannot navigate to the library project in your project, check whether the library project is opened in other Xcode windows.

Now, you will add a static library as the dependent library of the Instance project:

  • Select ZTResource in the project navigation bar.

  • Navigate to the Build Phases panel under the ZTResource target.

  • Open the Target Dependencies panel and click + to bring up the selector.

  • Find the ZYResource static library and click Add. This step indicates that when building an application, Xcode will check whether the static library needs to be rebuilt.

To connect to the static library itself, expand the Link Binary With Libraries panel and click the + button again,

Select libZYResource. a from the Workspace group and click Add.

This step ensures that Xcode can connect to the static library, just like connecting to the system framework (such as UIKit.

The advantage of using nested projects like this is that you can modify the library itself without leaving the sample project, even if you change the code in both places.

Each time you compile a project, you must check whether the public/project relationship of the header file is set correctly. If any header file is missing from the instance project, it cannot be compiled.

Create a Framework

Up to now, you may not be able to wait for your toes to figure out when the framework can come out. Understandable,

Because you have done a lot of work so far, but you have never seen the framework.

Now it's time to change. You haven't created a framework yet,

It is because the framework itself is a static library with a set of header files-in fact, it is exactly what you have created.

Of course, the framework also has the following differences:

  1. Directory structure. Framework has a special directory structure that can be recognized by Xcode. You will create a build task to create this structure for you.

  2. Segment (Slice ). So far, when you build a database, you only need to consider the structure (architecture) currently required ). For example, i386 and arm7. To make a framework more useful, the framework needs to construct this structure for each framework running. In a moment, you will create a new project, construct all the required structures, and include them in the framework.

This part is amazing, but we will come slowly. In fact, it is not as complex as it looks.

Framework Structure

A framework has a special directory structure that looks like this:

Now you need to add a script to create this structure during the static library construction process. In the project navigation bar, select ZYResource and then select the static library target of ZYResource,

Select the Build Phases column and select Editor-Add Build Phase-Add Run Script Build Phase to Add a new Script.

This step adds a new panel in the build phases section, which allows you to run a Bash script during build. When do you want the script to be executed during build,

Drag the panel to the corresponding position in the list. For this framework project, the script is executed at the end, so you can keep it in the default position.

Double-click the panel title bar Run Script and rename it to Build Framework.

Paste the following Bash script code in the script text box.

12345678910111213141516 set -e  export FRAMEWORK_LOCN="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework"  # Create the path to the real Headers diemkdir -p "${FRAMEWORK_LOCN}/Versions/A/Headers"  # Create the required symlinks/bin/ln -sfh A "${FRAMEWORK_LOCN}/Versions/Current"/bin/ln -sfh Versions/Current/Headers "${FRAMEWORK_LOCN}/Headers"/bin/ln -sfh "Versions/Current/${PRODUCT_NAME}" \             "${FRAMEWORK_LOCN}/${PRODUCT_NAME}"  # Copy the public headers into the framework/bin/cp -a "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/" \           "${FRAMEWORK_LOCN}/Versions/A/Headers"

This script first creates the ZYResource. framework-Versions-A-Headers directory, and then creates three connection symbols (symbolic links) required by the framework ).

  • Versions-Current =>

  • Headers => Versions-Current-Headers

  • ZYResource => Versions-Current-ZYResource

Finally, copy the public header file from the path of the Public header file you have defined to the Versions-A-Headers directory,

-The a parameter ensures that the number of modifiers is not changed as part of the copy, and prevents unnecessary re-compilation.

Now, select ZYResource static library scheme, select iOS Device build target, and then use cmd + B to build.

Right-click libZYResource. a static library in the Products directory of the ZYResource project, and select Show in Finder again.

In this build directory, You can see ZYResource. framework. You can confirm that the correct directory structure is displayed here:

This is a big step in completing your framework. However, you will notice that there is no static lib file. This is what we will solve next.

Multi-Architecture Compilation

IOS apps need to run in many different CPU architectures:

  • Arm7: used on the oldest device that supports iOS7

  • Arm7s: Used on iPhone 5 and 5C

  • Arm64: running on iPhone 5S 64-bit ARM processor

  • I386: Used on 32-bit Simulators

  • X86_64: 64 is used on the simulator.

Each CPU architecture requires different binary data. When you compile an application, Xcode will correctly compile the application based on the corresponding architecture no matter which architecture you are currently using.

For example, if you want to run on a virtual machine, Xcode only compiles i386 (or x86_64 ).

This means that the compilation will be performed as quickly as possible. When you archive an app or build the release mode of the app, Xcode will build the above three ARM architectures for the real machine.

Therefore, the app can run on all devices. But what about other compilation architectures?

When you create your framework, you naturally want all developers to run it on all possible architectures, right? Of course you want to, because you can get respect and praise from your peers.

Therefore, you need to compile Xcode in all architectures. This process actually creates a binary FAT (File Allocation Table, File configuration Table), which contains all the fragments of the Architecture (slice ).

Note: another reason for creating a sample project dependent on the static library is actually emphasized here: the Library is compiled only under the architecture required for running the sample project,

It is only possible to re-Compile when there is a change. Why is this so exciting? Because the development cycle will be shortened as much as possible.

Here we will use a new target in the ZYResource project to build the framework. In the project navigation bar, select ZYResource

Find Other-Aggregate and click Next to name the target Framework.

Note: Why use the Aggregate object to create a framework? Why is this not straightforward? Because OS X provides better database support, in fact,

Xcode directly provides a Cocoa Framework compilation target for each OS X Project. Based on this, you will use the set compilation target as the connection string of the Bash script to create a magic framework directory structure.

To ensure that the static Link Library is compiled whenever the new framework target is created, you need to add dependencies to the static library target ).

In the library project, select the Framework target and add a dependency to Build Phases. Expand the Target Dependencies panel and click + to select the ZYResource static library.

The main Compilation part of this goal is multi-platform compilation. You will use a script to achieve this. As you did before, under the Framework target,

Select the Build Phases column and click Editor-Add Build Phase-Add Run Script Build Phase to create a new Run Script Build Phase.

Double-click Run Script to rename the Script Name. This time it is named MultiPlatform Build.

Paste the following Bash script code in the script text box:

1234567891011 set -e  # If we're already inside this script then dieif [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then  exit 0fiexport RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1  RW_FRAMEWORK_NAME=${PROJECT_NAME}RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a"RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework"
  • Set-e ensures that the execution of the script fails anywhere. This prevents you from creating a partially valid framework.

  • Then, use the RW_MULTIPLATFORM_BUILD_IN_PROGRESS variable to determine whether to call the script cyclically. If the variable exists, exit.

  • Then set some variables. The framework name is the same as the project name. That is, RWUIControls. In addition, the static lib name is libRWUIControls..

Next, use the script to set some functions, which will be used by the project in a short time. Add the following code to the bottom of the script.

12345678910111213141516171819 function build_static_library {    # Will rebuild the static library as specified    #     build_static_library sdk    xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \                     -target "${TARGET_NAME}" \                     -configuration "${CONFIGURATION}" \                     -sdk "${1}" \                     ONLY_ACTIVE_ARCH=NO \                     BUILD_DIR="${BUILD_DIR}" \                     OBJROOT="${OBJROOT}" \                     BUILD_ROOT="${BUILD_ROOT}" \                     SYMROOT="${SYMROOT}" $ACTION}  function make_fat_library {    # Will smash 2 static libs together    #     make_fat_library in1 in2 out    xcrun lipo -create "${1}" "${2}" -output "${3}"
  • Build_static_library uses the SDK as a parameter, for example, iPhone7.0, and then creates a static lib. Most parameters are directly transmitted to the current build,

  • The difference is to set ONLY_ACTIVE_ARCH to ensure that all structures are built for the current SDK.

  • Make_fat_library uses lipo to merge two static libraries into one. The parameter is the output location of the two static libraries and the result. Learn from here

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.