HomeiOS DevelopmentDeep dive into Swift frameworks

Deep dive into Swift frameworks


Study every thing about Swift modules, libraries, packages, closed supply frameworks, command line instruments and extra.

Swift

Fundamental definitions

To start with you need to have a transparent understanding in regards to the fundamental phrases. For those who already know what is the distinction between a module, bundle, library or framework you may skip this part. Nonetheless for those who nonetheless have some blended emotions about this stuff, please learn forward, you will not remorse it. 😉


Package deal

A bundle consists of Swift supply recordsdata and a manifest file.

A bundle is a group of Swift supply recordsdata. In case you are utilizing Swift Package deal Supervisor you even have to offer a manifest file with a purpose to make an actual bundle. If you wish to study extra about this software, you need to verify my Swift Package deal Supervisor tutorial.

Instance: that is your bundle:


Sources
    my-source-file.swift
Package deal.swift


You may also take a look at the open sourced switf-corelibs-foundation bundle by Apple, which is used to construct the Basis framework for Swift.



Library

Library is a packaged assortment of object recordsdata that program can hyperlink towards.

So a library is a bunch of compiled code. You possibly can create two sorts of libraries:


From a extremely easy perspective the one distinction between them is the strategy of “integrating” aka. linking them into your undertaking. Earlier than I let you know extra about this course of, first we must always speak about object recordsdata.


Mach-O file format

To create packages, builders convert supply code to object recordsdata. The thing recordsdata are then packaged into executable code or static libraries.

If you’re compiling the supply recordsdata you’re principally making object recordsdata, utilizing the Mach-O (MachObject) file format. These recordsdata are the core constructing blocks of your functions, frameworks, and libraries (each dynamic and static).


Linking libraries

Linking refers back to the creation of a single executable file from a number of object recordsdata.

In different phrases:

After the compiler has created all the thing recordsdata, one other program known as to bundle them into an executable program file. That program known as a linker and the method of bundling them into the executable known as linking.

Linking is simply combining all of your object recordsdata into an executable and resolving all of the externals, so the system will be capable of name all of the capabilities contained in the binary.


Static linking

The supply code of the library is actually going to be copied into the applying’s supply. It will lead to a giant executable, it’s going to take extra time to load, so the binary could have a slower startup time. Oh, did I point out that if you’re attempting to hyperlink the identical library greater than as soon as, the method will fail due to duplicated symbols?


This methodology has benefits as nicely, for instance the executable will all the time comprise the right model of the library, and solely these components shall be copied into the principle utility which are actually used, so you do not have to load the entire stuff, nevertheless it looks like dynamic linking goes to be higher in some circumstances.


Dynamic linking

Dynamic libraries are usually not embedded into the supply of the binary, they’re loaded at runtime. Because of this apps might be smaller and startup time can considerably be sooner due to the light-weight binary recordsdata. As a free of charge dynamic libraries might be shared with a number of executables to allow them to have decrease reminiscence footprints. That is why typically they’re being referred as shared libraries.


In fact if the dynamic library will not be accessible – or it is accessible however ther model is incompatible – your utility will not run or it’s going to crash. Then again this may be a bonus, as a result of the writer of the dynamic library can ship fixes and your app can profit from these, with out recompilation.

Luckily system libraries like UIKit are all the time accessible, so you do not have to fret an excessive amount of about this difficulty…


Framework

A framework is a hierarchical listing that encapsulates shared assets, equivalent to a dynamic shared library, nib recordsdata, picture recordsdata, localized strings, header recordsdata, and reference documentation in a single bundle.

So let’s make this straightforward: frameworks are static or dynamic libraries packed right into a bundle with some additional property, meta description for versioning and extra. UIKit is a framework which wants picture property to show among the UI parts, additionally it has a model description, by the way in which the model of UIKit is identical because the model of iOS.


Module

Swift organizes code into modules. Every module specifies a namespace and enforces entry controls on which components of that code can be utilized outdoors of the module.

With the import key phrase you’re actually importing exterior modules into your sorce. In Swift you’re all the time utilizing frameworks as modules, however let’s return in time for some time to know why we wanted modules in any respect.


import UIKit
import my-awesome-module


Earlier than modules you needed to import framework headers straight into your code and also you additionally needed to hyperlink manually the framework’s binary inside Xcode. The #import macro actually copy-pasted the entire resolved dependency construction into your code, and the compiler did the work on that massive supply file.

It was a fragile system, issues may go fallacious with macro definitions, you would simply break different frameworks. That was the explanation for outlining prefixed uppercased very lengthy macro names like: NS_MYSUPERLONGMACRONAME… 😒

There was an different difficulty: the copy-pasing resulted in non-scalable compile occasions. In an effort to clear up this, precompiled header (PCH) recordsdata had been born, however that was solely a partial answer, as a result of they polluted the namespace ( for those who import UIKit in a PCH file it will get accessible in all over the place), and noone actually maintained them.


Modules and module maps

The holy grail was already there, with the assistance of module maps (defining what sort of headers are a part of a module and what is the binary that has the implementation) we have encapsulated modular frameworks. 🎉 They’re individually compiled as soon as, the header recordsdata are defining the interface (API), and the (mechanically) linked dylib file accommodates the implementation. Hurray, no have to parse framework headers throughout compilation time (scalability), so native macro definitions will not break something. Modules can comprise submodules (inheritance), and you do not have to hyperlink them explicitly inside your (Xcode) undertaking, as a result of the .modulemap file has all the data that the construct system wants.

Finish of the story, now what occurs below the hood, whenever you import Basis or import UIKit.



Command line instruments

Now that the logic behind the entire dynamic modular framework system, we must always begin analyzing the instruments that make this infrastructure doable.

All the time learn the person pages, aka. RTFM! For those who do not wish to learn that a lot, you may obtain the instance undertaking from gitlab and open the makefiles for the essence. There shall be 3 essential classes: C, Swift and Xcode undertaking examples.


clang

the Clang C, C++, and Goal-C compiler

Clang is a compiler frontend for C languages (C, C++, Goal-C). You probably have ever tried to compiled C code with gcc throughout your college years, you may think about that clang is kind of the identical as gcc, however these days it could actually do much more.

clang -c essential.c -o essential.o #compiles a C supply file

LLVM: compiler backend system, which may compile and optimize the intermediate illustration (IR) code generated by clang or the Swift compiler for instance. It is language unbiased, and it could actually accomplish that many issues that might match right into a e-book, however for now as an instance that LLVM is making the ultimate machine code in your executable.


swiftc

The Swift compiler, there is no such thing as a handbook entry for this factor, however don’t be concerned, simply hearth up swiftc -h and see what can supply to you.

swiftc essential.swift #compiles a Swift supply file

As you may see this software is what truly can compile the Swift supply recordsdata into Mach-O’s or remaining executables. There’s a brief instance within the hooked up repository, you need to verify on that if you would like to study extra in regards to the Swift compiler.


ar

The ar utility creates and maintains teams of recordsdata mixed into an archive. As soon as an archive has been created, new recordsdata might be added and present recordsdata might be extracted, deleted, or changed.

So, in a nutshell you may zip Mach-O recordsdata into one file.

ar -rcs myLibrary.a *.o

With the assistance of ar you had been capable of create static library recordsdata, however these days libtool have the identical performance and much more.


ranlib

ranlib generates an index to the contents of an archive and shops it within the archive. The index lists every image outlined by a member of an archive that could be a relocatable object file.

Ranlib can create an index file contained in the static lib, so issues are going to be sooner whenever you’re about to make use of your library.

ranlib myLibrary.a

So ranlib & ar are instruments for sustaining static libraries, often ar takes care of the indexing, and you do not have to run ranlib anymore. Nonetheless there’s a higher possibility for managing static (and dynamic) libraries that you need to study…


libtool

create libraries

With libtool you may create dynamically linked libraries, or statically linked (archive) libraries. This software with the -static possibility is meant to switch ar & ranlib.

libtool -static *.o -o myLibrary.a

These days libtool is the principle possibility for build up library recordsdata, you need to positively study this software for those who’re into the subject. You possibly can verify the instance undertaking’s makefile for more information, or as often you may learn the manuals (man libtool). 😉


ld

The ld command combines a number of object recordsdata and libraries, resolves references, and produces an ouput file. ld can produce a remaining linked picture (executable, dylib, or bundle).

Let’s make it easy: that is the linker software.

ld essential.o -lSystem -LmyLibLocation -lmyLibrary -o MyApp

It will probably hyperlink a number of recordsdata right into a single entity, so from the Mach-O’s you can make an executable binary. Linking is critical, as a result of the system must resolve the addresses of every methodology from the linked libraries. In different phrases, the executable will be capable of run and all your capabilities shall be accessible for calling. 📱


nm

show identify listing (image desk)

With nm you may see what symbols are inside a file.

nm myLibrary.a




As you may see from the output, some type of reminiscence addresses are related for a few of symbols. People who have addresses are literally resolved, all of the others are coming from different libraries (they don’t seem to be resolved but). So because of this they’re going to be resolved at runtime. The opposite possibility is that you need to hyperlink them. 😅


otool

object file displaying software

With otool you may study the contents of Mach-O recordsdata or libraries.

otool -L myLibrary.a
otool -tV myLibrary.a

For instance you may listing the linked libraries, or see the disassembled textual content contents of the file. It is a actually useful software for those who’re conversant in the Mach-O file format, additionally good one to make use of for reverse-engineer an present utility.


lipo

create or function on common recordsdata

With the assistance of the lipo software you may create common (multi-architecture) recordsdata. Often this software is used for creating common frameworks.

lipo -create -output myFramework.framework units.framework simulator.framework

Think about the next state of affairs: you construct your sources each for arm7 and i386. On an actual gadget you’d have to ship the arm7 model, however for the iOS simulator you will want the i386 one. With the assistance of lipo you may mix these architectures into one, and ship that framework, so the tip consumer haven’t got to fret about this difficulty anymore.

Learn on the article to see the way it’s carried out. 👇



Xcode associated instruments

These instruments might be invoked from the command line as nicely, however they are much extra associated to Xcode than those earlier than. Let’s have a fast walk-through.


xcode-select

Manages the energetic developer listing for Xcode and BSD instruments. You probably have a number of variations of Xcode in your machine this software can simply change between the developer instruments supplied by the induvidual variations.

xcode-select --switch path/to/Xcode.app


xcrun

Run or find improvement instruments and properties. With xcrun you may principally run something which you can handle from Xcode.

xcrun simctl listing #listing of simulators


codesign

Create and manipulate code signatures

It will probably signal your utility with the correct signature. Often this factor failed whenever you had been attempting to signal your app earlier than automated signing was launched.

codesign -s "Your Firm, Inc." /path/to/MyApp.app
    codesign -v /path/to/MyApp.app


xcodebuild

construct Xcode tasks and workspaces

That is it. It will parse the Xcode undertaking or workspace file and executes the suitable buid instructions primarily based on it.

xcodebuild -project Instance.xcodeproj -target Instance
    xcodebuild -list
    xcodebuild -showsdks



Methods to make a closed supply common FATtened (multi-architecture) Swift framework for iOS?

So we’re right here, the entire article was made for studying the logic behind this tutorial.

To start with, I do not wish to reinvent the wheel, as a result of there’s a fantastically written article that you need to learn. Nonetheless, I might like to present you some extra detailed clarification and somewhat modification for the scripts.


Skinny vs. fats frameworks

Skinny frameworks accommodates compiled code for just one structure. Fats frameworks then again are containing “slices” for a number of architectures. Architectures are principally referred as slices, so for instance the i386 or arm7 slice.

This implies, for those who compile a framework just for i386 and x86_64 architectures, it’s going to work solely on the simulator and horribly fail on actual units. So if you wish to construct a very common framework, you need to compile for ALL the present architectures.


Constructing a fats framework

I’ve a excellent news for you. You simply want one little construct section script and an combination goal with a purpose to construct a multi-architecture framework. Right here it’s, shamelessly ripped off from the supply article, with some additional adjustments… 😁

set -e
BUILD_PATH="${SRCROOT}/construct"
DEPLOYMENT_PATH="${SRCROOT}"
TARGET_NAME="Console-iOS"
FRAMEWORK_NAME="Console"
FRAMEWORK="${FRAMEWORK_NAME}.framework"
FRAMEWORK_PATH="${DEPLOYMENT_PATH}/${FRAMEWORK}"


if [ -d "${BUILD_PATH}" ]; then
    rm -rf "${BUILD_PATH}"
fi


xcodebuild -target "${TARGET_NAME}" -configuration Launch 
    -arch arm64 -arch armv7 -arch armv7s 
    only_active_arch=no defines_module=sure -sdk "iphoneos"

xcodebuild -target "${TARGET_NAME}" -configuration Launch 
    -arch x86_64 -arch i386 
    only_active_arch=no defines_module=sure -sdk "iphonesimulator"


if [ -d "${FRAMEWORK_PATH}" ]; then
    rm -rf "${FRAMEWORK_PATH}"
fi


cp -r "${BUILD_PATH}/Launch-iphoneos/${FRAMEWORK}" "${FRAMEWORK_PATH}"


lipo -create -output "${FRAMEWORK_PATH}/${FRAMEWORK_NAME}" 
    "${BUILD_PATH}/Launch-iphoneos/${FRAMEWORK}/${FRAMEWORK_NAME}" 
    "${BUILD_PATH}/Launch-iphonesimulator/${FRAMEWORK}/${FRAMEWORK_NAME}"


cp -r "${BUILD_PATH}/Launch-iphonesimulator/${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" 
    "${FRAMEWORK_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule"


if [ -d "${BUILD_PATH}" ]; then
    rm -rf "${BUILD_PATH}"
fi


You possibly can all the time study the created framework with the lipo software.

lipo -info Console.framework/Console


Utilization

You simply need to embedd your model new framework into the undertaking that you simply’d like to make use of and set some paths. That is it. Virtually…



Delivery to the App Retailer

There is just one difficulty with fats architectures. They comprise slices for the simulator as nicely. If you wish to submit your app to the app retailer, you need to minimize off the simulator associated codebase from the framework. The rationale behind that is that no precise actual gadget requires this chunk of code, so why submit it, proper?


APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"


discover "$APP_PATH" -name '*.framework' -type d | whereas learn -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults learn "$FRAMEWORK/Data.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    EXTRACTED_ARCHS=()

    for ARCH in $ARCHS
    do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    carried out

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Changing unique executable with thinned model"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

carried out

This little script will take away all of the pointless slices from the framework, so you can submit your app by way of iTunesConnect, with none points. (ha-ha-ha. 😅)

You need to add this final script to your utility’s construct phases.



Closing ideas

If you wish to get faimiliar with the instruments behind the scenes, this text will aid you with the fundamentals. I could not discover one thing like this however I needed to dig deeper into the subject, so I made one. I hope you loved it, be at liberty to submit a gitlab difficulty or contact me for those who discover something fallacious or you could have an recommendation to enhance the article. 😉



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments