Category: Objective-C

In the previous post, we discussed how protocols 1 are the foundation of polymorphism, and how using protocols we can define a contract, an expectation, that can be implemented in many different ways.

Today we are also to explore how we can use protocols as a way to use code that does not exist yet, as a boundary between what we know (our code) and what we don’t know (other people’s code).

In an ideal world (maybe not ideal for everyone, but that would be a different discussion) we don’t develop our software in isolation. We have team mates, or we use modules or frameworks developed by other teams within the same company.

Some time ago, I was with a time developing a set of Video On Demand applications. We had to implement a new feature: add support for recommendations based on user’s content consumption habits. The recommendations engine was not developed yet, in fact there was no team assigned to build it at that time.

We knew were our side of the solution started and ended. We knew we were going to need to tell the recommendations engine that a user had watched a particular item, and we were going to need to get a list of recommended items from the engine.

We started by defining our own interface for that recommendations engine. We looked at the problem from ur side of it, and wrote the interface we wished the recommendations engine had.

Did we know how the actual interface of the actual recommendations engine would look? Not at all. Did we care? We did not.

But we could start working on our side of the solution using fake data.

Having a clear boundary, clear separation between our side and their side, allowed us to build our side completely decoupled from the recommendations engine.

Having a clear boundary also gave us the confidence that we would be able to adapt to whatever the actual interface of the recommendations engine would look. And why I mean by adapt is literally write an adapter between our interface and the actually interface of the engine, if necessary (see the Adapter Pattern)

Also, having a clear boundary allowed us to unit test our solution from day one, giving us the confidence we needed to move forward fast.

It’s not rocket science. But it is worth remembering that protocols are not just those things that you use for table views data sources and delegates, but that they are probably the most powerful tool in our reach.

I have never been a fan of how the Cocoa frameworks use the word protocol instead of interface. ↩︎

It is all in the documentation, both in the UIViewController Class Reference, and in the comments in the class header. It also makes sense, but today I spent a couple of hours debugging a weird crash, due to this.

So this is something I think I won’t forget in a long time.

When initializing a view controller passing nil as a nib, the view controller will attempt to load a nib whose name is the as same as the view controller’s class. That’s what the UIViewController header clearly states:

If you
invoke this method with a nil nib name, then this class’ -loadView method will attempt to load a NIB whose
name is the same as your view controller’s class. If no such NIB in fact exists then you must either call
-setView: before -view is invoked, or override the -loadView method to set up your views programatically

But there is more. According to the UIViewController class reference:

If you use a nib file to store your view controller’s view, it is recommended that you specify that nib file explicitly when initializing your view controller. However, if you do not specify a nib name, and do not override the loadView method in your custom subclass, the view controller searches for a nib file using other means. Specifically, it looks for a nib file with an appropriate name (without the .nib extension) and loads that nib file whenever its view is requested. Specifically, it looks (in order) for a nib file with one of the following names:

If the view controller class name ends with the word ‘Controller’, as in MyViewController, it looks for a nib file whose name matches the class name without the word ‘Controller’, as in MyView.nib.

It looks for a nib file whose name matches the name of the view controller class. For example, if the class name is MyViewController, it looks for a MyViewController.nib file.

And that’s exactly what happened to me earlier today. I was initializing a view controller like this:

1

2

let vc=AddContactViewController()

While also having in the project a completely unrelated xib, named AddContactView. Unrelated, like in “AddContactViewController does not use AddContactView.xib at all. Nothing. Zero.”

So my app was crashing, throwing an assertion that kindly reminded me that AddContactView did not have any owner properly setup.

Unit tests covering Objective-C code can be written in Swift. By following this approach, we can kill two birds with one stone: add testing coverage while starting to introduce Swift into an Objective-C project.

If you are having a hard time finding how and where to start adding Swift to a legacy project, or you are not really sure if Swift is for you, or your management thinks Swift is just a fad, or just “syntactic sugar”1, or not mature enough, it might be the moment to turn to your testing bundle.

Killing two birds with one stone

Every piece of software should be unit tested. If your project is not tested, I strongly recommend adding unit tests to it as soon as possible.

So, if your project does not contain any tests, you can kill two birds with one stone, by starting to add tests, writing them in Swift. And if you project already contains tests, one way of dipping your toes into the Swift world could be using Swift to write your unit tests.

Let’s assume we have an Objective-C only project. To complicate things just a little bit, let’s assume this project does not even contain a testing bundle.

Follow these easy steps

Add a testing bundle. This step would not be necessary if you already have a testing bundle.

Select Swift as the testing bundle language. Not necessary if you already have a testing bundle.

Add a bridging header to the production bundle. The easiest way to do that, in my opinion, is by adding a dummy Cocoa class, to be removed later, selecting Swift as the language, and letting Xcode take care of adding the header for you. After Xcode adds the header, the new class can just be removed from the project.

Import the Objective-C class or classes you want to test in the bridging header.

Update the testing bundle’s build settings, pointing the the Objective-C Bridging Header setting to the header that was created in step 3.

The last couple of years there has been a lot of discussion in the community about one of the most pressing issues when it comes to writing maintainable applications.

And that pressing issue is no other than the size of view controllers. View controllers tend to become a kitchen sink, a mix of responsibilities, that handle networking, deal with navigation or validate user data.

But here is the thing: I don’t think MVVM is intrinsically better than MVC. Nor the other way around. I have the feeling that sometimes MVVM is sold as some kind of silver bullet that, in combination with a more functional style, is going to, magically, make our lives easier.

I love the idea of separating presentation and presentation logic, which is something MVVM advocates for. But, I don’t think that, by itself, is enough. I think it is necessary to do much more than just embracing a different pattern, no matter how good that pattern looks on paper.

I believe this book (highly recommended, non-affiliated link) is the first one where I read about the idea of micro-architectures. Basically, the idea is: when facing a problem, don’t try to think too big, try to build a solution that solves the problem in a clean, extensible and testable way.

I think that micro-architectures pay off at a local scope. But the way micro-architectures really shine is by accumulation. When you start solving small, limited in scope, contained problems by architecting the crap out of them, everything else starts falling into place, and you start noticing how an application-wide architecture starts emerging.

How? A local, isolated, solution usually leads to a better solution at a wider scope, which usually shows the way to a better solution to an even wider scope.

For example, if you remove from a view controller the responsibility of creating and navigating to another view controller by adding a class to the system that takes care of doing that, you might find that if you inject that class into every other view controller you might generalise it to deal with all the navigation logic in your app. So, now, you need to find a way to inject that NavigationManager into all your view controllers, so it might make sense to have another class that takes care only of creating view controllers. It would be great if you could pass your NavigationManager to this new UIManager, so you might need something that creates both and injects one into another. That could be an ApplicationBootstrapper that you create in the App Delegate. See the pattern? Decisions at a local level propagate up, so you can build an application-wide architecture from the bottom up.

The point I am trying to make is: applying the SOLID principles everywhere, all the time, is going, by accumulation, to produce well architected, maintainable and testable applications.

Embracing MVC, MVVM, or whatever goes into fashion next, by itself, is not going to be enough. I think it is better to embrace whatever pattern you understand better, or think is good for you and your application, or you can reason about better, and keep always a vigilant and critical eye on every decision you make. Trust your instincts, and as soon as you notice a bad smell, micro-architect the crap out of whatever you are building.

Greetings, fellow Cocoa developers, and welcome to a new edition of The Week in Cocoa News, your weekly mash-up of bad jokes and links to blogposts and articles of interest to the discerning Cocoa developer in your life.

So, let’s get the bad joke out the way first. And trust me, this is a really bad one

Knock, knock.

Race condition.

Who’s there.

Badum-tsh!

Before you shoot yourself, read the following post. It contains plenty of what’s best about Swift -type-safety, the possibility of avoiding all “sting-typed” programming, easy ways to modify behaviour without relying on extension, to name a few-, in this case in the context of the “classic” Objective-C territory: UIKit

To be honest, most of the suggestions in that article are not about Unit Testing, but just about good engineering (injecting static dependencies, relying on abstractions -protocols- and not concretions -classes-), but again, this just prove the point of TDD: there is usually a correlation between good production and good testing code.

By the way, now that we are discussing testing. it might be a good moment to link to Nimble, the matcher framework for Swift (and Objective-C)

The last project I have been working on is a set of highly customisable applications, that need to render their user interface according to some configuration downloaded from a remote service. Meh.

But, the thing is, a setup like this leaves a lot of opportunities for Swift to shine. One of those opportunities is implementing color schemes.

The context

All the colours used in an application need to be declared as part of a color scheme, that needs to be downloaded from a remote service. For the shake of this example, we are going to leave the “download it from a remote service” part out of the equation.

A good approach

Well, this is Cocoa, so, the first approach that comes to mind would be declaring an extension on UIColor, and declare the different palette items in it. Something like this:

Swift

1

2

3

4

5

6

7

8

9

extensionUIColor{

classfuncforegroundColor()->UIColor{

returnUIColor(red:0/255.0,green:174/255.0,blue:239/255.0,alpha:1)

}

classfuncbackgroundColor()->UIColor{

returnUIColor(red:25/255.0,green:22/255.0,blue:22/255.0,alpha:1)

}

}

Which is a perfectly valid approach. But, that is basically a literal translation of what I would do in Objective-C, if I had to figure out a way out of this problem. Which is not bad.

But…

A better approach

The previous approach does not feel very Swift-ish. And, what is worst to me, it does not seem extremely flexible. For example, how would I deal with a requirement such as “yo, bro! can we make the color scheme change at runtime?. Like, you know, light theme during day hours, dark theme during night hours? That’d be sooooo coooooooooool”

Well, let’s try a fresh approach to the problem at hand. What’s a color scheme? To me, it is a set of mutually exclusive values. The active color scheme can be Light, or Dark, not Light and Dark at the same time.

And that, in Swift, is an enumeration. Also, it happens that Swift enumeration can implement methods. So, we could rewrite the previous extension as:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

enumColorScheme{

caseLight

caseDark

varbackgroundColor: UIColor{

letreturnValue:UIColor

switch(self){

case.Light:

returnValue=.lightGrayColor()

case.Dark:

returnValue=.blackColor()

}

returnreturnValue

}

varforegroundColor: UIColor{

letreturnValue:UIColor

switch(self){

case.Light:

returnValue=.blackColor()

case.Dark:

returnValue=.whiteColor()

}

returnreturnValue

}

}

Now, we can set the active scheme as:

Swift

1

varscheme:ColorScheme=.Dark

And consume it, everywhere in the UI as:

Swift

1

square.backgroundColor=scheme.backgroundColor

All of that, backed up by the compiler, which will make sure that we do not miss any possible value of the color scheme in its methods.

Final words

Switching to Swift is not only a matter of writing code in a different language, it is also a matter of forgetting about most of the old patterns, and embrace new ways.

I am the first to be surprised to find a post about good old Objective-C in this blog. This Sexy Software Engineer has not written any Objective-C code in almost a year! This Sexy Software Engineer, though, still enjoys using the Royal We. Some things ain’t changin’

A little bit of ancient history

Those, like me, old enough to be around in the “good old days”, before ARC, when memory had to be manually managed, will remember how a proper constructor (sorry, initializer) in a proper Objective-C class was supposed to return id

Objective-C

1

2

3

@interfaceSexySoftwareEngineer

-(id) initWithName:(NSString*)name surname:(NSString*)surname;

@end

id meant “Yo! Compiler! This is untyped! Have fun with it!” Or something similar. You get the point.

But then ARC came in with all its modern memory management, and all its fancy annotations, and suddenly, the right thing to do was to type return types in initialisers as instancetype

A little bit of contemporary history

Here we are now, one year into the Swift age. Lots of things have changed, and most of us do not consider the fully dynamic nature of Objective-C a selling point anymore. We might still miss it sometimes, but we like the warm and fuzzy feeling of relying on the compiler, and let it catch potential problems for us.

But, and this is a big but, we still need to rely on Objective-C libraries and frameworks daily. And those are not trivial libraries, those are the actual SDK frameworks (AppKit, UIKit and Foundation), which are still Objective-C

Apple is doing a great job in making the interoperability as smooth as possible. Please, watch the WWDC Session Swift and Objective-C interoperability right now, and you will get a great walkthrough everything that has been done in order to turn Swift code that uses Objective-C code into something safe. Let’s just say that now you can do something like this:

Back to the point: what’s with id?

By adding some extra metadata to the Objective-C code, like nullability and “kindof” annotations, or by embracing generics, Objective-C code will be more robust, less error prone, and Swift code that uses Objective-C can be safer.

Values marked as Nullable in Objective-C will be considered as Optionals in Swift. Typed Objective-C arrays will not be AnyObject arrays in Swift anymore. And that’s very good.

But still, what happens to id? Well, there are still two use cases for it:

Store different types of values in a Dictionary.

Type something as “any object implementing a protocol”

The second use case is something I have not done in many years (I always used to type pointers to protocols as NSObject <MyProtocol>).

The first one, is something that, although powerful, I always considered as a code smell.

So, here comes Swift 2 to the rescue, introducing something that will make roll the eyes to our Java-oriented friends in the house: throw

throw does not suck that bad

Yes, I know, I know, Java has been throwing exceptions for years, and Java this and Java that. But, first, Swift throws does not have any performance side effects, opposing to Java exceptions, (meaning, your program is not going to slow down to a crawl when you try to throw one) and second, and most important, using throw, and its sidekicks try and do catch, you can make your code intent extremely clear and obvious to anyone reading your code (including yourself in a couple of months time).

So, how does the awesome shinny new thing works? Actually, it is quite simple.

If you want to Do Things Properly(TM), the first thing you would need to do would be declaring your error type, which should conform to, surprise, ErrorType. Why would you ever want to conform to ErrorType? Well, because that’s what NSError conforms to. Wink, wink, nudge, nudge.

So, again, your error:

Swift

1

2

3

enumError: ErrorType{

caseDummy

}

Remember the previous post? We had a function that bailed out as soon as a set of sanity preconditions where not met. Well, let’s rewrite that one to, instead of just bailing out, throwing one of your shinny new errors.

Swift

1

2

3

4

5

6

7

funcdivide(x:Int?,y:Int?)throws->Double{

guard letx=x,y=ywherey>0else{

throwError.Dummy

}

returnDouble(x)/Double(y)

}

Please note that, in theory at least, throwing an error is not supposed to be that different from an early return. Specially in terms of performance. In other words, throwing errors is the cool thing to do now.

Now, clients of this function can do this:

Swift

1

2

3

4

5

do{

trydivide2(10,y:nil)

}catchError.Dummy{

print("What are you doing, you idiot!?")

}

Note how you must add the try keyword when calling a function that throws something. Explicit much?

Final words

Now, as usual, reader discretion is advised. Use this at your own risk. It is not that hard to end up with code like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

enumError: ErrorType{

caseZero

caseNegative

caseNull

}

funcdivide(x:Int?,y:Int?)throws->Double{

guard letx=x,y=yelse{

throwError.Null

}

guardy>0else{

throwError.Negative

}

guardy!=0else{

throwError.Negative

}

returnDouble(x)/Double(y)

}

do{

trydivide(10,y:nil)

}catchError.Zero{

print("Do not do that, man!. Do not pass a zero as second argument!")

}catchError.Negative{

print("Do not do that, man!. Do not pass a negative number as second argument!")