IOS development: Xcode packaging framework

Source: Internet
Author: User

IOS development: Xcode packaging framework

I think this packaging framework is still a very important feature that can be used to do the following:

(1) encapsulate functional modules. For example, if a mature functional module is encapsulated into a package, it will be easier for you or other colleagues to use it later.

(2) encapsulate a project. Sometimes, this problem occurs when a company finds two development companies to create two projects and then asks one of their projects to be nested into another project, in this case, you can package embedded projects into the framework, which is convenient.

Why do we need a Framework )?

It is very troublesome to share the database in a developer-friendly way. You not only need to include the library itself, but also add all header files, resources, and so on.

Apple solves this problem by using the framework ). Basically, this is a folder that contains a fixed structure and contains everything necessary to reference the library. Unfortunately, iOS prohibits all dynamic libraries. At the same time, Apple also removed the function of creating a static iOS framework from Xcode.

Xcode still supports the framework creation function. to restart this function, we need to make some minor changes to Xcode.

Encapsulating code in a static framework is permitted by app store. Although the form is different, it is essentially a static library.

Framework category

Most frameworks are in the form of dynamic link libraries. Because only Apple can install dynamic libraries on iOS devices, we cannot create such frameworks.

The static Link Library is the same as the dynamic library, except that it links binary code during compilation, therefore, static databases do not have the same problems as dynamic libraries (that is, no one except Apple can use dynamic libraries on iOS ).

The "pseudo" framework is implemented by cracking the target Bundle of Xcode (using some scripts. On the surface and in use, it is no different from the static framework. The functions of a "pseudo" framework project are almost the same as those of a real framework project (not all ).

The "embedded" framework is a package of the static framework, so that Xcode can obtain resources in the framework (images, plist, nib, etc ).

This release includes templates for creating static frameworks and pseudo frameworks, as well as "embedded" frameworks.

Which template is used?

This release has two templates, each of which has two categories: "strong" and "weak. You can choose the most suitable one (or both ).

The biggest difference is that Xcode cannot create a "real" framework unless you install the static framework file xcspec in Xcode. This is really a pity (this file is for the project, not for the Framework ).

Simply put, you can decide which template to use:

If you do not want to modify Xcode, use the "pseudo" Framework version.

If you just want to share binary data (not a project), either of them can be

If you want to share the framework with developers who do not want to modify Xcode, use the "pseudo" Framework version.

If you want to share the framework with developers who have modified Xcode, use the "real" Framework version.

If you want to use a framework project as the dependency of another project (via workspace or subitem), use the "real" framework (or "pseudo" framework, use-framework -- see later)

If you want to add other static libraries/frameworks to your framework project and link them to the final results so that you do not need to add them to your project separately, use the "pseudo" Framework

"Pseudo" Framework

The "pseudo" framework is a cracked "reloacatable object file" (the target file in relocable format stores code and data and is suitable for connecting to other target files, it is used to create an executable target file or a shared target file. It allows Xcode to compile something similar to the framework-in fact, it is also a bundle.

The "pseudo-framework" template divides the entire process into several steps and uses some scripts to generate a real static framework (based on the static library instead of reloacatable object file ). In addition, the framework project defines it as the wrapper. cfbundle type, a "second-class citizen" in Xcode ".

Therefore, it works normally like a "real" static framework, but it is troublesome when there is a dependency.

Dependency problems

If no dependency is used, it is no problem to create a common project. However, if you use project dependencies (such as in workspace), Xcode will be miserable. When you click the '+' button under "Link Binary With Libraries", the "pseudo framework" cannot be displayed in the list. You can drag it manually under the Products of your "pseudo" framework project, but when you edit your main project, a warning will appear:

Warning: skipping file '/somewhere/MyFramework. Framework' (unexpectedfile type 'wrapper. cfbundle' in Frameworks & Libraries build phase)

With a link error in the "pseudo" framework.

Fortunately, there is a way to solve it. You can use the "-framwork" switch in "Other Linker Flags" to manually tell linker to use your framework for link:

-Framework MyFramework

The warning still exists, but at least the link is correct.

Add other libraries/frameworks

If you add other static (not dynamic) Libraries/frameworks to your "pseudo" framework project, they will "Link" them into your final binary framework file. In a "real" framework project, they are purely referenced, not linked.

You can avoid this situation by simply including the header file in the project rather than the static library/framework itself (for compilation ).

"True" Framework

All aspects of the "true" framework comply with the "true" standard. It is a real static framework, just as it was created using the feature removed from Xcode by Apple.

To create a real static framework project, you must install an xcspec file in Xcode.

If you publish a "real" framework project (instead of compiling), the person who wants to compile the framework must also install the xcspec file (using the installation script of this release ), so that Xcode can understand the target type.

Note: If you are releasing a fully compiled framework instead of a framework project, end users do not need to install anything.

I have submitted a report to Apple and want them to update this file in Xcode, but it takes some time. OpenRadarlink here

Add other static libraries/frameworks

If you add other static (not dynamic) Libraries/frameworks to your "real" framework project, they will only be referenced, instead of being linked to the final binary file like a "pseudo" framework.

Upgrade from earlier versions

If you are upgrading from Mk6 or earlier, and use the "real" static framework and versions earlier than Xcode4.2.1, run uninstall_legacy.sh to uninstall all the fixes that were previously used in Xcode. Run install. sh and restart Xcode. If you use Xcode4.3, you only need to run install. sh and restart Xcode.

Install

Run the install. sh script under the Real Framework directory or Fake Framework directory respectively (or both of them are running ).

Restart Xcode and you will see StaticiOS Framework (or Fake Static iOS Framework) in the Framework & Library of the new project wizard ).

Run the unistall. sh script and restart Xcode.

Create an iOS framework project

Create a new project.

Select Static iOS Framework (or Fake Static iOS Framework) under Framework & Library for the project type ).

Select include unit test (optional ).

Add classes and resources to the target.

All header files to be used by other projects must be declared as public. Go to the Build Phases page of target, expand the Copy Headers item, and drag the public header file from the Project or Private part to the Public part.

Compile your iOS framework

Select the scheme of the specified target

Modify the Run configuration of scheme (optional ). Run configuration uses Debug by default, but you may want to use Release when preparing for deployment.

Compile the framework (no matter which iOS device or Simulator is the target, the same binary will be compiled, so it doesn't matter who you choose ).

Select your framework from Products, "show in Finder ".

The build directory has two folders: (yourframework). framework and (your framework). embeddedframework.

If your framework only has code and has no resources (such as the momd files for comparison, script, xib, and coredata), you can set (yourframework ). the framework can be distributed to your users. If you still have resources, you must distribute (your framework). embeddedframework to your users.

Why embedded framework? Because Xcode does not search for resources in the static framework, if you distribute (your framework). framework, all resources in the framework will not be displayed or unavailable.

An embedded framework is only an additional package outside the framework, including the symbolic links of all resources of the framework. In this way, Xcode can find these resources.

Use iOS framework

The iOS framework is similar to the conventional Mac OS dynamic framework, but it is a static link.

To use a framework in your project, you only need to drag it to your project. When including header files, remember to use angle brackets instead of double quotation marks to enclose the frame name. For example, for the Framework MyFramework:

# Import

Usage Problems

Headers Not Found

If Xcode cannot find the framework header file, you may forget to declare it as public. Refer to step 2 of "Create an iOS framework project.

No Such Product Type

If you have not installed iOS Universal Framework in Xcode and attempt to compile a universal Framework project (for a "true" Framework, it is not a "false" Framework), this will cause the following errors:

Target specifies product type 'com. apple. product-type.framework.static ', but there's no such product type for the 'iphonesimulator' platform

To compile the "real" iOS static framework, Xcode needs to make some changes. Therefore, to compile the "real" static framework project, install it in all development environments (this is not required for framework users, but only for framework compilation ).

The selected run destination is not valid for this action

Sometimes, Xcode errors and loads the wrong active settings. First, restart Xcode. If the error persists, Xcode generates a bad project (because of a bug in Xcode4, this problem occurs for any type of project ). If so, you need to create a new project.

Link warning

When the target framework is compiled for the first time, Xcdoe cannot find the folder in the Link stage report:

Ld: warning: directory not found for option '-L/Users/myself/Library/Developer/Xcode/DerivedData/MyFramework-ccahfoccjqiognaqraesrxdyqcne/Build/Products/Debug-iphoneos'

In this case, you can clean and re-compile the target to eliminate the warning.

Core Data momd not found

For framework projects and application projects, Xcode will compile momd (hosting object model files) in different ways ). Xcode will simply create a. mom file in the root directory instead of A. momd directory (the directory contains VersionInfo. plist and. mom files ).

This means that when you instantiate NSManagedObjectModel from a model of the embedded framework, you must use the. mom extension as the URL of the model instead of the. momd extension.

NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @ "MyModel" withExtension: @ "mom"];

Unknown class MyClass in Interface Builder file.

Because the static framework uses static links, linker removes all code that it deems useless. Unfortunately, linker does not check the xib file, so if the class is referenced in xib without being referenced in O-C code, linker will delete the class from the final executable file. This is a linker issue, not a framework issue (this problem also occurs when you compile a static library ). This problem does not occur in Apple's built-in framework, because they are dynamically loaded during runtime, and the dynamic libraries that exist in the firmware of iOS devices cannot be deleted.

There are two solutions:

Let the framework end users disable the linker optimization options by adding-ObjC and-all_load to the Other Linker Flags of their projects.

Add a code reference for this class to another class in the framework. For example, if you have a MyTextField class, it is removed by linker. Suppose you still have a MyViewController, which uses MyTextField in xib, and MyViewController is not excluded. You should do this:

In MyTextField:

+ (Void) forceLinkerLoad _{}

In MyViewController:

+ (Void) initialize {[MyTextField forceLinkerLoad _];}

They still need to add-ObjC to linker settings, but do not need to force all_load.

The 2nd method requires you to do more work, but it allows end users to avoid disabling linker optimization when using your framework (disabling linker optimization will lead to object File expansion ).

Unexpected file type 'wrapper. cfbundle' in Frameworks & Libraries build phase

This problem occurs when the "false" framework project is used as the workspace dependency or as a sub-project (the "true" framework project does not have this problem ). Although such a framework project produces a correct static framework, Xcode can only see from the project file that this is a bundle, so it sends a warning when checking dependencies and skips it in the linker phase.

You can manually add a command to enable the linker to properly link the link. Add:

-Framework MyFramework

The warning still exists, but the link will not fail.

Libraries being linked or not being linked into the finalframework

Unfortunately, the "true" framework and "false" framework templates work differently in handling the introduced static libraries/frameworks.

The "true" framework template uses normal static library generation steps and does not link other static libraries/frameworks to the final production objects.

The "false" framework template uses the "spoofing" Xcode method to make it think that it is compiling a target file in relocatable format. In the link stage, it is like compiling an executable file, link all static code files to the final product (although the target code is not checked ). To achieve the same effect as the "true" framework, you can include only the header files of the Library/framework to your project, without the need to include the Library/framework itself.

Unrecognized selector in (some class with a category method)

If your static library or framework contains a module (declared only in the class code without class implementation), linker will be confused and remove the code from the binary file. Because this method is not available in the final generated file, an "unrecognizedselector" exception is reported when the method defined in this category is called.

To solve this problem, add a "fake" class to the module code that contains this category. Linker finds a complete O-C class that links the class code to the module.

I wrote a header file LoadableCategory. h to reduce this workload:

# Import "SomeConcreteClass + MyAdditions. h"

# Import "LoadableCategory. h" MAKE_CATEGORIES_LOADABLE (SomeConcreteClass_MyAdditions); @ implementation SomeConcreteClass (MyAdditions)

...

@ End

When using this framework, you still need to add-ObjC to the Other Linker Flags of Build Setting.

The unit test crashes before executing any code.

If you select "withunit tests" when creating a static framework (or library) target in Xcode4.3, it will crash when you try to run the unit test:

Thread 1: EXC_BAD_ACCESS (code = 2, address = 0x0) 0 0x00000000 --- 15 dyldbootstrap: start (...)

This is a bug in lldb. You can use GDB to run unit tests. Edit scheme, select Test, and change the Debugger from LLDB to GDB in the Info tab.

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.