MAZYOD’S
DEVDIARY

Blabbering on, and on, and on…

Swift V

For the record, I needed to use Alfred spell command to be able to spell interoperability correctly …

Anyways, some time ago, Apple introduced NS_ENUM and NS_OPTIONS to Objective-C. Back then, it wasn’t a huge improvement to warrant rolling out these macros that were pretty much handled properly by their C counterparts. However…

If one had a mind as sharp as Kenpachi’s sword, then maybe they’d smelled the scent of what about to come

First, there was the introduction of the 64-bit devices. Sure, it’s ambiguous to know the size backing those enums, but I mean, if you’re that much of an enum fan, I doubt anyone would want to touch your code.

The big cheese introduced this year, namely Swift, actually benefits greatly from those macros (I think they later turned into actual identifiers). When your Objective-C enums are defined using NS_ENUM and NS_OPTIONS, they are properly ported to swift enums when accessed from swift. Here is an example taken directly from my app:

typedef NS_ENUM(NSInteger, ESettingsCellType) {
    ESettingsCellPlain,
    ESettingsCellOptions,
    ESettingsCellSegmented,
    ESettingsCellSwitch,
    ESettingsCellSlider,
    ESettingsCellButton,
    ESettingsCellCheckmark,
    ESettingsCellDownload
};
private let reuseMap: [ESettingsCellType:String] = [
    .Plain     : "disclosure",
    .Options   : "options",
    .Segmented : "picker",
    .Switch    : "picker",
    .Slider    : "picker",
    .Button    : "disclosure",
    .Checkmark : "checkmark",
    .Download  : "download",
]

I am guilty of not using NS_ENUM at first, since this code is as old as my college days take me, but as soon as I migrated, everything ran smoothly.

Pretty cool stuff, this ObjC/Swift thingie…


Static Libraries and Swift

About two years ago, while developing a second Islamic application, I noticed that there is just too much shared code between the projects, and it will only get worse when I start developing the Mac versions. So, it made sense to group the shared code together into a single static library, linked against all the apps.

Honestly, it was just for fun at that time. Using static libraries wasn’t the easiest way, simply importing all the classes by reference would’ve achieved the same result… However, today, the benefit of migrating to a static library really proved to be worth it:

#import <LPEngine/LPEngine.h>

Before explaining what the line above is, let me explain my current situation a bit. I have a completely new design for my app, and since the old code still has bits and pieces written since 2010, along with the urge to write code in swift, I decided to start with a fresh code base, written in swift from the ground up.

Now, since the core logic is all grouped into a static library, instead of having rouge imports all over the place, that code snippet written above, added to the bridging header, was enough to start leveraging the whole library right from within swift…

Conclusion

If you have a project that you know you’ll want to keep around for a while, best make use of best practices, and gift your future-self a piece of mind.


What’s in a Day

I had a lovely, and productive day, so might as well end it with a blog post.

iOS Transitions

In my app update, I am doing some pretty cool, high-profile interactive animation thingies. What is that, you say? To you, I say this:

First, if you are an Android dork, just forget it. There is no way Android will reach this elegance.

Interactive animations are when the animation can either play fully on its own, or be controlled by a gesture from the user:

I really don’t want to explain how they work, as there are two of them tutorials that cover the subject pretty thoroughly.

Design thingies

I came across an app called Sketch. I haven’t tried it yet, but it looks pretty insane. I think it’s worth taking a look at for any developer out there looking to streamline their development process.

More Swift

Swift is just full of surprises… I learned that the didSet, willSet property observers don’t get triggered when the property is mutated in the init method, and for good reason, if you ask me. For example, if the property is non-optional, the old value will be nil, which doesn’t make sense, since it’s a non-nilable property… See? Confusing.

The first use-case for the so called property observers was to implement a highlight effect for my custom drawn UIButtons. Since I use PaintCode to import my assets, all assets are drawn with code. So, I have to subclass UIButton to add the drawing code. The point is, I need to call setNeedsDisplay when the button state is highlighted.

To do that, all I did was:

class VectorizedButton: UIButton {
    override var highlighted: Bool {
        didSet {
            setNeedsDisplay()
        }
    }
}

Yeah, I never new you can override properties that way in swift. Pretty freaking awesome, if you ask me.

Even more on swift, IBDesignable is a pain to implement. This is one reason why the dynamical nature of ObjC rocks. In order to make a Swift class IBDesignable, you need to add it to a separate framework, that can then be built and run by Xcode for interface builder.

The problem with that is if you have linked against any Objective-C static libraries, the compiler will start crying that you can’t do that… I still don’t know what the problem is, I just gave up on IBDesignable.

Storyboards

As embarrassing as it is for me to say that, the truth must be told. Today I touched the awesomeness of storyboards, and truly appreciated the power of creating collection view cell prototypes right inside the collection view. So fast, easy and awesome.

The only problem was trying to use autolayout and the transitioning thingies that I mentioned above. It seemed cumbersome, so I gave up on using autolayout for the container view that transitions between the views.

Conclusion

So many things to say, even more things to do, very limited time to spare…


Creating A Custom Collection View Layout

Today is a sneak peak of my custom Collection View Layout implementation. I wanted it to be as perfect and painless as possible, so I ended up with this:

override func collectionViewContentSize() -> CGSize {
    let width = self.collectionView?.bounds.width ?? 0
    let height = allMetas.reduce(0) {
        $0 + $1.rect.height
    }
    
    return CGSize(width: width, height: height)
}

override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
    return allMetas.filter {
        $0.rect.intersects(rect)
    }.map {
        $0.asCollectionViewLayoutAttributes
    }
}

override func layoutAttributesForItemAtIndexPath... {
    return cellMetas[indexPath.item].asCollectionViewLayoutAttributes
}

override func layoutAttributesForSupplementaryViewOfKind... {
    return supplementaryMetas[indexPath.item].asCollectionViewLayoutAttributes
}

override func layoutAttributesForDecorationViewOfKind... {
    return nil
}

And a preview:

What is this magic, you say? Well, it’s thanks to these meta structures that describe our layout for us. Along with some slick swift functional tricks, this code can’t get any simpler!

I still need to implement sticky headers, and efficient scrolling, so I’ll write a complete post about this when I am done, hopefully!

Shtay tuned!


Swift IV

Today, I’ll present one of my favorite syntactic sugars in swift:

var value = array.reduce(0) {
    $0 + Int($1.rect.height)
}

While trying to sum the result of all the rectangles in an array, I decided to use functional programming. I recalled watching the $ shorthand somewhere, so I decided to give it a try, and Voàla. Can’t get better than this.

Let’s write the previous code in the verbose form, and break it down:

var value = array.reduce(0, {
        (total, current) in 
        return total + Int(current.rect.height) 
})

So… There are three important shortcuts:

  1. We add the closure outside the method call
  2. We get rid of the parameter declaration, and use $n instead.
  3. We get rid of return

Swift III

With swift, we can finally act smarter and use some sexy functional code! Functional operations, unlike python, are added as part of the object type. So, if you have an Array, you’d do something like array.filter to access the functional operator.

I don’t want to go into details of how to actually use the operators, since they are superbly presented over at the Ray Wenderlich site. What I am going to bore you with, however, is how this changes the way you write code.

Remember that time when you had to copy all those CollectionView layout attributes, and mutate each one, creating a new array and sending it as the return value? Let’s check it out in swift, with functional awesomeness:

let layoutAttributes = super.layoutAttributesForElementsInRect(rect)
return layoutAttributes?.map() {
    (attribute) -> UICollectionViewLayoutAttributes in

    let newAttributes = attribute.copy() as UICollectionViewLayoutAttributes
    newAttributes.center = ... // do whatever
        
    return newAttributes
}

How can you not fall in love with that?


Swift II

Apple have really took all that frustration that bottled up in Objective-C developers, and decimated it in Swift.

In Objective-C, you had to do a small dance to configure C struct variables on Objective-C objects. Here is what I mean:

CGRect frame = self.view.frame;
frame.origin.y = 0;

self.view.frame = frame;

This is because when you access view.frame, that returns a C object by value. Any changes you make to it do not reflect back to the view.

In Swift, not only have Apple removed that problem, but went ahead and kicked ass beyond what we hoped for:

view.frame.origin.x = 0     // Works!!
let minY = view.frame.minY  // AWESOME!!
...

So basically, Apple really got rid of that C baggage that included using CGRectGet... stuff..


Swift I

As I am rebuilding my app in swift, might as well share things as I come across them. To my surprise, some really basic stuff have changed and don’t behave as they did in Objective-C.

Class Name

To load UICollectionViewCells from NIB, I use a universal category/extension that loads the nib from class name. Of course, the easiest way to this was:

+ (UINib *)nib {
    NSString *nibName = NSStringFromClass(self);
    return [UINib nibName:nibName bundle:nil];
}

The reason we can use self directly is because self represents the caller class in Objective-C. So, even though this is a category on UICollectionViewCell, the result string from class will be resolved appropriately when we say [MyCollectionViewCell nib].

So, simple enough, let’s try converting the code to swift:

class func nib() -> UINib {
    let nibName = NSStringFromClass(self)
    return UINib(nibName: nibName, bundle: nil)
}

Yay, that was easy… Not. That doesn’t work, and it fails. Let’s print the value of nibName and see why: MyProject.MyClass. In swift, due to the existence of namespaces, the class is prefixed with it’s target namespace. Unless you want to rename all your XIBs, and use the new convention, I suggest you add a global function that extracts the class name from the verbose form. Something like:

var classString = NSStringFromClass(self)
let range = classString.rangeOfString(".", options: .CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)

var identifier = ""
if let dotRange = range {
    identifier = classString.substringFromIndex(dotRange.endIndex)
}
else {
    assertionFailure("Couldn't resolve class: \(classString)")
}

return identifier

Arabic Text on iOS 8

While upgrading our app to iOS 8 SDK, something broke in the usual NSAttributedString method:

[string boundingRectWithSize:CGSizeMake(_suggestedBoundsWidth, CGFLOAT_MAX)
                     options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                     context:nil];

It still works perfectly on iOS 7, but on iOS 8, we were seeing some clipping in our custom fonted Arabic text. Switching to system font would work, but we needed to use custom font anyway.

Thankfully, there was an excellent stackoverflow answer about a less efficient approach that is incredibly accurate. That saved the day!


QRR I

QRR is yet another series, and it stands for “Quick, Random Rant”. Please don’t let me catch you translating QRR without adding that comma. Thanks.

The premise is to just push myself to blog more, so I open the editor without a topic in mind, and start typing.

The Topic

What comes to mind is something I’ve been recently working on, and that is of course, Cocos2d-x. Cocos is an excellent library, but I have learned the hard way that it was the worst possible choice for me. Let me enlighten you why.

It’s C++

C++ is a grownups language. It’s arguably the most powerful language, but it requires you to be mindful about every freakin detail that you write. Writing my game in such a language, over the span of two years, is a nightmare. I learned so many things, and realized how many mistakes I made in the past, as I desperately attempt to fix them.

That characteristic of C++ also implies that you have to write everything yourself. You need an observer pattern? Write it! You need a string formatter? Write it! Seasoned C++ programmers might argue that boost C++ is the way to go, since it implements most of these missing features from the language, but I only realized that after I decided never to write a personal game in C++ again.

It’s Turbulent

Almost every new version of the library comes with changes that break your sufficiently-complex project. Whether it is as simple as deprecations, all the way to core engine behaviors. These changes make a long lived project mostly about maintenance rather than focusing on making the game.

It’s Buggy

No matter what you hear, Cocos2d-X is supported by the community, and is bound to be buggy. It’s not horribly buggy, but you’ll find yourself looking for solutions to the engine every now and then, and you can’t afford that when running a one man show, now can you.

Conclusion

Well, am happy that I actually contributed something today, and by all means, I am not saying stay away from Cocos2d-x! Just be mindful about those issues, and choose a Javascript/Lua binding approach maybe. As for me, I’ll test drive the JS binding for my next game, and try a few other promising engines.


On APNS

Recently, I went back to my undocumented project to implement a few new features that are related to the recent change the the push notification API on iOS 8. I fell into a trap, that I only recalled I’ve fell into it before after falling into it again >__<

Push Notifications

Apparently, you should only call unregisterForRemoteNotifications on rare circumstances. The reason for that is, Apple is saying that you should tweak the push notification behavior on the server side rather than unregistering and re-registering based on the user settings.

An important note here is, the user is able to completely block push notifications from the app through the iOS settings.app. That is how Apple wants users to behave:

Don’t make users disable and enabled push notifications through the app. Instead, there is a single place to manage all notification settings for all apps, and that is in the settings app.

Of course, that quote isn’t from Apple, but I am just shoving words in their mouths from what I can conclude from the docs.

iOS 8

If you haven’t heard, Apple has transitioned in iOS 8 to UIUserNotification APIs, that consolidate the UILocalNotifications and UIRemoteNotifications APIs. It’s nice, and it completely lacks the unregister method discussed above. So, you are forced to do things the Apple-way.

Conclusion

I really hope Apple just stops everything for a whole year, and stabilize iOS, Mac, Swift, Xcode, and all the other new goodies they threw at us. They are all pretty awesome, but lots of issues are surfacing with these new changes.


Spine Skeleton Data Caching in Cocos2d-X

Introduction

While integrating the amazing Spine editor by esoteric software with my cocos2d-x game, I ran into an issue where the game would take a while to load. Since the only thing I changed since the last time I tested the game was add new spine animations, that was most likely the cause of this performance hit.

By following the definition of:

SkeletonAnimation::createWithFile(...);

I realized the runtime was loading the file everytime without any sort of caching going on. Mature frameworks most certainly take care of this task automatically for you (for example, UIKit’s convenient method in the UIImage class that we all use, imageNamed:). Alas, that had to be solved by us, but thanks to open source software, it’s as easy as pie.

The Meat

So, once you see the implementation of SkeletonAnimation, you realize that it creates a SkeletonRenderer object with the named files. That class loads the files into a spSkeleton object, which holds the parsed data in the data member. data is const, and according to the runtime diagram, it should be fine to reuse.

So, here is the solution!

static Map<std::string, SkeletonRenderer *> skeleRendererCache;
if (!skeleRendererCache.at(filename))
{
    auto skeleRenderer = SkeletonRenderer::createWithFile(jsonFile.c_str(), atlasFile.c_str()/*,  0.1 */);
    skeleRendererCache.insert(filename, skeleRenderer);
}

auto cacheData = skeleRendererCache.at(filename)->getSkeleton()->data;

SkeletonAnimation* skelly = SkeletonAnimation::createWithData(cacheData);
skelly->setSkin(skin.c_str());
skelly->setSlotsToSetupPose();
skelly->setAnimation(0, "idle-simple", true);

skelly->update(0);

return skelly;

Conclusion

All hail open source, for which without, this task would’ve been boring, dull, and time consuming!


Amazon EC2

Introduction

As the case is with most developers, I decided to move away from GoDaddy’s PHP hosting, and move to Amazon EC2, because that’s what the cool kids do these days. I have to say, though, if you just want to get shit done, GoDaddy was 100 times less painful. However, after deploying on GoDaddy, I still felt novice and didn’t learn a thing… So, for the sake of improving and learning, EC2 is way better.

Pandora’s Box

The first thing I had to do was run our site on this shiny new server. My choice of poison was Flask. Honestly, bottle would’ve served me just as well, but in any case.

I got the site up and running in no time on my local machine. The horrors started after I wanted to deploy.

Lesson #1: Permissions

If something doesn’t work on Linux, check your permissions.

After following a tutorial step-by-step and setting up apache, along side the wsgi configuration, I got really weird errors from the server. I looked up the logs, nothing. It wasn’t even logging properly.

Banding my head for hours, and stripping down the application to a bare minimum, I finally stumbled upon a solution that suggested checking your permissions. Now, the first thing I do is permissions, before checking if I missed a semi-colon.

Lesson #2: Invest in the Best

Beyond your first option, is a best option.

The wsgi thingie worked! I was happy to see all the things showing when I navigate to our site. It was a happy moment, yet too early to celebrate.

Our site provides a service that needs to be up-to-date on daily basis. Hello, Daemons.

Daemons was a very new topic to me, and the whole Linux thing was, too. I am no sysadmin, and it was torture to work as one. Reality is, I had to do it, anyway.

Code monkey search online for resources…

Code monkey find init.d daemons…

Code monkey thinks this is the best way…

Code monkey wastes hours messing with the syntax..

Code monkey finally searches for alternatives and finds the awesome Upstart.

With upstart, it was as easy as pi to get the daemon running, and it was time to actually put together the daemon script!

Lesson #3: Log is your friend

No matter what application you are writing, just make sure you have logging setup properly right off the bat.

I didn’t really learn that logging is your friend from this experience, but I did invest a lot of time setting up proper logging. What is a better logging mechanism than to get an email when something happens? Get an SMS!

Well, I didn’t setup SMS notification (yet), but email logging is pretty cool by itself. The problem is, python’s default mail handler, SMTPHandler doesn’t have TLS capabilities integrated, so it didn’t work with Gmail accounts. Searching for solutions online, they didn’t seem to work properly for me. That’s when I looked outside python.

I was unfortunate to try and setup email logging through postfix initially, which is a freakin overkill.

It didn’t get any better when I found (sSMTP)[https://wiki.archlinux.org/index.php/SSMTP]. After installing ssmtp, it was easy to send emails through terminal, but I had to go through all the subprocess ride to get something working, and it didn’t work as expected…

After trying to fix it for a while, I went back to look into python again, and found smtplib. This worked perfectly, alongside a simple producer/consumer setup, using Queue, it was working like a charm.

With all that in place, one can now have a little piece of mind knowing that if the server chokes, we’ll get notified right away.

Lesson #4: Automation

Computers are good for two things: Crunching numbers and repetition

I can’t really imagine anyone trying to configure a server and develop on it without having some sort of scripting language in their toolset. If you’re spending more than 1% of your time not writing business logic and solving problems, your process is not automated enough.

That doesn’t only include scripts to make your workflow easier and faster, but also loggers to identify problems quickly and unit testing / regression testing.

Conclusion

If you ever decided to build your backend service on Amazon EC2, make sure you’re doing it for the right reasons. There are many other better and easier alternatives, otherwise, prepare to invest lots of time in this.


Synchronized

Introduction

Whenever I write something about synchronization, I am required, by law, to reference this picture:

If you don’t get it, just let it slide.

Disclaimer: Vim/emacs users, stop reading. Now. Probably.

The Problem

As with all useful articles, we are ultimately aiming to solve a problem. The problem we would like to amend is the slow process of developing projects on a remote sever.

Hence, what we are trying to achieve is Simple, iterative process of developing projects on a remote server

The Story

After launching a Amazon EC2 Ubuntu instance, I moved all my projects to the server in order to run them, and they instantly broke. Thankfully, I had setup a logging mechanism, so I realized what the problems were, but now I need to fix them!

I launch my favorite IDE, PyCharm, and fix those issues, and commit to the VCS. Only problem now is, I need the server to get those changes!

First thing I did was, I would ssh into the server, navigate to the project root, and pull latest, execute a deploy script. This deemed very mundane and time consuming!

I then tried utilizing an old script I had, which uses scp, to transfer my files. The problem now was, scp was transferring everything, every single time. Not only that, but I no longer need the .git directory to be sent, as well as all the patterns that are specified in the .gitignore! Something had to change. It was time to learn something new.

The rsync

After searching on how to exclude files from scp, the answer was: “You can’t. Use rsync, instead”. Best part about this is, rsync comes with so many more benefits other than excluding files, as we we’ll see now.

rsync’s beauty in this context can be described in three points:

  1. Effeciency: Only sends the new/changed files! Doesn’t transfer the whole directory every single time, like scp did.
  2. Control: Using --include, --exclude, you can easily control what gets synced, and what doesn’t.
  3. Organization: By specifying the --delete options, files deleted locally will also be deleted from the remote directory.

Needless to say, that’s all I ever wanted.

The Scripts

Now, let’s take a look at how this works:

def cmd_ec2_rsyc_project(project_path="."):
    """Syncs the project path with the ec instances projects dir, optionally invoking 'deploy.py' remotely"""

    project_path = resolve_path(project_path)
    # Important: Make sure we have a trailing slash! Read more:
    # http://bit.ly/1rYK94U
    project_path += "/" if not project_path.endswith("/") else ""

    # Resolve the remote path
    project_name = os.path.basename(project_path[:-1])
    target_project_path = os.path.join(REMOTE_PROJECTS_DIR, project_name)
    remote_path = REMOTE_ADDRESS + ":" + target_project_path

    # Read more about the extra options here: http://bit.ly/1rYK94U
    os.system("rsync -azP --delete --exclude '.*' {src} {dst}".format(
        src=project_path, dst=remote_path
    ))

    if not os.path.exists(os.path.join(project_path, "deploy.py")):
        return

    # Silver lining: Execute the deploy script after syncing
    os.system("ssh {addr} 'sudo python {script_path}'".format(
        addr=REMOTE_ADDRESS, script_path=os.path.join(target_project_path, "deploy.py")
    ))

Conclusion

With all that setup in the pythonic terminal, it’s as tasty as pie!


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…