Common problems when modularizing an iOS application

Rayane Kurrimboccus
6 min readMar 30, 2019

You may want to modularize your iOS app, but in some cases, things can get complicated. In this post I am going to present most common problems I went through when I was modularizing an existing big iOS app, and what I did to solve or to avoid the problems.

This article will mostly cover encapsulation, circular dependencies, images (bundle), pbxproj and extraction of existing app part to a framework.

“Okay so where am I going to create this ?”

When you have frameworks in your app, the first question that may come into your mind is “Where are you going to write code for this next feature ?”.

As I said in my previous post on frameworks, you should categorize your frameworks. You could have one Core framework, some feature-specific frameworks, and some other technical frameworks.
If your new feature or whatever you are going to develop doesn’t enter in any existing framework, you might want to create a new one.

Make your choice carefully because it will surely have impacts later if you want to change or interact with this new feature.

“Public, internal, private ?”

Error : Use of unresolved identifier…

You will have this popping up in front of your nose ! This is because you need to declare your classes/structs or whatever you are defining in your module and want to access it from the outside as public.

When developing an app without framework, you usually don’t pay much attention to visibility or access control because everything in Swift is by default internal. Internal means that you can access it in the current module. When you are developing a module, you need to explicitly define the class you want to be usable from the outside as public.

This also forces you to have a better code encapsulation and to better define your app structure. You should only mark as public the types that you want to be accessible from the outside of the framework. Everything else should be at least internal, or even private if it’s for a local use.

So if you want to silence the Xcode error just mark your class as public.

“Let’s import this framework everywhere we need it !”

Yes, but ! When working with frameworks you have to be careful or you will deal with circular dependencies and many headaches. Inside your framework, you cannot import a second framework which is already importing the first one, directly or indirectly.

Also, you may have a situation where a feature framework (let’s say Account) want to know something about another framework (Booking) to create a link. For example you want to launch a booking search based on your preferences in your account section. From the account framework you want to launch a search so you may want to import Booking framework, but that would be wrong because it would be questioning the separation of these two frameworks.

So how to handle links between two frameworks that shouldn’t import each other ? This case is an interesting question and one solution is to create a bridge between the two frameworks, using a pattern known as POP (Protocol Oriented Programming).

This solution requires a long post to be explained so I am not going to discuss it here but I surely will in another article.

“My app crashes when loading an image !”

Error: Could not load the image from referenced…

This is going to get you into trouble if you are extracting an existing part of your app with many images. Each framework has it own bundle, that means if you put your images into your framework.xcassets and load your images normally, in your .xib or .storyboard or even using #imageLiteral, you are eventually going to have a crash like below :

Crash when loading an image using #imageLiteral

The app is crashing because the bundle used by xibs, storyboards or imageLiterals is the main bundle. Since you are developing in a framework which has its own bundle, the system is looking for the image asset in the wrong bundle.

To resolve this problem, you have to specify the bundle for every image you use in this framework. Here is an exemple of what you can do :

How to use images inside a framework

Here you are creating a class inside the module, just to indicate to the Bundle init on line 6 that you want to use the bundle of that class, which is the framework bundle. By defining this Bundle extension, you can create an image located in the framework bundle by specifying it very easily.

Concerning xibs and storyboard I think you should set image sources in the code, because it is safer.
If you are creating a new module and don’t have any existing image, don’t forget to specify the bundle for your new images.

“I want to export a part of my app but the dependency is too strong”

Trying to export a small part of the app which is too dependent

When I was starting to modularize a part of the app I was working on, I ran into a wall. I was trying to export a little service, which was in fact using another service, which depended on another one… and so on.

It was not possible to export all of these services to my new framework because of the dependencies. It was too tied to the main app, like if you were trying to get a noodle out of a noodle dish, but end lifting the whole thing.

So then I had to find out how to export my first service without grabbing the whole noodle dish.

I am going to explain in details how I managed to do this in another post, since it requires a clear explanation, and can be a little too long for this post.

“Conflits on pbxproj… a pain in the neck !”

When you are trying to merge your branch and then…

Yes it is ! If you are multiple developers working on the project, you will be confronted to this hell. Unfortunately, I don’t have any miracle solution for this problem.

Each time you create a new framework or move files to other targets, or basically everytime you touch on the configuration of one target, you are modifying the .pbxproj file. That means you are going to have conflicts with your team mates and this file is very hard to read. Often you will have to “choose both” but you surely will have to check if the project is broken or not.

However, there is a tool called XcodeGen that could be a solution to this problem. You can read more about it here.

To conclude, I don’t have any real solution for this problem but keep in mind that the number of conflicts on this file is important only at the beginning of your framework structure creation. Once you have your frameworks defined, everything should work fine and you will no longer have this nightmare with you !

You can check the GitHub project, showing a modularized iOS app, basic problems I came across in this post, and how to handle them (images and bundles for example).

I hope this post could have given you an overview of the main problems that you could encounter when modularizing an iOS app. All of these problems can be overcome so keep going ! ;)

--

--