Swift Weekly – Issue 10 – The Swift Runtime (Part 8) – Switch Statement

I was thinking of writing an article this week about the switch statement but i almost fell asleep half way through the article. that’s super boring. to write it even! so I thought I’ll do something more exciting and that is looking at how theswitch statement and its complementary case statement works.

Click here to read the full article on Swift Weekly’s GitHub page…

Advertisements

Swift: Convert Unmanaged to String

Edit 1 (20th October 2014): Apple has now fixed this issue. To convert an unmanaged object to managed, just use the takeUnretainedValue() or the takeRetainedValue() method on it, based on whether you want to take a retained or unretained value.

So let’s say you have an Unmanaged<AnyObject> value that you know internally contains a value of type CFStringRef and you want to convert this to a value of type String in Swift. This is how I have managed to do that:

func convertCfTypeToString(cfValue: Unmanaged!) -> String?{

/* Coded by Vandad Nahavandipoor */

let value = Unmanaged.fromOpaque(
cfValue.toOpaque()).takeUnretainedValue() as CFStringRef
if CFGetTypeID(value) == CFStringGetTypeID(){
return value as String
} else {
return nil
}
}

Shown in Xcode it looks like this:

Screen Shot 2014-07-07 at 14.43.52

Creating string enumerations in Objective-C (The ultimate solution)

A while ago I wrote on my blog about a solution to one of the most common questions asked by Objective-C programmers which is “How can I create string enumerations?”. Well, the solution that I’ve given has immediately become one of the top subjects that attracts developers to my blog, as I can see in my stats. I thought I should now take it to a whole other level and get rid of the limitations that I had presented in the old solution, and come up with a fresh perspective.

The following video is the result of my work on this subject. I hope you’ll enjoy watching it.

Getting the most out of your WiFi dongle data plan (The definitive guide)

I am currently facing a situation where I need to carry out my work while I am connected to a WiFi dongle. I have spent about £20 for 6GB of data that can be used for up to 3 months, whichever comes first. So I have now learnt a lot of tricks on how to minimize my data usage and save money. Here, I want to share with you some of these tricks.

Trick 1 – Disabled images in your browser

If you view the web without images, your browser does not have to load those images from the internet so you will save A LOT of data. Every browser is different so I cannot tell you how to do that on every browser. Here is how to disable the loading of images on Safari on OS X:

  1. Go to Safari Preferences
  2. Go to the Advance tab
  3. At the bottom of the Advance tab, find the “Show Develop menu in menu bar”
  4. Then close the preferences window
  5. Go to the newly-shown Develop menu and choose Disable Images

That’s it. Some websites will not look nice without images and that just shows you how some web developers have now become too reliant on using images! Their fault really.

Trick 2 – Use Git commands carefully

I use Git through the terminal and two of the most useful commands that I use quite often are git fetch and git rebase. Now, git fetch, will fetch every new branch and all change-sets from the server and brings it into your local machine. What you want to do is to replace git fetch with the following command:

git fetch origin NAME OF BRANCH

So if you are on a branch named “ios7” and you want to just bring the remote changes on that branch to your local repo, do this:

git fetch origin ios7

git rebase origin/ios7

Now you got only the changes in that branch and you rebased to the latest changes

Trick 3 – Use Adblock… A LOT

Install Adblock on your browser and go to your popular websites and start blocking anything that looks useless and will consume your data. So just start blocking all content that is irrelevant.

Trick 4 – Disable Flash

I don’t have to explain this. Flash videos are memory, CPU and data hungry. They consume your battery so fast it is unbelievable. Just disable Flash to make sure your browser will not try to load those darn Flash videos for you.

Trick 5 – Stop watching videos on websites

Do not go to YouTube and other streaming video websites. They are very data hungry no matter how low you have set the quality of the videos. Watch videos when you are on a proper broadband, not on a tiny WiFi dongle.

Trick 6 – Subscribe to websites with push notifications

I read MacRumors quite a lot. I go to their website probably 3-4 times a day. But instead of doing that, it’s best that you subscribe to push notifications from news websites that offer that service. Then you can get push messages directly to your OS X desktop of new content that get posted on those websites instead of going there every time you want to check the news. A push notification will only contain the new article, not the whole website. But if you go and browse the website, you are viewing everything that is on the front page at least, hopefully without the images, as one of the tricks you learnt earlier!

Trick 7 – Stop opening a browser page ever time you think you’ve lost your internet connection

We all do this. When we think we have no internet connection, which can happen on a daily commute on a Wifi dongle, we open our browsers and navigate to our favorite website. If the website loads, we go “Aha, it works”. Instead of that, do this:

  1. Open Terminal
  2. Type this: ping http://www.apple.com

Once you see ICMP packets going and coming back, you know at least ICMP is working and you are almost 99.99% sure that your internet works.

Trick 8 – Do not preload top hits in your browser

Users of Safari or most modern browsers know that when they type in the search field for anything, a few “suggested” websites and terms will appear automatically. For instance, if you start typing “blood”, in your search field in your browser, you may get suggested words such as “blood pressure”, “check your blood sugar level”, and etc. Every time you type something in your browser’s search field, your browser will hit your search engine and look for suggested words and links. This will take battery and will use your internet. To disable this in Safari, follow these steps:

  1. Open Safari Preferences
  2. Go to the Privacy tab
  3. In the “Smart search field” area, click the “Prevent search engine from providing suggestions”
  4. In the same area, click the “Do not preload Top Hit in the background”

Okay that is it for now. These are all the tricks I have up my sleeves for saving you some data usage on your WiFi dongle. If you have any other tips that you believe are worth sharing with others, please let me know and I will include them here.

Enjoy

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! 🙂

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 🙂