Enforcing modular code with frameworks in Xcode

Every iOS developer I know dreams of writing code that’s DRY, modular, testable and reusable. While this is a great goal to strive for it’s often quite hard to write code that is completely modular. It just takes one oversight to blow most of the modularity you have achieved right out the window.

One technique that people use to make it easier to write modular code is to try and ensure that a certain part of their code, for instance the networking logic or their models, know nothing about other parts of the app. Again, a great idea but this isn’t really enforced by anything other than you and your team.

Wouldn’t it be great if there was a way to enforce this level of modularity automatically? Well, I have some great news for you. This is entirely possible and once I tried it for myself it was amazing how straightforward the solution actually is to implement. You can add multiple targets to your Xcode project. This can be used to turn certain parts of your code into frameworks which means that these parts of your code live in isolation from the rest of your code.

The outline of setting this up is as follows:
1. Identify code that should live in a framework
2. Add a new framework target to your project
3. Transfer relevant existing code to the framework target
4. Optional if you use Cocoapods: add dependencies to your new target
5. Write code independent from your app
6. Write tests for your framework
7. Use the framework in your app

We’ll go over each of these steps briefly so you get a good feel of how you can adopt this workflow in your own apps.

Identifying code for your framework

The first step to creating a framework is figuring out what code should live in the framework. It isn’t always obvious which parts of your app could be a framework and which parts can’t be. A good way to figure this out is to think about putting a group of files together in a folder. Can you find a couple of related classes that could happily be put together in a folder where they could only be aware of other classes in the same folder? If you can, it’s probably a good idea to put those files together in a framework.

Another way of finding code that could be better off in a framework is by looking at your code. Are there certain parts of your code that are littered throughout your project that would make changing certain things really hard? That could be a problem in the long run and it might very well be that you actually made some decisions along the way that have destroyed the modularity of your code. Moving some of this tightly coupled functionality into a framework could help you rethink the structure of this tight coupling and it could improve your code drastically.

Adding a framework target in Xcode

Once you have figured out which part of your app you want to put in a framework you need to add a new framework target in Xcode. The easiest way to do this is by going to your project’s settings by clicking on your project name in the Project navigator. Next, look for the + button at the bottom of the panel that lists your targets. This will present you with the same dialog that is presented when you create a new project. In the left sidebar pick the Framework & Library option and select Cocoa Touch Framework.

Now confirm your choice and create the framework by following the on screen steps. If you want to write tests for this target, which you should, make sure to select the Add Unit Tests checkbox. After creating your framework, it is automatically linked to your main app and two new folders were created. One for the framework and one the framework tests.

Adding code to your framework

If you are transferring existing code to your framework, drag the files from your main project folder to the framework folder so your code is logically organised. Next, select the files you just transferred and open the sidebar on the right side of Xcode. Look for the Target Membership header in the File Inspector. You’ll see that the checkbox next to your app is checked. Uncheck this checkbox and check the one next to your framework’s name. This will link the code to your framework instead of your main app.

When you create new files, make sure that the Target Membership is set correctly. Usually Xcode is smart enough to see which folder is currently active and it will add the code to the correct target. It’s always a good idea to double check because you don’t want to go hunting for issues only to find out you forget to correctly set the target for your files.

Integrating with Cocoapods

There’s a good chance your framework has some dependencies. If you’re writing an API framework, you could have a dependency on Alamofire or maybe SwiftyJSON. Cocoapods only links to one framework at a time so your Podfile needs to be updated so it can handle your new framework target. Setting up a Podfile with multiple targets can be done with the following skeleton.

This is very similar to the Podfile you probably already have, expect it has one more target; your framework. Cocoapods will set up your framework target just like it sets up your app, you don’t need to do anything special if you’re adding Cocoapods to a framework.

Writing code independent from your app

Now that you’re all set up, you can start writing your framework code. You do this the same way you’re used to except there is one major difference. In a framework, any code you want to expose to your main application should be marked as public. Code that isn’t marked as public is considered internal and can only be accessed by your framework. Code marked as private still works the same, it can only be accessed by code that lives in the same file.

The big upside of this is that your app can’t know more about the framework then it should. That’s already a big win in terms of modularity.

Writing tests for your framework

Because your tests can only access the public code in your API it’s wise to use your tests as the place where you develop and test your framework. By this I mean that your tests will be the first client that uses your framework. Developing your framework like this makes sure that your framework has great test coverage and you’re testing your framework in isolation from the rest of your app. This forces you to think about your framework instead of the entire app.

Using the framework in your app

Since Xcode has already linked your framework to your app, using your framework works just the same as using any other framework you’ve used. Any file that uses your framework needs to add an import for the framework at the top of the file and from that point out your framework is available to rest of your code.

In conclusion

As you’ve seen, adding your own frameworks to your project isn’t very complex and it forces you to think of your app in a different way. Instead of creating an app where any object can use and access almost any other object you’re creating an app and one or more frameworks. Each of the frameworks you create can function independent from the rest of your app. This means that you could eventually add the framework to other projects or even open source it if you’d like.

Testing your framework is also a lot easier because you know which parts of codes are the API that’s public and those should be the first parts you test. If all you write tests for is your public API, you know that using your framework should work as expected and intended before you even use it in your app.

The approach outlined in this post is especially useful if you only want to use your frameworks in a single app. Using them in multiple apps would require a slightly different approach because you would want the frameworks to live outside of your main project but the benefits and most steps should be very similar.

If you have any feedback, questions or want to discuss this post with men feel free to reach out on Twitter or in the ios developers slack channel

Surviving a start-up’s bankruptcy

On a Tuesday almost two months ago, near the end of april, me and my coworkers received an email about an important meeting the next. We knew that something was going on, the look and feel of this email wasn’t the same as usual. This one seemed a bit darker, a bit more serious. On Friday you could feel the tension in the office, people were speculating a bit and just acting different than usual. But we all had jobs to do and we tried to do them just like we always did. But it turns out that this tension and the feeling we al had wasn’t wrong.

When the meeting actually went down we heard that an investor had backed out of our start-up. Resulting in an inability to pay the bills and sending all of us home until we would know more. What followed was a pretty strange, exhausting and tough period where I learned new things about myself, my work and how to keep busy. I would like to share this experience with you in this blogpost to try and explain how weird of a period bankruptcy can be from an employee’s perspective.

Stage one: registering the events that happened

Since the big announcement was made on a Friday, we actually had a few drinks afterward. It was different than usual, but we had fun, we laughed, talked about how much of a great time we had and that it wasn’t over just yet! We could still be bought, an investor might pop up soon and we’ll all be back to work in no time. Then Monday came along and I didn’t have to go to work. There really wasn’t much for me to do actually. So I started my week with just taking the day off. In the back of my mind I had this idea that I was getting payed anyway, so I might as well enjoy this time off.

At first I did pretty well, the first couple of days were pretty laid back, I started working on a side project called “Cijfer Hulp”. It’s a simple app for Dutch students to keep track of their grades and what grade they need to maintain a great average. But after a couple of days I realised that my job probably wasn’t going to come back. This was a pretty huge blow, I loved my job! I enjoyed going there every single day, and to realise that a 10 minute meeting was the last thing I’d ever do at this company was a pretty big blow.

Stage two: finding purpose, keep going

When I established with myself that I was probably going to be out of a job soon I started to look for a new job. This went pretty well at first, a few companies responded to my applications rather quick and I had set up some meetings in no time. However, I felt like I lacked a purpose. My side project was finished in about 8 days so there wasn’t much for me to do either. Staying in bed until 10:00AM, 11:00AM or later started to become easier and easier and falling asleep at night became harder and harder. I grew frustrated and irritable very quickly and while the meetings with potential employers were fun, they didn’t give me a sense of security.

The fact that I had no job, a few potential employers and the possibility of choosing one to work for and not knowing when I would know more about my current job was troubling me. One of the things that kept me thinking was the fact that my current employer still didn’t officially go bankrupt. We were all sitting at home, waiting for the court to pass a verdict. Three weeks went by with no news. It was just about time for us all to get payed, but the money wouldn’t come since there was no money. In The Netherlands there’s a company that will take over all of the salary payments from an employer if they can’t pay anymore, but this only happens after the court has declared bankruptcy. At this point it was clear that verdict would have to become bankruptcy. It was just a matter of when.

During this first month I had days where I was just frustrated, grumpy and tired all day. Keeping myself busy just felt pointless. I lacked purpose, everything I did was just filler to get through another day of not having to do anything. On other days I was motivated, I though about maybe going freelance or starting another side project. These days were quite fun actually because they had purpose and meaning. Whenever I’d go and have a cup of coffee at some company I always felt pretty satisfied, I was working towards something. However, my overall mood wasn’t too good. Having no responsibilities or purpose is taxing and I wouldn’t recommend it to anybody. Doing small side projects is a smart idea. What also helped was to just head out of the house around 09:30 and go to the library to work there. Whenever I did this I was at least double as productive compared to staying at home all day.

Stage three: something look forward to

After a little longer than a month I found an employer that I wanted to work for. And they were excited to hire me as well! This felt like a huge win. No matter what was going on at my current job, I knew what was next. And the best part, just a few days after this I also got the news that me and my coworkers were now officially fired and the company had been declared bankrupt. However weird it may seem I was very relieved with this letter. Finally some closure, finally a timeline for it all. Just one more month and then I would start at my new employer, knowing that the current situation would be fully handled and I could finally start working towards getting the salary I still needed from the month of sitting at home. All of this had been so frustrating, especially not knowing what’s next and when it was coming. So for all of this to fall in place so short after one another was truly a blessing.

Tips for people who might find themselves in a similar situation

My most important tip is to try and keep up some sort of schedule. Your work rhythm probably provides some stability to you and your mind. Don’t break this, try to go to a public library or if you’re comfortable working from home, try to spend the day working on things. Maybe a side project, maybe some blog posts or maybe do some chores that you needed to get done anyway. You don’t have to spend your whole day programming, just make sure you’re busy.

Also, i would recommend to start looking for jobs right away. Just go and have some cups of coffee with people. You don’t have to formally apply everywhere, just get to know some people. Expand your network. It might seem a bit pointless and hard at times, but it’s really worth it. The nice thing about being in this situation is that there’s no rush in finding a new job. You can take it easy, you can really browse around for a nice place to work at.

It’s okay to be sad or feel down about the situation. When I had a bad day sometimes I thought that I had messed up. I should have been able to see this coming or do something, or whatever. It’s tough to realise that it’s something you might not have been able to see coming, something that you lack control over and it’s okay to be bummed out. If you loved your job it will have huge impact on you when that suddenly disappears. This is also the reason why I recommend to try and keep up our rhythm. It will help to keep your mind from wondering and it will help you wit that feeling of having no purpose.

On variable naming when teaching

One of the hardest things a programmer has to do on a daily basis is naming things. Anything that we name will stay with us for a while and it’s very likely that other programmers will have to use the thing we just named as well. So naming something properly is very important. It’s often said that the two hardest problems in programming are naming things and cache invalidation. I tend to agree with that statement.

A lot of times when I struggled with a piece of code, naming could have made my struggle easier. A function name like fetchData might make sense at the time of writing. But a few weeks later you look at that code and you start wondering.. what data does that function fetch, exactly? Couldn’t it have been named fetch just as well? I mean, the fact that it fetches data is implied. Or is it? Almost always there’s room for discussion on the naming of things in code. However, that’s not the point I want to make in this post. This post is about naming things in the context of tutorials and books. In other words, code snippets that have a teaching purpose.

When you write code that is intended or teaching you should make sure that you keep two things in mind.

  1. You want to get a certain point or concept across to the reader. The code should make this point as clear as possible.
  2. You want to stick to best practices so you’re not teaching bad habits.

I have found that these two goals can easily be in conflict.

An example

Let me show you an example I have found in the Functional Swift book by the folks over at objc.io.

These four lines won’t look very scary to somebody who is familiar with Generics in Swift. They will know that T and U are just placeholders for types. Any value could go there, we could have defined them as A and B or Hello and World just as well. However, the best practice is that generic naming starts at T and seems to work it’s way up through the alphabet from there. So that’s why this snippet uses the T and U as type names for the generic portion of this struct. For beginners this might be confusing so you could argue that more descriptive type names would be better. For example, FirstType and SecondType are a lot clearer. They don’t follow best practices though, so picking between the two can prove to be quite tough and in my opinion it depends on the point you’re trying to get across. In the above snippet the concept of generics is already explained in previous chapters, so T and U are just fine in this snippet. If this snippet was about explaining generics it might have been better to help the reader out a little bit by breaking best practices for the sake of readability and introducing the proper way after explaining how generics work.

What does bother me about the way the Times struct is defined is the way fst and snd are named. The author chose to sacrifice readability in order to save a few keystrokes. In production code this happens all the the time. Loops like for u in users or [obj.name for obj in res] are not uncommon in Swift and Python. One might even argue that using short names like this is actually some sort of convention and while that might be true, if you’re explaining something in code you do not want the reader to have a single doubt about what something does because of the name. For example, fst and snd in the Times struct could have been named first and second or left and right. A loop like for u in users could be for user in users. [obj.name for obj in res] could be clarified by writing [user.name for user in fetched_users]. These more verbose versions of code might not be fully in line with best practices or common in production code, but when you’re using code to explain something you need to make sure that your code is as readable as possible.

In conclusion

Naming things is hard, there’s no doubt about it. What might be clear one day could look like gibberish the next. What might be obvious to me could be nonsense to you. Conventions help ease the pain. If everybody uses the same rules for naming things it becomes a little bit easier for programmers to come up with good naming. However, we should not forget that people who read our code to learn more about a certain topic might not be fully aware of certain conventions. Or they might not be very good at understanding what i, j and k mean when we’re nesting loops. And let’s be honest, those single letter variables lack all kinds of meaning. Even though it’s convention and we all do it, it’s just not a good convention follow when teaching. At least not all of the time.

Next time you write code that’s intended for explaining something, ask yourself if breaking a convention will make your snippet simpler or easier to follow. If the answer is yes, it just might be a good idea to break the convention and save your readers some brainpower.