MAZYOD’S
DEVDIARY

Blabbering on, and on, and on…

The Daily WTF III

In today’s wtf, we will looking at a very peculiar case.

The Fail

While going over the code, I noticed a very strange block. The programmer was constructing a JSON payload from available variables and then passing the payload to the visible view controller, like so:

NSString *vanityURL = params[@"vanity_url"];
NSDictionary *payloadParams = @{@"endpoint" : @"story/profile",
                                @"params" : @{@"vanity_url": vanityURL},
                                @"type" : @"story"};

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payloadParams
                                                   options:0
                                                     error:nil];

NSString *payload = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

params = @{@"feedbackPayload" : payload,
           @"user_vanity_url" : vanityURL,
           @"analytics_key": vanityURL,
           @"title": vanityURL};

I really don’t want to get into the details of where these hardcoded strings came from, or why the hell a JSON payload is created in the first place, but there is no limit to how bad code can be, apparently.

NOTE: I added newline separations for the reader to be able to read the code. It was actually all smushed together without any spacing.

… One more fun fact, this code lies in the infamously abused AppDelegate class.


A Post About Nothing

Inspired by an episode from Seinfled, I decided to make a post about nothing. Well, I do have to write something, so it will be an improvise of whatever comes to mind.

What Is Nothing

Some might argue that in programming we have null, which is nothing. However, if null is nothing, then what is void?

I think null in most programming languages is just a sentinel value, hence it is something. Although some languages, like python and swift, actually have “nothing”, which is the None type. If you have a function in python that returns nothing, and you try to assign the return to a variable anyway, that variable will hold None, which is literally nothing.

Is It Important?

It is very important to have this concept of a well defined “nothingness” in a language. If you have it, you can easily express the nothingness of something…

I mean, in a typical case scenario, we might have a method that returns an int. If for some reason that method might fail to calculate the return type, we would want to return something to indicate the calculation failure. In a language like objc, we use NSNotFound, which is just INT_MIN. But what if that value is a possible value returned by the method?

So, adding a nothingness provides a consistent way of expressing a no-value thing that the caller understands.

Conclusion

(null)


Singletons Hidden Poison

The singleton design pattern is an extremely convenient weapon to utilize in any software project, be it a game, app, or whatever. For many years, I used singletons, and slowly formed a mental image of how they work. Today, I realize how poisoned my code is because of these treacherous snakes.

Singleton Flaws

It is widely known that the main issue with singletons is that you need to make sure that you will ever need one object of the singleton class you’re creating.

Another issue with singletons is how they seep through the code, and are hard to clean up once created, hence most use cases, if not all, require that the singleton instance is never destroyed. This global access also promotes contention and tight coupling, which is bad ®.

The Poison

Moving on to the poison about the singleton pattern, it is actually part of the global access issue. After creating that singleton instance, one would be very tempted to access everything through that singleton instance. I’ll explain with the problem I fell into:

When writing a game, I made the GameScene a singleton instance, since the game has so many layers and sublayers (objects) hierarchy. So, initially the intention was pure. I just wanted an object deep within the hierarchy to be easily able to send messages to the GameScene if an action happened…

The problem started when I ended up using the singleton instance to fetch information about the game.. Instead of initializing a layer with the necessary data, I would just initialize it normally, and query the singleton for the data. Sooooo bad…

The main issue with this is … I can no longer test the components in separate/isolated context! The GameScene, along with all the layers that query it, have been tied by the chains of fate, and became this inseparable, monolithic component, which ended up being a burden on testing and maintainability.

Conclusion

When the use of singletons is necessary, try using dependency injection, but in general, avoid relying on them for immediate convenience, and do your job of properly designing the object hierarchy and data flow!


The Daily WTF II

This one is my favorite, and was the first wtf I fixed, because it was so bad…

The WTF

In iOS, we have view controllers, and the whole app is built around the concept of view controllers. Now, someone decided that if we are going to present a modal view controller, the view life cycle calls are no longer relevant, and they used a cached boolean for a check (not even bothering with self.presentedViewController) (/facepalm_all_the_way_to_the_back_of_my_skull):

- (void)viewWillAppear
{
    if (self.modalPreseted) {
        return;
    }

    [super viewWillAppear];
    // ... more stuff
}

- (void)viewWillDisappear
{
    if (self.modalPreseted) {
        return;
    }

    [super viewWillDisappear];
    // ... more stuff
}

Why Is It So Bad?

These methods are provided by UIKit, and we are overriding them. These methods are sacred, and are expected to execute the way they are designed to be executed.

As an iOS developer coming to the project, it’s hard and painful enough to learn the code base and the custom implementation, and now you expect me to unlearn UIKit, and learn those hacky ways that don’t even make sense?


How to Compose

In a previous post, I talked about the beauty of composition. Today, I want to extend on that with a beautiful enlightenment that I had. Lucky you, I am gonna share it, and you are reading it!

Breaking It Down

It is all about breaking those methods calls down!

Let’s assume you are building an application that authenticates with different services, like twitter, facebook, google, … etc. If you have this in your code, you’re doing it wrong (I used python because it’s easier to write):

class AuthManager(Object):
    def authenticateWithTwitter(self):
        ...

    def logoutFromTwitter(self):
        ...

    def authenticateWithFacebook(self):
        ...

    def logoutFromFacebook(self):
        ...

authManager = AuthManager()
if user.selection() == 'Twitter':
    authManager.authenticateWithTwitter()

elif user.selection() == 'Facebook':
    authManager.authenticateWithFacebook()

Now, notice how you can achieve a much more modular design with even better readability:

class AuthManager(Object):
    
    def __init__(self):
        self.twitter = TwitterService()
        self.facebook = FacebookService()

authManager = AuthManager()
authService = None
if user.selection() == 'Twitter':
    authService = authManager.twitter

elif user.selection() == 'Facebook':
    authService = authManager.facebook

authService.authenticate()

I know, I could’ve used getattr, but that’s not the point. The point is how we managed to break the long method name into a nicely composited object!! This is actually the obvious example, let’s see a bit more challenging one:

class Person(Object):
    
    def __init__(self):
        self.name = "Kirito"
        self.DOB = datetime.now() # whatever

    @property
    def age(self):
        """Compute age from DOB"""
        return ...

    def getLocalizedAge(self):
        """Return a localization friendly age"""
        return LocalizationManager.instance().localizeNumber(self.age)

    def getLocalizedDOB(self):
        """Return a localization friendly date"""
        return LocalizaitonManager.instance().localizedDate(self.DOB)

You can see it now, can’t you ;) YES!! This is bad, and should be changed to:

class Person(Object):
    
    def __init__(self):
        self.name = "Kirito"
        self.DOB = datetime.now() # whatever
        self.localized = PersonLocalizer()

    @property
    def age(self):
        """Compute age from DOB"""
        return ...

person = Person()
person.localized.DOB()

Conclusion

I don’t think I will ever write anything in the blog of more value than this post… I desperately needed this advice ages ago.


The Daily WTF

I just can’t take it anymore.. I have been quite conservative of some really wtf code, and it’s going on the blog form now on.

Apparently, we have these two methods in our class:

1
2
3
4
5
6
7
8
9
- (void)requestFacebookPermissionsWithCompletionHandler:(void (^)(NSArray *permissions, NSError *error))completion
{
    ...
}

- (void)requestFacebookPermissions:(void (^)())completionHandler
{
    ...
}

Here is the best part:

THEY SERVE COMPLETELY INDEPENDENT PURPOSES.

While refactoring the code, I did cleanups to the method names, so in the process, both these methods had the exact same name… Who in their right mind would do such a horrible thing…


The Beauty of Composition

On of the highly debatable problems that we come across as programmers is the classical inheritance vs composition problem. It haunts us as we try to figure out how to group duplicate code across multiple classes, and today the rant shall be about that.

Hierarchical

A language like Java uses the keyword “extends” to indicate inheritance. I love that, because it helps the code become more readable, and it becomes clear to any programmer what our class’s relationship is to its superclass.

From there, you just have to keep in mind that when you design your class hierarchies that any superclass within that hierarchy will impose itself as an “alias” to the subclass… I don’t think that was clear, so let’s see an example:

Let’s say we are designing a “View Controller” hierarchy. In UIKit, the developers decided to go with ViewController, then under that comes CollectionViewController, TableViewController, … etc. Notice that TableViewController can still be called a ViewController, so we say that ViewController is just an abstract alias of TableViewController.

Notice also how this imposes the type of hierarchy we have here. We are essentially making a controllers hierarchy based on the type of view they have. This isn’t a must, it’s just how developers of UIKit/AppKit decided to go.

That’s all nice and dandy.. The trouble starts creeping in when the developers want to extend these classes to provide their application-specific hierarchies.

So, in the problem I am having, we have a bunch of ViewControllers that are related to the login process. The duplicate code that we want to eliminate is related to the HUD loading indicator that we show when the authentication process starts, and then removing it when the authentication is complete.

The code I came across made the obvious approach of defining a LoginViewController superclass, and extended that class in the different login service (facebook, twitter, email). The only problem here is that some of the classes are TableViewController while others are not! So, if they all inherit from LoginViewController, they either all have to be TableViewController or plain ViewController, depending on what LoginViewController derives from…

Composite

Now, we reach the composite approach. In the problem described above, we simply inherit from TableViewController or ViewController in each of the login classes depending on the use case. This hierarchy matches what we see in UIKit so it is the best approach. How about the duplicate HUD code?

We simply have to define a new class, call it AuthHUDController. That class will then be instantiated in those classes in a single line of code, then some customization can be made to it per use case, giving us more flexibility.

Ideally, we would want to eliminate all duplicate code, including the instantiation of the AuthHUDController, but doing that without ending up with a weird and implicit implementation (using AOP or similar) is very tricky, and would probably be best avoided.

There is actually another composite solution, and that is to make LoginViewController a subclass of ViewController, then in the classes that were deriving from TableViewController we move the table view code to a new class, and make that a composite in the old class.

In any case, it’s both using the beauty of composition.

Conclusion

The problem ends up not being that difficult if we realized the above definitions and sticked to them!


Solving Programming Problems

At sourcebits, I realized that whenever our technical lead wants to convey an idea to the team, he would always do that through a visual graph. He would quickly put together an FSM diagram, a flowchart, or whatever to materialize his thoughts and make sure we can all clearly see his idea.

I thought that was cool, but didn’t quite do it myself because I work on my own project alone. The thing I realize now is that Joe, our tech lead, might’ve also used charts and graphs to organize his own thoughts and think about the problem, because I started doing that, and it’s insanely helpful!

Here is an example of a problem I am trying to solve:

As you can probably tell, this is the matchmaking process in the game, and using yEd, I can easily draw this FSM and make sure I account for all situations.

Now, I am stuck at that last state. If the user presses “accept” to the matchmaking, we poll the match status to see if the other user accepts. If the user’s device crashes, or the user kills the app, our game won’t be able to report that the user is no longer available, so we have to set the match state as INVALID after a certain amount of time…

Sounds simple, although it isn’t with the constraints I have. I can either have the client disconnect if a certain amount of time passed, but that doesn’t concern the client app. It should be as dumb as possible and just poll the match status. If that magically becomes INVALID by any other means, then we can close the dialog.

So, this “magical” way of invalidating the match… I can think of two ways of doing this:

One approach is to add a timestamp variable to the session, and each time the user polls the status, we have some logic in the backend checking the timestamp to determine if the match should be invalidated. The problem is that we don’t know exactly when the match state has switched from “looking for opponent” to “waiting for confirmation” (aka accept). We have to store the previous state and all that crap.

Another approach is to associate the timestamp with the match object, and check the timestamp from the match itself. This is easy to implement and the logic actually fits. Once we change the match state to WAITING_CONFIRMATION, we can set the timestamp then.

Conclusion

Try drawing diagrams for your problems, it will help you model a solution!!


Lessons from Jenkins

Introduction

Recently, I was privileged with the task of configuring a mac mini server with Jenkins to automate our build process, and distribute new versions OTA using HockeyApp.

The task was anything but smooth. I did not expect Jenkins to have so many bugs!! Well, less Jenkins, and more the plugins that are around it. Anyways, let’s dive right into it.

Hello, Jenkins

Before anything, you probably want to give yourself remote access to the Jenkins server. Configuring jenkins through VNC, SSH, or other indirect manner is not feasible, as you’ll probably spend quite a few hours working on Jenkins.

Fortunately, this is quite simple. First, make sure that your server is secure by setting up some authentication method. This is done in Jenkins preferences. Choose whatever suits you, so long as not anyone with that knows the IP address of the server and port number can access Jenkins. That would be really bad.

A word of caution: While setting up the credentials, make sure you give the anonymous user full privileges, and only remove them once you’ve set everything up. You could end up locking yourself out of the server, otherwise. (which is easy to fix, but better avoid it altogether)

Once that is setup, open the Jenkins config.xml (possibly located in ~/.jenkins) and change the value 127.0.0.1 to 0.0.0.0. I forgot the exact name of the key, but just tells Jenkins to accept incoming connections from all addresses.

YAY! Now you can play around with Jenkins from your iPad.

Hello, Xcode

This is when I realized how really aweful those plugins for Jenkins are. They are suppose to serve as a UI replacement for common commands used by Jenkins users, but they ultimately fail to deliver. I am sorry if the truth hurts, but I did waste a lot of time on them, and that hurt as well.

If you want to see for yourself, download the Xcode plugin for Jenkins, and just try to build your project through it. It’s hard to specify the freakin details, especially if you have a complex project setup. On top of that, it always added an argument that broke my build, and you can’t turn it off..

In any case, I prefer and ultimately used Shenzhen, which is part of the Nomad cli package. My thoughts?

So painless, so simple, so awesome.

# Unlock the keychain
security unlock-keychain -p PASSWORD

# Increment the build number
agvtool next-version -all
# build the IPA
ipa build --scheme TellyApp-On-Commit --configuration Ad-Hoc
# distribute through hockey app
ipa distribute:hockeyapp -m "Jenkins build" --token

The few lines of script above replaces two Jenkins plugins, the Xcode one and the HockeyApp distributor one.

Hello, GitHub

Github uses a concept called “Webhooks” to do a very convenient thing for us. Once a push has been made to master, or a pull request is submitted, we can tell github, through webhooks, to submit a POST request to our server informing it about the change. This rids us of polling the SCM for changes, and even get instant results!

Those webhooks were a nightmare, though. Throughout the guides I read, there was nothing specifying that you should choose the urlencoded content type instead of the application/json, but you have to do that. Another issue is that Github sends a ping notification first, which fails… I tried to make it work, but ultimately found out that it’s not supported by the Jenkins Github plugin. It is destined to fail, I guess :( …

Thank You, Knowledge Sharing People

This is a very detailed and organized article on integrating Jenkins with Xcode. Another important resource was this simple set of steps that helped me debug a few issues.

Goodbye, Everyone

That was what it took to get it up and running! The devil is in the detail, and I am sure I am missing bits and pieces here and there… The main take away is: DON’T RELY ON PLUGINS UNLESS YOU ABSOLUTELY MUST.


How to Logout from Hockeyapp

As silly as it may sound, but there doesn’t seem to be a way for the HockeyApp user on Mac to sign out once he signed in…

With just a tiny bit of knowledge about how the Foundation framework offers app the ability to save preferences, I realized I can probably delete the preferences file:

$ defaults find hockey
[... huge lump of text, and somewhere in the middle:]
Found 19 keys in domain 'com.hockeyapp.mac': {
[...]

With the domain of the app figured out (maybe I could’ve just checked the app bundle’s info.plist?), it was as simple as:

$ defaults delete com.hockeyapp.mac

And now, I have been signed out!


I Am Blogging, Again!

Holy crap… It has been so long since I last blogged, I missed this awesome feeling of typing things into the computer. In any case, onto the blog!

Introduction

I have came into an important realization today, and that is, the programmer’s philosophy. I am not sure if there is such a thing, but if there isn’t, there sure should be one and it should be taught to all programmers..

Time to Get Philosophical

What is programming? Jk, not that philosophical, just a tad bit.

Before a programmer writes code, there must be something that they want to achieve. That goal is (in most cases) well defined, and can be verified. The approach the programmer takes to achieve that goal can be in so many different ways, I dare say infinite.

Recently, I found myself writing contradicting code. This is because my philosophy hasn’t been laid out before hand, and the span of the project exceeds a whole year, which made me change philosophies quite often…

Time to Get Practical

In my example, I’ll talk about this game backend I have been writing…

So, writing backend code is awesome. There is no GUI involved, it is just pure data manipulation.

Initially, I started writing and designing the backend in such a way that the client doesn’t compute the “business logic”. This means, that the backend does the computation for the frontend, and sends the result…

Today, I while I was implementing this new feature, I decided I want the client to compute the result instead, forgetting that the rest of the code depends on the fact that the backend should compute the logic! I did that because I was thinking about moving computation costs to the frontend.

The moment I realized how I had set everything else up to compute the results in the backend, I switched the implementation to follow that philosophy immediately, and that’s when I came with this important realization…

Time to Realize Things

First, my former self is no idiot. He didn’t decide to compute the logic on the backend for no reason! It was because of security concerns, and that was arguably the right choice, I can still see that.

The issue, though, is when I tried to make the frontend compute the result, I kept bumping into hurdles and obstacles that were very annoying. I am suppose to be at a stage of development where the base is all laid out, why the hell is it so hard to add this simple thing!!

Yes, the realization being, I’m doing it wrong! It is a relief that I am in sync with my former self, so I consulted him, and he told me about the computation thingie… The problem begins when you start working with a team or an open source project.

Conclusion

I love how python, lua, and many language specify their philosophies, but I don’t think there are enough of them out there.


What the Snippet

I am really getting used to this video blogging business. It feels like I want to make all future posts videos. So easy, so convenient…

This one is about using Xcode snippets to speed up your development. I present a use case with cocos2d-x, but it can be used with anything really… Even Swift ;).

Here are the snippets. Just drag the code over to the snippets area in Xcode:

class <#class#> : public <#superclass#>
{
    
public:
    
    static <#class#> *create(<#args-definition#>);
    virtual bool init(<#args-definition#>);
    
};
<#class#> *<#class#>::create(<#args-definition#>)
{
    <#class#> *obj = new <#class#>();
    obj->init(<#args#>);
    obj->autorelease();
    
    return obj;
}

bool <#class#>::init(<#args-definition#>)
{
    if (!<#superclass#>::init(<#superargs#>))
    {
        return false;
    }
    
    return true;
}

Regex Fun

Today, I went on a regex mission to refactor our code base, and ended up replacing a huge lot of code with macros, which saved us around 450 lines of code throughout the project. Now, we can use those macros to work faster, too!

Here are all the commands I wrote, good luck figuring anything out :p

$ search_grep NSNotificationCenter\s+
$ search_grep NSNotificationCenter\\s+
$ search_grep "NSNotificationCenter\\s+"
$
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$ search_grep "NSNotificationCenter\\s+"
$
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+selector"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+selector\\((\\w+)\\)"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+@selector\\((\\w+)\\)"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+\@selector\\((\\w+)\\)"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+\\@selector\\((\\w+)\\)"
$ search_grep "\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+selector:@selector\\((\\w+)\\)"
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:(\\w+)\\s+selector:@selector\\((\\w+)\\)\\s+name:(\\w+)\\s+object:(\\w+)\\]"
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ blog_new_post regex-disaster
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:(.*?)\\]"
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*(.*?)\\]"
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*(.*?)\\s*\\]"
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]"
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]"
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]" "NC_ADD\\(\\g<1>, \\g<2>, \\g<3>\\)"
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]" "NC_ADD\\(\\g<1>, \\g<2>, \\g<3>\\)" ""
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]" "NC_ADD\\(\\g<1>, \\g<2>, \\g<3>\\)" 0
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]" "NC_ADD\(\\g<1>, \\g<2>, \\g<3>\)" 0
[[NSNotificationCenter defaultCenter] addObserver:tar selector:@selector(sel) name:nam object:nil]
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:nil]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*nil\\s*\\]" "NC_ADD(\\g<1>, \\g<2>, \\g<3>)" 0
$
$ search_grep "NC_ADD\\(.*?\\)"
$ search_grep "NC_ADD\\(.*?\\);"
$ search_grep "NC_ADD\\(.*?\\);\\s+NC_ADD"
$ search_grep "(NC_ADD\\(.*?\\);)(\\s*?\n)+(\\s*NC_ADD)"
$ search_replace "(NC_ADD\\(.*?\\);)(\\s*?\n)+(\\s*NC_ADD)" "\\g<1>\n\\g<3>"
$ y
$
$ search_grep "(NC_ADD\\(.*?\\);)(\\s*?\n)+(\\s*NC_ADD)"
$ search_grep "(NC_ADD\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)"
$ search_g "(NC_ADD\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)"
$ search_replace "(NC_ADD\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)" "\\g<1>\n\\g<3>"
$
$ search_grep "\\[NSNotificationCenter"
[[NSNotificationCenter defaultCenter] addObserver:tar selector:sel name:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotification:notif]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotification:notif]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] removeObserver:tar]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s+addObserver:\\s*(.*?)\\s+selector\\s*:\\s*@selector\\s*\\((.*?)\\)\\s+name:(.*?)\\s+object:\\s*(.*?)\\s*\\]" "NC_ADDO(\\g<1>, \\g<2>, \\g<3>, \\g<4>)" 0
$ search_replace "(NC_ADD\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)" "\\g<1>\n\\g<3>"
$
$ search_replace "(NC_ADD\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)" "\\g<1>\n\\g<3>" 0
$ search_replace "(NC_ADDO?\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)" "\\g<1>\n\\g<3>" 0
$ search_replace "(NC_ADDO?\\(.*?\\);)(\\s*?\n){2,}(\\s*NC_ADD)" "\\g<1>\n\\g<3>" 0
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotification\\s*:\\s*(.*?)\\s*(.*?)\\s*\\]" "NC_POSTN(\\g<1>)" 0
[[NSNotificationCenter defaultCenter] postNotification:notif]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s*(.*?)\\s+object\\s*:\\s*nil\\s*\\]" "NC_POST(\\g<1>)" 0
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*nil\\s*\\]" "NC_POST(\\g<1>)" 0
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s*\\]" "NC_POSTO(\\g<1>, \\g<2>)" 0
[[NSNotificationCenter defaultCenter] postNotification:notif]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
$
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s*\\]" "NC_POSTO(\\g<1>, \\g<2>)" 0
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s*\\]"
[[NSNotificationCenter defaultCenter] postNotification:notif]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
$ search_grep "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s+userInfo\\s*:\\s*(.*?)\\s*\\]"
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*postNotificationName\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s+userInfo\\s*:\\s*(.*?)\\s*\\]" "NC_POSTOU(\\g<1>, \\g<2>, (\\g<3>))" 0
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*removeObserver:\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s+userInfo\\s*:\\s*(.*?)\\s*\\]" "NC_REMN(\\g<1>, \\g<2>)" 0
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*removeObserver\\s*:\\s*(.*?)\\s+name\\s*:\\s*(.*?)\\s+object\\s*:\\s*nil\\s*\\]" "NC_REMN(\\g<1>, \\g<2>)" 0
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*removeObserver\\s*:\\s*(.*?)\\s+name\\s*:\\s*(.*?)\\s+object\\s*:\\s*(.*?)\\s*\\]" "NC_REMNO(\\g<1>, \\g<2>, \\g<3>)" 0
[[NSNotificationCenter defaultCenter] removeObserver:tar name:nam object:obj]
$
$ search_replace "\\[\\[NSNotificationCenter\\s+defaultCenter\\]\\s*removeObserver\\s*:\\s*(.*?)\\s*\\]" "NC_REM(\\g<1>)" 0
[[NSNotificationCenter defaultCenter] removeObserver:tar name:nam object:obj]
$
$ search_grep "NC_REM\w*\\(.*?\\)"
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] postNotificationName:nam object:obj userInfo:uInfo]
[[NSNotificationCenter defaultCenter] removeObserver:tar name:nam object:obj]
[[NSNotificationCenter defaultCenter] removeObserver:tar name:nam object:obj]
[[NSNotificationCenter defaultCenter] removeObserver:tar name:nam object:obj]
$

Regex Disaster

It was such a painful lesson, almost as painful as my previous bash lesson, only mildly less awful.

Le me once wanted to write pretty bash code:

~$ var=5    # Ugly!
~$ var = 5  # better...

… Only to realize that the second line is an error. The script I was modifying was not through interactive shell, so I had no idea what is was throwing errors… Till this day, whitespace haunts me in my sleep.

As for the regex part, it was this:

regex = r"(?:.*\n.*){0, 3}"

This looks like a perfectly healthy regex expression, except that it is not. Adding that extra space within the braces made the whole thing break and produced unpredictable results. Don’t do that.



Event Dispatcher

A special post is happening this time, and it is a video! We will explore the new cocos2d-x Event Dispatcher, and how to use it as a replacement for CCNotificationCenter.

Without further ado:

Here are some relevent code snippets:

#define gEventDispatcher Director::getInstance()->getEventDispatcher()
#define NC_ADD(target, notif, handler) gEventDispatcher->addEventListenerWithSceneGraphPriority(EventListenerCustom::create(notif, handler), target);

Technological Lust

I grew up reading that lust is one of the deadly sins, but according to wikipedia, it can take many forms, including lust for knowledge, which is good, right?

I just got inspired to spill what is in my head and write about the tons of things I want to learn and try doing, so here it goes:

Haskell Game

You are not a programmer if you haven’t tried doing any functional programming. Actually, you can be, I was just exaggerating.

The premise is that functional programming is a new way to tackle programming problems and bends your thinking from looking at thing imperatively to another holistic view (I think).

I haven’t tried functional programming yet, and hence the idea of writing a game in Haskell.

Web Development / Ruby

I really wish I set some time aside and refactor my whole blog such that I know exactly how each and every thing works. After that, begins the fun of importing different frameworks and writing Ruby scripts for Octopress to streamline the process even more and make it awesome.

Cocos2d-X / Qt

I am already contributing to Cocos2d-X, but they seem to be interested in implementing a Mac client for the Cocos Studio, and it would be awesome if I can work on that. What would be even more awesome if I were to make it in Qt and make it multiplatform, while learning the Qt framework (since I am sick of the stupid Cocoa framework).

Pixel Art

I have started learning pixel art for a while, and abruptly stopped :( I need to get back to that..

Conclusion

Doesn’t look like much, actually!! Need to get serious about stuff.


Rant

I had this urge to just write a blog post, but don’t exactly know what to write about… Something broke along the way, I should be blogging like twice a day on average.

Anyways, let me see what should the first topic be…

Refactoring

I have been spending most of my extra energy refactoring the code I am working with at work. Some code hasn’t been visited since 2012, and I am just looking at the code, and I am thinking … “I have to understand what this does”. You see, you can’t really go into the flow state without a full clear idea of a macro perceptive of what you are working on.

Let’s track back a bit, I am saying too many things…

One, the flow state. You can only be truly productive if you enter this state. In order to enter this state, you need a clear goal, and very strong understanding of the work that has to be done. Basically, there is no flow state when you are just staring at the screen trying to understand something.

So, while I am looking around understanding code, I come across old code, which of course, is “bad” in terms of the current state of the project. Instead of enduring the pain of understanding the code, I go ahead and refactor it as well, so my future self, or other programmers don’t endure it, as well.

The process of refactoring is awesome because it actually allows you to enter the flow state even though you don’t understand the code, and you are trying to understand it! HOW?!

Let me pull a real example:

// FROM
[UIView animateWithDuration:1.6
                 animations:^{
                     dispatch_async(dispatch_get_main_queue(), ^{
                         int64_t delayInSeconds = 1500; //milliseconds actually
                         dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_MSEC);
                         dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                                [self doSomething];
                        });
                     });
                 }
                 completion:^(BOOL finished) {
}];

Anyways, this is code that hasn’t evolved as fast as the project.

So, while in complete focus, you see that the code is in dispatch_asyc, and then another dispatch is made. Obviously, we don’t need both, so BAM. Get rid of the outer async call.

Then, you see the milliseconds actually comment, and you simply rename that variable, and delete the comment. It’s a systematic process. You just apply what makes sense. Now, you got rid of that async call and useless comment.

Finally, you realize the delay can be added to the animateWithDuration call, and after you do that, the code doesn’t work anymore! You go into doSomething, and voala! There is another animateWithDuration call, and that’s why it didn’t work.

All this, as I mentioned, is systematic, and you can easily submit to the flow, and before you realize it, you have this code instead:

// TO
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
    [self doSomething];
});

Now, if anyone dares looks me in the eye and says refactoring is a waste of time, I’d probably lose hope in that individual’s future.

Yes, this is real code I dealt with.

Google Tag Manager

Because, why not?

Recently, I was asked to implement Google Tag Manager in our application for marketing purposes, and I’d like to share my thoughts on this beast.

We haven’t used it much, but my initial thought is.. WOW.

This beast is like a container for your “tags”. A tag is basically an addon that drives your application. This addon can be other apps, custom data, … you name it! All managed from a single slick web interface over at google’s website.

So, after integrating your app with GTM, all you have to do as a developer is deal with this single SDK! The powers it gives you are:

  1. Pull custom data from backend. (Customization)
  2. Integrate with apps on the fly. (AdWords, analytics, .. etc.)
  3. Manage container versions, and be backward compatible!

Yeah, it’s pretty darn awesome. Will post later how it actually performs, though.

Decorator Pattern

I made use of the decorator pattern, so I might as well share that! :D

The premise of the decorator pattern for GUI systems is that .. You decorate the base view with decorators! So, the decorator I wrote simply applies a “popup” effect, by rounding the corners and adding a close button at the top left corner.

Pretty neat stuff! Now, any view you want to show as a popup is developed independent of this aesthetic look… Truly awesome stuff. MUCH, MUCH better than the naive approach of “Uh, yeah, let’s just subclass”.

Reading

Opposed to my lack of blogging recently, I have been reading… and reading A LOT. If I am walking.. Just walking, and not responding to emails, whatsapps, … etc, I am reading something. To the point that, I walked the whole Mall of the Emirates back and forth to take a passport pic, and while walking, I finished 5 chapters of my book.

I am not sure it’s good or bad, but it’s sure productive! Walking is now coupled with reading, and is no longer irritating. Sometimes while walking, some (me) get affected by their surrounding negatively, and could flip their mood completely. But reading, and immersing yourself in that book instead of what’s around you, … is bad, actually. One ought to be more social than that…

Food

Without feeding, we can’t survive… Wait, wth am I writing! OK, I need to go eat .. NOW.

Conclusion

I like blogging… I wish people would blog more often, and especially people like Abdullah Al-Shalabi. Freaking awesome stuff he puts up on those posts.


Cocos2d-X v3

If you haven’t read the cocos2d-x forums yet, there has been a radical change to the cocos2d-x github repo. Basically, the team decided to abandon ship! No, they just moved from the develop branch to the new, shiny v3.

It wasn’t that bad of a migration for me. All I needed to do is follow the instructions in the post referenced above, and apply my own patches and changes. One issue was converting Point to Vec2… I mean… Whatever. Cocos should be renamed to something more meaningful if they aren’t gonna use ANY Cocoa conventions!!


A Challenge

I am collaborating on a iOS project, and the team is using Xcode. The issue with Xcode is that it doesn’t do any kind of #import management.

The challenge is to write a script that simply checks the import and searches the file for that class. If not present, remove that import. This is naive, since that imported file might contain other headers, variables, … etc, that are needed, but for the purposes of getting this over quickly, we will overlook that part.

5:11 pm: START!

Obviously it’s gonna be python…

5:16 pm:

Instead of defining a function that taken a path pointing to a file, I should make it take a string, so I can easily test it when I am done!

def clean_imports(file_contents):
    # stuff

5:24 pm:

I am slow… And I wish I used PyCharm for this, not sublime. Anyways, v0.0.0.1 is working!

import os
import re

def clean_imports(file_contents):
    """"""

    import_regex = re.compile(r'#import\s+"(\w+)\.h"')
    check_regex_raw = r"{}[^(\.h)]"

    all_classes = []
    for match in import_regex.finditer(file_contents):
        all_classes.append(match.group(1))

    print repr(all_classes)

clean_imports('#import "thisisatest.h" akdjsf a;ksldfj')

5:33 pm

I think it is done, and ready to be hooked with a “crawler”.

import os
import re

def clean_imports(file_contents):
    """"""

    import_regex = re.compile(r'#import\s+"(\w+)\.h"')
    check_regex_raw = r"{}[^(\.h)]"

    all_classes = []
    for match in import_regex.finditer(file_contents):
        all_classes.append(match.group(1))

    for klass in all_classes:
        check_regex = re.compile(check_regex_raw.format(klass))

        if not check_regex.findall(file_contents):
            file_contents = file_contents.replace(klass, klass + "NOTUSED")

        else :
            print repr(check_regex.findall(file_contents))

    print file_contents

clean_imports('#import "thisisatest.h" akdjsf a;ksldfj thisisatest ')

5:37 pm

Time to test!!

import os
import re

def clean_imports(file_contents):
    """"""

    import_regex = re.compile(r'#import\s+"(\w+)\.h"')
    check_regex_raw = r"{}[^(\.h)]"

    all_classes = []
    for match in import_regex.finditer(file_contents):
        all_classes.append(match.group(1))

    for klass in all_classes:
        check_regex = re.compile(check_regex_raw.format(klass))

        if not check_regex.findall(file_contents):
            file_contents = file_contents.replace(klass, klass + "NOTUSED")

        else :
            print repr(check_regex.findall(file_contents))

    return file_contents

if __name__ == "__main__":
    walk = os.walk(".")

    for dirname, dirs, files in walk:
        src_files = [x for x in files if x[:-2] in [".h", ".m"]]
        for afile in src_files:
            filepath = os.path.join(dirname, afile)
            with open(filepath) as f:
                contents = f.read()

            new_contents = clean_imports(contents)
            with open(filepath, "w+") as f:
                contents.write(new_contents)

5:43 pm

Tested… found so many bugs… Try to spot them. Time to run this beast!

5:48 pm

Fail. This is the worst idea I had ever. Xcode refused to compile anything when it saw the #import “blahblahUNUSED.h”. The premise was to comment it out type of deal, but it doesn’t work like commenting it out.

Need to revisit this later.

Conclusion

Whatever.. It was a nice exercise anyways.