banner



Xcode Link Binary With Libraries Optional

Hullo my beau peers, Leo here.

Today we'll explore one thing that I recently discovered and I want to share with you all. When you create a framework in iOS development it can be various things, today we'll focus on only two of those options - a static library or a dynamic library. The advantages of modularization are plenty: development tin exist divided, you lot have more readable programs, programming erros (or features who knows?) are easy to handle, it allows re-use of code, you accept improved manageability and so on.

It's non new that create frameworks is a good strategy for big teams because they accept literally hundreds of thousands lines of lawmaking to maintain, then it's important to take it neatly done to don't become a really big mess. And isn't in the scope of this post what the are the advantages and the disadvantages of using frameworks, this might announced in some latter writings.

The painting that I picked for this article is Village and Ophelia from Agnes Pringle (1853–1934) and the reference is the "to be, or non to be, that's the question" from the famous masterpiece that I put not secretly in the title.

Allow's become!

Trouble

I want to know what is a better strategy for my new created framework, it's meliorate static or dynamic? Embed or not?

First for this topic we'll demand some theory about what are the the advantages and disadvantages of each one of the choices and afterwards that I'll evidence you an instance of each one.

Dynamic Library vs Static Library

The primary divergence between those two is how each one is linked to the executable file.

Dynamic libraries as the name says are dynamic linked to the awarding, they are not part of the application executable file. It means that when the app volition load all of them in runtime, you might be thinking exactly the same thing like me right now "Just if it's a runtime load, if I add a lot o dynamic libraries into the project and all or the majority of them be loaded in the startup, this could be a problem." AND you are correct as commented at this WWDC16 talk it'southward not a good idea having a lot of dynamic libraries inside your app.

The process goes similar this: When an app is launched the code is first loaded into the target address space. Then the dynamic linker comes into play, linking everything that the app needs to work properly. The dynamic linker will resolve each dependency location on the file system based on their install name and so linking the undefined external symbols ( in this example the code that you are relying to) to your app.

On the other mitt, the static library when linking it will employ the static linker. That ways, when at the build time you are using such library the linker will merge in i single executable file all the framework lawmaking and the target application code. This way your terminal executable will be bigger but you guarantee that all the code needed to run, are already available to use. When the application launches all the application code plus the framework code will be loaded in the application address spaces.

Framework

In apple world, the frameworks can be various things. The Apple documentation says:

A framework is a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, pecker files, image files, localized strings, header files, and reference documentation in a single package. Multiple applications tin utilise all of these resources simultaneously. The organisation loads them into memory equally needed and shares the i copy of the resources among all applications whenever possible. [...] Frameworks serve the same purpose every bit static and dynamic shared libraries, that is, they provide a library of routines that tin be called past an awarding to perform a specific task.

Later you create a framework, how tin can yous tell if your framework is a static library, dynamic library or something else? To answer this question you need to search for the Mach-o-type inside your framework, like the epitome below.

Screen Shot 2021-03-06 at 14.27.20.png

You just demand to get in your target -> build settings -> Linking -> Mach-o-Type. You can CHANGE the type of the framework to any other options. When you create a framework from Xcode it'll automatically gear up it to dynamic library, only you tin can change for whatever you desire, like the paradigm below shows.

Screen Shot 2021-03-06 at 14.28.17.png

For the example of this post I only created a plainly new framework with "command + shift + n" shortcut.

Screen Shot 2021-03-06 at 14.37.25.png

Embedding (or non) a framework

When you create an app you can have multiples frameworks, and dependencies in it. All of them y'all tin can set in the General tab in the Target of your choice. As the prototype below advise:

Screen Shot 2021-03-06 at 14.45.18.png

Frameworks have this three choices: Do not Embed, Embed & Sign and Embed Without Signing.

Screen Shot 2021-03-06 at 14.47.17.png

Do not Embed

The "Do Non Embed" pick yous are literally saying: please don't pack all the contents of this framework with the main awarding. This implies that the final awarding package volition not contain a folder called (by default) Frameworks with all the framework code.

But expect... early on you didn't say that the dynamic library is loaded outside the application lawmaking in runtime? Aye, and if you have a framework with the mach-o-type dynamic library and in the project "practice not embed" when your app try to dynamically find the dependency inside the package it will give you lot a runtime error. So be careful with this. And yes, Apple tree could check if you are doing this kind of affair but all we accept at present is hope that this could be Xcode feature for the hereafter.

Withal talking about the "Do Not Embed", if you exercise not embed a framework that is mach-o-type static library, your code will run normally because the code within the framework when you archive it as static linked to your chief code, this means the code inside the framework was packed together inside the awarding code. Therefore, you don't need to embed information technology to your app unless you lot want to have access to some "media bundle" inside the static library framework that you lot are using.

Plain when you don't embed the framework code your final ".ipa" will be smaller, only in example of dynamic library you don't have selection of non embedding them.

Embed framework (signing or not)

The "Embed and Sign" and "Embed Without Signing" the only diference is if y'all demand to sign the framework or not. If is already sign you don't demand to sign information technology again ( advertising hoc doesn't count on this).

Embedding a framework that mach-o-type is a dynamic library you are assuring that all the files of that framework volition be available in the final bundle of the app. When the app effort to resolve the external symbols that are not within the chief app code it will find inside the app bundle in the framework folder. As explained above, this could bear on seriously your startup time so be careful dynamic linking.

Now finally, when embedding a framework with mach-o-type of static library is something that you might rarely do. If you lot already take your code inside the main app executable you lot really will "duplicate" the size of your dependencies embedding a static framework on your app. Of course, if for some (out-of-your-control or not) reason you need to go admission to the "media bundle" inside the static library you tin exercise it embedding the static framework to your final package, but go on in mind the "size duplication" problem stated above.

TL;DR

Now y'all will be able to compare in a single view the chief differences between those four options.

Screen Shot 2021-03-06 at 15.41.23.png

And now allow's go the instance app that shows the final size differences of each one of the options listed above.

Exempli Gratia - Code Setup

To the setup I create a simple app that have ane ViewController that I want to accept all the option to choose the colour from another framework that I will create. The application is called BundleForAllExample and the framework I volition create is called MyColors.

The awarding code is pretty straightforward. Simply create a new app and paste the Code below to the ViewController.swift archive.

                      import            UIKit            //import MyColors // marker 1                          class              ViewController:              UIViewController            {            private            var            titleLabel:            UILabel!            individual            var            pressMeButton:            UIButton!            override                          func              viewDidLoad              ()                        {            super.viewDidLoad()            //view.backgroundColor = UIColor.Material.blueA100 //mark 2            view.backgroundColor = .blue         configureTitleLabel()         configureButton()     }            private                          func              configureTitleLabel              ()                        {         titleLabel =            UILabel()         view.addSubview(titleLabel)         titleLabel.translatesAutoresizingMaskIntoConstraints =            false            titleLabel.text =            "THIS IS Simply AN Case"            NSLayoutConstraint.activate([             titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, abiding:            30),             titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)         ])     }            private                          func              configureButton              ()                        {         pressMeButton =            UIButton()         view.addSubview(pressMeButton)         pressMeButton.translatesAutoresizingMaskIntoConstraints =            false            pressMeButton.setTitle("Press Me",            for: .normal)         pressMeButton.setTitleColor(.black,            for: .normal)         pressMeButton.backgroundColor = .yellow            NSLayoutConstraint.actuate([             pressMeButton.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant:            xx),             pressMeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)         ])     } }                  

You should run into this:

Screen Shot 2021-03-06 at 16.00.42.png

But what you really desire is to take that beautiful Blue A100 color from material pallete as your background color.

Now please remove the actual view.background color line and remove the comment signs from the import marking 1 and the view.background colour marking two. The lawmaking volition exist cleaved because your project don't have the MyColors framework dependency added, we will solve this trouble soon just first permit me explicate the 1 and ii marking on lawmaking.

The ane mark is when I'1000 telling the code to import the dependency of the framework nosotros'll create. This is very important considering without him, the Swift compiler can't tell that the extensions that will be using on the 2 marker exists. When we add that we are telling to the compiler: "Swift bring the UIKit module and the MyColors module to this file".

The 2 mark on the "view.backgroundColor = UIColor.Material.blueA100" is when we use the MyColors framework to get the Material colour blue A100. I'm non telling that textile colors are ameliorate than the UIColor default colors, information technology'due south simply an example ok guys.

Now it's time to create the framework.

  1. Create a new framework printing control+shift+n and select Framework.
  2. Name information technology MyColors.
  3. Create a swift file MainColors.swift.
  4. Add all the content of this repo to the file.

And your framework is done, merely build it to generate within the Products folder the MyColors.framework and nosotros are prepare to set upwards in the BundleForAllExample app.

Adding the framework to the app

Now you merely need to elevate the MyColors.framework of your framework project to the "Frameworks, Libraries and Embedded Content" of the BundleForAllExample app like the image below:

Screen Shot 2021-03-06 at 16.11.35.png

Later on yous elevate into your app be enlightened if Xcode set in the "Build Phases" tab of your Target the MyColors.framework. If not, you should but lookup in your folders and link manually. Troubleshooting tip: if your Xcode don't interact linking automatically the framework, yous can go to Build Settings -> Framework Search Paths, and at that place yous put the exact path ( go to the left bar framework folder -> correct-click on MyColors.framework -> show in finder -> get the path to information technology -> add the path to the Framework Search Paths)

Screen Shot 2021-03-08 at 07.48.28.png

Now back to the General tab, let seed the options of embedding the framework.

Screen Shot 2021-03-08 at 07.50.06.png

And if you click in the right side arrows, the options will announced:

Screen Shot 2021-03-08 at 07.52.31.png

This is how you can manipule all the options that we discussed earlier. If go inside your framework and change the mach-o-type of it, you tin choose between static library or dynamic library. The same mode, if you want to embed or not your framework in your last app bundle you tin dispense those options in General -> Frameworks, Libraries, and Embedded Content.

Go back to the ViewController and brand certain your add two things in it.

This:

                      import            MyColors                  

And inside viewDidLoad() this:

                      view.backgroundColor            = UIColor.Material.blueA100                  

Run your project, the blue should be the new cloth A100 bluish. What a lovely solar day!

Screen Shot 2021-03-08 at 08.40.01.png

Sizes Comparison betwixt .IPA files

To finish this and wrap up all that we discussed I generated four .ipa archive files to demonstrate how different the size can be depending on what options you choose. I'll sort in ascending order and I think you tin imagine already what options volition exist the smallest and the biggest ane. I'll use the archive procedure for development team considering information technology'southward easier and information technology'south just to show the differences betwixt sizes, for your surround you should cheque if you lot will demand to sign or not in example of embedding content.

Outset permit'due south the the see the smallest option with 33kb .ipa : Do Not Embed in App and Dynamic Library in framework mach-o-type options. This is obviously the smaller ane because if y'all don't embed a dynamic library, non a single line of code of the framework will be present in the terminal bundle, this ways that if your app depends on this framework to run production code, it will crash.

Screen Shot 2021-03-08 at 08.50.16.png

2nd 1 with 64kb .ipa is: Non Embed in the App and Static Library in framework mach-o-type options. This is also pretty straightforward past now: as the static library is static linked to the principal app code, the swift compiler tin can practise some optimizations to shrink the size of the framework inside the final app code.

Screen Shot 2021-03-08 at 08.56.54.png

The tertiary .ipa file has 84kb and has the options: Embed in the App and Dynamic Library in framework mach-o-type. This will bundle the framework code into the concluding .ipa file merely the symbols inside the main app code are external and bachelor at run time through dynamic linking. The default behaviour is generate a folder called framework that your app can link in runtime the files.

Screen Shot 2021-03-08 at 09.10.24.png

The 4th and it's not surprise with 371kb .ipa file is: Embed in the App and Static Library in framework mach-o-type. This archive will in the .ipa accept the Framework folder with all the contents of the framework and also the main code will have all the lawmaking that the static library has. So this option is only useful if you lot need to get the media packet inside the static framework, otherwise is a actually bad idea.

Screen Shot 2021-03-08 at 09.14.06.png

The End

I promise y'all, my beloved readers, enjoy this content as much as I enjoyed preparing and studying this. This is just an introductory topic on Frameworks and Xcode packing but it's some foundation knowledge that I thought it would exist great to share with you.

As always if yous have any comment or feedback, please don't hesitate to share beneath. I want to know your impressions on this.

And if you want to help me keeping this work, you tin buy a swift book from amazon from my link.

That'southward all my people, I promise you liked every bit I enjoyed write this article. If you want to support this blog you tin Buy Me a Coffee or merely leave a comment maxim hello. You can also sponsor posts and I'm open to writing freelancing! Just reach me in LinkedIn or Twitter for details.

Thanks for the reading and... That's all folks.

credits: image

Xcode Link Binary With Libraries Optional,

Source: https://holyswift.app/frameworks-embed-or-not-embed-thats-the-question

Posted by: corleyatrom1939.blogspot.com

0 Response to "Xcode Link Binary With Libraries Optional"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel