Accelerate Your iOS Build Time Process Within Xcode

Danny Santoso
CodeX
Published in
8 min readOct 26, 2022
Photo by Ammar ElAmir on Unsplash

Have you been wondering why your iOS app project took so long when you build your iOS app in Xcode? when you have created a small change or maybe you just want to log or print some of your code but when you build again it took so long ? and is there any solution to fasten our build time process so we can be more productive ?

In this article, I will tell you why your iOS build process took so long and how you can accelerate your build time process. without further ado, let’s jump into the topic.

Usually, when you build your iOS app project, Xcode runs many processes to transform your code into an iOS app, but there is some process that matters to determine the build time process of your app, and we also can accelerate these process, and these processes are compiled and link.

I have written an Article about compiled and link process, so I will not explain more about compile and link process in here, but you can refer to this link if you want to know more about compile and link process.

Different from any programming language (like C++, Objective C, and other C languages), swift doesn’t have any header file, so it makes one of the reasons why swift programming language takes too long when we build our program (especially when compiling process).

Header files commonly contain forward declarations of classes, subroutines, variables, and other identifiers. Usually, Developers will declare standardized identifiers in more than one source file and can place such identifiers in a single header file. which other code can then include whenever the header contents are required. This is used to separate the interface and the implementation.

A newer compiled programming language such as Swift does not use forward declarations, and identifiers will be recognized automatically in swift source files, and read directly from dynamic library symbols. So this is the reason why Swift programming language doesn’t need header files different from Objective C.

In compiling process, the compiler will read the identifiers in the header file first and then it will read the implementation of the identifiers in the source of files during the linking process, so when we have declared identifiers in the header but we don’t have the implementation in the source files, so it will give an error when in the linking process. for the Example, I have created 2 file of c++ below, and one header file that declares all the identifier will be used in those 2 files.

  • fileA.cpp
  • fileB.cpp
  • fileA.h

as the example above, we can run commands like this to compile and link those files.

  • Compile
g++ -c fileA.cppg++ -c fileB.cpp

after we run these commands, the compiler will create a new fileA.o and fileB.o, these .o files are binary file, and we can link them as an executable file with the command below.

  • Linking
g++ fileA.o fileB.o -o executable.out

this command will generate a new executable file (executable.out) that allows us to run. you can run this executable file, by used this command ./executable.out.

now, let’s try to command haloB function in fileB.cpp file, and rerun the compile and link process. when you run the compile process it will succeed to create a new binary file, but when you link these binary files will show undefined symbols error like below.

This because when we declare all the identifier in header file, the compiler will not check the implementation of the identifier in source files, the compiler will ignore the implementation in source files, and when it comes to link process, the linker will check if the implementation of the identifier in the header file already correct or not with the implementation in the source files. so this is the reason why compiled programming language that has a header file have a compile process faster than new modern programming language that has not a header file, that because the compiler will ignore the implementation of the identifier because it’s the linker task.

So how do we enhanced our swift compiling in iOS development ? the solution is we can create a modularize app with the framework. because when you group or modulize your source code as a framework it will create a new library file whether it is static or dynamic library, and any other extension file, such as .swiftdoc, .swiftmodule, .swiftsourceinfo. and, in .swiftmodule file it contains serialized ASTs (and possibly SIL) — it’s basically a binary file format equivalent to header files for a C framework or library.

So, that’s why when you compile, the compiler will read the initialize identifier in .swiftmodule file, and will move to linker to check the implementation so the compile process will not being taken too long.

Not only that, but because we create a framework, indirectly the compiler asks us to group our source code as a module, this is the advantage when we build our iOS app, because the compiler will not compile all the framework again, but it will compile the framework or library that just made a change and this why when you create a modularization app it will reduce build time process.

And how we can create modularization using a framework in our app? Here, I will guide you step by step to create a modularization app using a framework in Xcode.

  • First, open your .xcodeproj, and then create a new workspace like the example image below.
  • After you finished creating a new workspace, it will show an empty file like the example image below.
  • Next, all you need is to add your previous .xcodeproj file to your workspace.
  • open the directory of your .xcodeproj located and then add it to your workspace.
  • after you add your .xcodeproj into your workspace, the next step is you need to create a new framework, by tapping the file menu in the menu bar and then choosing a new project.
  • after that, you can choose to create the framework.
  • locate your framework in the root level of your workspace file or the same level as your .xcodeproj in your workspace file.
  • after you create your new framework, and then it will show like the image below, and then you need to change the library type of your framework. in here, you can choose a static library as your mach-o type of your library.
  • some of you may be wondering what is the difference between a static and dynamic library, here I will explain both of them in a nutshell.
  • in a static library, it only linked all the binary files, because all the binary files are already being precompiled, and in a static library all the binary files that have been compiled will be copy-pasted into the executable app. but in a dynamic library it will create a reference, and in a dynamic library it will run a linker in runtime.
  • after you change the Mach-O type of your library, you can copy the feature folder that you want to separate as a new module from the main project and paste it into your framework module, and don’t forget to delete the feature folder that you want to separate as a new module in your main project, because we already copy it into your framework. after that, you can add a target, and choose the iOS App template like below.
  • finally, you have your module target app, if you want to create your micro-app you can utilize this to run your module page only.
  • In your new module app target don’t forget to add your current framework. you can tap the + button in the section that I have marked in the image below.
  • and then you can choose the framework that you have created in the previous step.
  • Now, you will have your framework linked to your target app.
  • Here, is the overall look of your module app, that you have been separated from your main app.
  • one last thing, after you separate your module, if you copy-paste your feature into a new module, if you have some of the XIB file, don’t forget to change your module like the example image below.
  • now you can repeat those steps for all your feature that you want to separate as a new module.

and that is the step if you want to fasten your build time process in your iOS app project. by separating as a different module from the main app, if one of the modules has any change, the compiler only recompiles your module that has changes, it will not recompile all your code, and also by creating a framework, it will have .swiftmodule that contains serialized ASTs that is equivalent with the header file in the old compiled programming language that is used to fasten your compile and linked process, and this is why it will accelerate your build time process.

--

--

Danny Santoso
CodeX
Writer for

not a wizard, nor a sage. only an apprentice who keeps intensifying his intelligence to form great magic.