Hiding sensitive business logic in Objective-C

So you have some business logic in a class that you want to hide from the users of your class? Let’s say that you are working on a library project and you have to expose the header file of this particular class to your user but once you do that, it’s easier for dubious programmers to find the class name behind your business logic and potential reverse engineer your app.

In Objective-C, we can hide the implementation of our business logic by taking advantage of the Objective-C runtime. Here is our action plan:

  1. We will create our class called Person (the class whose header file is going to be exposed to evil programmers out in the wild!)
  2. We will create another class called PrivatePerson and will include our business logic in there
  3. We will then redirect requests from the Person class to the PrivatePerson class

And obviously we will not export the PrivatePerson’s header files for the programmers, are we crazy? No!

Ok so let’s begin by creating the interface for our Person class like so:

Screen Shot 2014-01-17 at 16.10.09

The properties are fine. But the method named fullName is going to have business logic in it. It will return the current first name and the last name, separated with a space. We don’t want the logic for this method to be inside the Person class so what can we do? We will go first and create the class named PrivatePerson and we will put our business logic for the fullName method in there. Let’s start with the header file. But before we do that, remember that the firstName and lastName properties are in the Person class. So how can the PrivatePerson class that contains the business logic calculate the full name without having those values? Well, we just have to pass those values to PrivatePerson as parameters like so:

Screen Shot 2014-01-17 at 16.25.54

Then we will implement the PrivatePerson class:

Screen Shot 2014-01-17 at 16.26.45

 

Now what we have to do in our Person class is to implement 2 methods. The first method is methodSignatureForSelector: and this method will be called on our Person class whenever the fullName method is called. Since Person doesn’t implement fullName, the runtime will, in the process of throwing an exception, first find out whether the Person class can handle this message. By implementing the aforementioned method, we get a chance to return a method signature that corresponds to the fullNameFromFirstName:lastName: method in the PrivatePerson class, like so:

Screen Shot 2014-01-17 at 16.31.39

 

Note: self.privatePerson is a private property of our class. Look at the next screen shot to learn how we implement that property’s getter.

 

Then we will implement the forwardInvocation: method using which we redirect the call for the fullName method into the fullNameFromFirstName:lastName: method in PrivatePerson class:

Screen Shot 2014-01-17 at 16.33.21

 

Perfect, in your app delegate for instance, test this out:

Screen Shot 2014-01-17 at 16.34.39

 

You can see the correct value of “Vandad Nahavandipoor” will be printed out to the screen.

That’s all good and fluffy and warm and nice. But LLVM will be nagging at the incomplete implementation of the fullName method in the Person class since we haven’t implemented it there. Remember? That was our goal! Doh!

Screen Shot 2014-01-17 at 16.37.22

So using the awesome techniques described by the lovely people behind LLVM, we will silent these incomplete-impelemntation warnings in our Person class like so:

Screen Shot 2014-01-17 at 16.39.56

 

Awesome, problem solved. Happy coding everyone! :-)

iOS 7 Programming Cookbook’s Source Code

As you know, my recent book is now published, titled “iOS 7 Programming Cookbook”. You can purchase it here:

http://shop.oreilly.com/product/0636920031031.do

All the source codes written for this book are now available on Github at the following location:

https://github.com/vandadnp/ios-7-programming-cookbook-source-codes

If you have any questions, please let me know.

Completely removing (obsoleting) an enumeration item from iOS 7.0

Deprecating Properties, Methods and Enumerations in Objective-C – LLVM/Xcode Tips and Tricks

A lot of times when working in a team, you would write a class, or add an enumeration to an existing class or add a new property. Some times, you might need to tell other programmers who work on the same code-base that a property, enumeration or a method that you wrote is now becoming deprecated and perhaps a new version of the API introduces a new property/enumeration/method that programmers need to use instead.

This is where LLVM can be very useful. Obviously, if you are the only programmer in a project and not developing an API for others, this might not be of much use to you. But if you are used to working in a team, knowing this trick is an absolute necessity.

Let’s say we are writing an enumeration that at the time of writing (let’s assume at the time of writing this enumeration, iOS 5 was the latest iOS version), everything was fine like so:

Our enumeration works on every iOS version for now

Now let’s say iOS 6.0 is introduced and you are thinking to yourself “Oh that Ultra Fast item in the enumeration is just not very good and I think I have to remove it”. So what to do now? The solution is using __attribute__ like so:

Deprecating an enumeration value in Objective-C

Deprecating an enumeration value in Objective-C

The availability attribute can have the following keys:

introduced: this will be the version of the operating system (iOS, Mac OS X) where the API was introduced first.

deprecated: this is the version of the operating system where the API was deprecated (ready to be removed from the API in later versions of the API)

obsoleted: the version of the operating system where the API is completely removed and is no longer supported.

message: the message to display to the programmer in Xcode.

As you can see, right in front of the availability attribute, we can write “ios” or “macosx” to denote if an API is (un)available for iOS or Mac OS X respectively.

Now let’s assume iOS 7.0 comes along and we want to completely stop our support for the “ultra fast” enumeration value. All we have to do is to add the “obsoleted” key to the availability attribute like so:

Completely removing (obsoleting) an enumeration item from iOS 7.0I hope you enjoyed this tutorial. Let me know if you have any questions :-)

Making a Class Unavailable in Objective-C – LLVM/Xcode Tips and Tricks

So you have written an Objective-C class and you would like to mark it as unavailable so that others won’t be able to instantiate it?

The solution is simple. In the header file of your class, place the following code:

__attribute__((unavailable("Your message to the developer goes here")))

So here is an example of a class header file that uses this LLVM extension:

#import <Foundation/Foundation.h>

__attribute__((unavailable(“This class is unavailable. Please use the YourClass class instead”)))

@interface MyClass : NSObject

@end

Once a programmer attempts to use this class, they will see something similar to this in Xcode (Click to Enlarge the photo):

Unavailable Objective-C Class

Click to Enlarge

Build and Run Python Scripts Using Xcode 5

Edit 1 (20th October 2014): Xcode 6.1 instructions can be found here: http://vandadnp.wordpress.com/2014/10/20/building-and-running-python-scripts-with-xcode-6-1/

In this video, I’ll demonstrate how you can use Xcode 5 to build and run Python scripts.

[Feature Request] Audio Comments in Xcode? That would be great!

So I have had this idea for a while. The idea is simple. Audio comments in your favourite IDEs, such as Xcode.

What do I mean by that? Well, think about all the times where you were coding something complex and wanted to leave some comments in the code explaining to a fellow programmer how your algorithm works. Wouldn’t it be better if you could just record your voice and say what the algorithm does? And have that recording attached to the code and viewable right in the IDE?

That would be great!

I know I would use that. To demonstrate, I’ve attached how I envision this feature looking in Xcode (Click on the image to enlarge it)

Leave your comments below if you think this is a good idea too and would like to see it in action.

Audio comments in Xcode

This is a new feature which I hope all IDE makers, like Apple, will start incorporating into their product. I really think this will be the next evolution on code commenting.

Update 1: 11th July 2013:

So after I submitted this feature request to Apple, this is the email I get back from their team:

Hi Vandad,
This is a follow-up regarding Bug ID# 14370555.   
Engineering has determined that this is not to be fixed based on the following information:
OSX has voice over etc. You can also add file links to an audio file in a comment for example. 
Thank you very much for the suggestion.
If you have questions regarding the resolution of this issue, please update your bug report with them.
We are now closing this bug report.
Please be sure to regularly check new Apple products for any updates that might affect this issue.
Thank you for your assistance in helping us discover and isolate bugs within our products. 
Best Regards,
Developer Bug Reporting Team 
Apple Worldwide Developer Relations
Seriously, Apple? VoiceOver? I don’t even think their engineers understood the suggestion :-D