Knowledge points involved in this article:

  • Creation & use of dynamic libraries
  • Compile the Framework common to each architecture
  • Dynamic library stripping

1. Create oneFrameworkProject & Use

1.1 Creation Procedure
  • XcodeVersion for12.2
  • Operation steps:Create a new Xcode Project -> iOS -> Framework & Library -> Framework -> next

  • Add code to the project, for exampleHDLogToolIn theDylibFrameworkAdd code to:#import <HDLogTool.h>That is as follows:

  • Open common code header files. Drag and drop header files that need to be exposed to the outside worldTarget -> Build Phases -> Headers -> Public

  • Next, select an emulator to compile (support for various CPU architectures will be covered later)
1.2 use it
  • Add one to the current projectTarget:File-> New -> Target -> iOS -> Application -> App
  • inDemoTo import the dynamic library

  • Next thing you know, you can goDemoUse dynamic library code, and should be able to compile and execute correctly, if you modify the dynamic library code, run directlydemoYou can see the effect

Compiles the generic schemaFramework

1.1 Use the Framework in other projects
  • In the previous section I made it possible to use dynamic libraries by adding subprojects, but in real development, the Framework needs to be provided to developers separately.
  • inProducts -> DylibFramework.framework -> Show in finderFind the well-packaged library files.
  • Viewing by CommandFrameworkThe supported schema types arex86_64
#Lipo is a MAC OS built-in tool that can be directly typed into the terminal to view some parameters
lipo -info DylibFramework
Copy the code

  • Drag into a new projectDylibTest, in theGeneral -> Frameworks,Libararies,and Embedded contentSet the imported library toEmbed & Sign(In older versions of Xcode, Embed was set separately)

Embed & Sign can be understood as: the libraries need to be copied into the App Bundle during build, which is different from apple’s official dynamic libraries. The officially provided system libraries do not need to be copied into the App Bundle. Sign stands for signature. Libraries imported into the App Bundle need to be signed when they are packaged and uploaded

  • After it is used in the project, it runs successfully

  • When we choose to run on a real machine, an error will be reported, as shown in the following figure:

Xcode compiles the Framework for emulators and real machines in different packages, and supports different platforms

1.2 Compile for each platformFramework
1.2.1 merger
  • Build and generate dynamic libraries for each platform. Select any emulator to compile, selectAny iOS DeviceAt this point, two types of dynamic libraries have been generated in the sandbox
  • useXcodeIn theAggregatTo complete the Framework merge
  • inDylibFrameworkCreate one in the projectAggregat Target:File -> New -> Target -> Other -> Aggregat

  • inAggregatthetargetCreate a new script in

  • Merge the dynamic libraries that support the simulator and the real machine, and generate theProducts) :
if [ "${ACTION}" = "build" ]
then

INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework

DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework

SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework

if [ -d "${INSTALL_DIR}" ]x86_64

then

rm -rf "${INSTALL_DIR}"

fi

mkdir -p "${INSTALL_DIR}"

cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"

#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"

#Use the lipo command to combine them into a common framework  

#Finally, place the generated generic framework under the newly created Products directory under the project root directory  

lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"

#open "${DEVICE_DIR}"

#Open the generated folder
open "${SRCROOT}/Products" 

fi

Copy the code
  • At this point we can see that the dynamic libraries are also merged. You can view the supported CUP types by running the following command:

  • We drag the dynamic library into the project, run it again, and it fails againQAQ
#Because later did not reappear, so here only send out the error message
/DylibTest.xcodeproj Building for iOS Simulator, but the linked and embedded framework 'DylibFramework.framework' was built for iOS + iOS Simulator.
Copy the code
  • Solutions:Build Settings -> Validate Workspace -> YES

Reference links: https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built

  • Modified toYESAfter running perfectly.
  • Due to theiOSCompilation particularity, for easy debugging, a lotSDKI386 (iOS14 emulator no longer supports), x86_64, armv7, arm64Several platforms have merged. uploadapp store, you need to changeI386, x86_64Libraries on both platforms are deleted, otherwise they cannot be submitted for review normally.
1.2.2 stripping
  • Mainly throughlipoCommand to perform some operations on the library
  • Let’s start with a copy of the current dynamic libraryDylibFramework.framework
  • Decouple from dynamic librariesarmv7andarm64In the library
# armv7
lipo DylibFramework.framework/DylibFramework -thin armv7 -output DylibFramework_armv7
# arm64
lipo DylibFramework.framework/DylibFramework -thin arm64 -output DylibFramework_arm64
Copy the code
  • willarmv7andarm64The library package
lipo -create DylibFramework_armv7 DylibFramework_arm64 -output DylibFramework
Copy the code
  • Changing the file name
#Replace the library in the backup with the new one
mv DylibFramework DylibFramework.framework/
Copy the code
  • theDylibFramework.frameworkRe-import it into your project and it’s ready to use

Think about:

  1. Compiling a generic version of the dynamic library is relatively complex. Consider writing some scripts to support it.
  2. When making dynamic library, code extraction should be carried out according to actual business. It is recommended to privatize the dynamic library first, and then consider compiling it into dynamic library
  3. A reasonably designed dynamic database update scheme is relatively complex and needs to fit the existing development mode.
  4. Write good project development documentation for subsequent developers.
  5. At presentCocoaPodsSupports integration with third parties in the form of dynamic libraries whileCocoaPodsThe code is visible and easy to debug, so it’s a priorityCocoaPodsTo do it.