The back button typically shows the title of the previous UIViewController, unless it's empty. However, sometimes you don't want to show the title of the previous. Sometimes you have a title that just doesn't make sense to show on the back button.

The easy option is to simply set the back button title yourself to @"Back" with the caveat that it will always be English, no matter what the device's configured language is. The better solution is to temporarily remove the title in the previous UIViewController and re-set it when returning.

The new Facebook SDK for iOS has a convenient way to access user information via the FBGraphUser protocol in a nice "dot-syntax" manner. However, because the FBGraphUser protocol doesn't have an email @property, we can't access all the information like we do with the name (see example below). Nevertheless, as with the previous SDK, the NSDictionary still contains the email kv-pair and other user information, which is not populated via the FBGraphUser protocol and we can access it like we would have done it with a normal NSDictionary (since it still is just a normal NSDictionary).

Recently Google released their beloved Chrome browser for iOS, which supports advanced features like Chrome for your desktop computer. The most interesting among them are the smart suggestions while typing in the omnibox as well as synchronized bookmarks, history and passwords, where especially the latter is a pain to enter on mobile devices, when using long and cryptic passwords.

It all sounds pretty awesome, but there is one problem with that: the default browser for iOS is still Safari. And I guess Apple has no interest in changing that. Luckily Raphael Caixeta came up with a few lines of code, that app developers can add to their application, so that at least those will support opening links on Chrome for iOS where installed. If the user doesn't have Chrome installed, it will gracefully fall back to Safari.

As a developer you simply have to use the following snippet, whenever you want to open an URL with an external web browser:

For jailbroken devices there is another option: Browser Chooser, developed by Ryan Petrich. You can get it by adding rpetri.ch/repo as a repo to Cydia (Manage > Sources > Edit > Add) and then simply search for Browser Chooser.

For those who still don't get it, we can also look at it the other way around:
a 33% discount on something that is 150% results in 100%

150% * (1-0.33) = 100%

and a 50% increase on something that is 67% also results in 100%

67% * (1+0.50) = 100%

Therefore if you're offered either a 33% extra for free or a 33% discount you should definitely go for the discount, since we already learned above, the 33% discount gives you a 50% extra for free.

Another marketing trick people often fall for is double discounting. So if a product has been reduced by 20% and then later on by another 25% percent, most people think 20% + 25% = 45% discount, while the truth is, it's only a 40% discount.

100% * (1-0.20) * (1-0.25) = 60% which is obviously a 40% discount

Note: values have been rounded to make them easier readable. If you perform the calculations yourself and you want precise results, use fractions instead of percentages, e.g. 1/3 instead of 33%.

A brief introduction to Machine Learning by Hilary Mason in her talk Machine Learning for Hackers at Bacon. Unfortunately the video has restrictive settings on vimeo, so I couldn't embedded it directly, but please follow the link.

If you're interested in learning more, you can get a full video lecture from Hilary at O'Reilly.

“I observed something fairly early on at Apple, which I didn’t know how to explain then, but have thought a lot about it since. Most things in life have a dynamic range in which average to best is at most 2:1. For example if you go to New York City and get an average taxi cab driver versus the best taxi cab driver, you’ll probably get to your destination with the best taxi driver 30% faster. And an automobile; What’s the difference between the average car and the best? Maybe 20% ? The best CD player versus the average CD player? Maybe 20% ? So 2:1 is a big dynamic range for most things in life. Now, in software, and it used ot be the case in hardware, the difference between the average software developer and the best is 50:1; Maybe even 100:1. Very few things in life are like this, but what I was lucky enough to spend my life doing, which is software, is like this. So I’ve built a lot of my success on finding these truly gifted people, and not settling for ‘B’ and ‘C’ players, but really going for the ‘A’ players. And I found something… I found that when you get enough ‘A’ players together; when you go through the incredible work to find these ‘A’ players, they really like working with each other. Because most have never had the chance to do that before. And they dont work with ‘B’ and ‘C’ players, so its self policing. They only want to hire ‘A’ players. So you build these pockets of ‘A’ players and it just propagates.”

I just noticed that Facebook provides you with a great experience, when selecting a bunch of friends to invite them to join an event or page. This is especially dragging if you have hundreds of friends, however, Facebook came up with a few tricks to make it a very painless process.

Visual Summary

First to notice is that Facebook doesn't just provide a simple list, where one row equals one item. Instead it puts 3 items in one row, making it much faster to scroll through the whole list. This might not be the best idea for a simple text based list. In Facebook's case, however, they add a thumbnail of the profile picture to each entry, which makes it very easy for the user's eye to scan the list, even if it has 3 columns. You know how most of your friends look like, and if in doubt or in case of a strange profile picture, you can still quickly double check with the name next to it.

Filtering

The second important feature to notice is the filter drop-down menu in the top left corner and the search box right next to it. With the filter you can easily display only the friends, which belong to a certain group or region, while with the search box the displayed entries will be restricted as you type to the entered character.

An additional nifty feature are the filter options Recent Interactions and Selected, where the first one gives you your most important friends (the ones you've interacted with recently), while the second one displays all the selected user, so that you can get a quick overview before hitting the Submit button, without having to scroll through hundreds of entries again.

Selection

And the best part of it is in my opinion the way you can select entries and how selected entries are displayed. Because of the checkbox the user will immediately notice, that this is a selectable item. However, you can not only click on the checkbox itself, but also the related image and text next to it. Which makes it way easier to hit the target, rather than aiming for a little checkbox.

Also, instead of just marking the checkbox as checked, Facebook highlights the whole item with a subtle blue frame and background. Which makes it way easier to differentiate the selected from the unselected items, without having the eye constantly jumping between checkbox, image and name.

Worth noticing is that Facebook grays out users that can't be selected anymore, typically because they've already been invited before or even already joined the event.

"I divide my officers into four groups. There are clever, diligent, stupid, and lazy officers. Usually two characteristics are combined. Some are clever and diligent -- their place is the General Staff. The next lot are stupid and lazy -- they make up 90 percent of every army and are suited to routine duties. Anyone who is both clever and lazy is qualified for the highest leadership duties, because he possesses the intellectual clarity and the composure necessary for difficult decisions. One must beware of anyone who is stupid and diligent -- he must not be entrusted with any responsibility because he will always cause only mischief."

After reading this you might wonder why I would write about something obvious like that. And I agree. It is quite obvious. Once you know about it. However, first I didn't know and neither did the other Java programmers I've spoken to. So I thought it's worth writing up a quick blog post.

Probably all of you already know about enums and use them as type-safe flags or enumerations:

enum Cardsuit { CLUBS, DIAMONDS, SPADES, HEARTS };

That is pretty basic and probably everyone learned that in Java 101. What was new to me, though, is that you can customize the enum { } pretty much like a class.

So for example, one day I was working on a XML parser implementation, where depending on an attribute value of a XML element I had to make a decision. Since in XML everything is a String I wrote a quick method which compares an enum to a String. But I didn't know where to put it in my code. I figured the best place would be within the enum itself. Not really thinking that it would work, but still curious I tried the following:
I tried to compile it and voilà: it worked! No errors, no warnings.

In my actual XML parser I then would only have to do the following:

if ( Cardsuit.CLUBS.compareToString(xmlString) ) { .... }

Of course there would have been many other ways to do this, but this solution seems quite clean and elegant to me.

If you have a media heavy application it is very likely that you store the image, sound or video data on the sd-card, since it gives you a lot more space than bundling everything with the application. Also, it enables you to dynamically add, remove or modify your media data.

However, the problem that comes with it is, that all your media is public now and can be read by other applications, e.g. the Gallery App, which scans the whole sd-card for image files. To prevent other applications from scanning and displaying your media files, you can simply add an empty file called .nomediain the root folder of your media data.

Name of the file signaling the media scanner to ignore media in the containing directory and its subdirectories. Developers should use this to avoid application graphics showing up in the Gallery and likewise prevent application sounds and music from showing up in the Music app.

Especially in mobile development you most likely have some client-server communication going on, which is often the source of a lot of problems and long debugging sessions. To make the debugging easier it is helpful to see what each side sends or receives. There are two UNIX tools that can come in quite handy in such situations:

Both a very powerful tools and you can do a lot of stuff with them (e.g. write your own web server with a shell script). However, in this post we will keep it simple and focus on debugging a HTTP (JSON) communication between a web server and a mobile client (iPhone, Android, but could be pretty much any kind of client).

Listening to incoming requests

We start a listening server with

nc -lk $ip $port

-l: listen

-k: forces nc to stay listening for another connection after its current connection is completed.

$ip: the IP/interface you want to bind to. Use 0.0.0.0 to bind to all interfaces and IPs.

$port: the port you want to bind to. Doesn't really matter which one you use, as long as the client uses the same one to connect to.

{"id":3,"jsonrpc":"2.0","method":"sendTestMessage","params":{"clientVersion":"0.11.4-debug","user":"sk@geekmind.net","imei":"32420214181983746","message":"This is a test message :-)"}}

In green the HTTP header and in orange the actual content, in this case a JSON-RPC message. While the header is mostly irrelevant to us, it might in some cases contain useful information to detect the source of the problem. However, more interesting, and in most cases more prone to errors is our own "custom protocol" and its implementation. By evaluating the content section we can now easily compare if there is a difference between what we were expecting to receive and what the client was actually sending out.

Sending "fake" requests to a server

Sometimes the problem may not be in the client's implementation of our communication protocol, but on the server side. The complementary approach to the above example is to send "fake" requests to our server and look at the response we get.

In red the response we got from the server. In this case we used a real username with a wrong IMEI and tested if the server generates the right response. In our case the server correctly produced an error.

If you want to directly monitor a real connection I suggest that you have a look at tools like Wireshark and tcpdump. Wireshark has a GUI and is fairly easy to understand. It also helps to have a server instance running on your local machine (development server), so you don't need to figure out how to tap into your phones WiFi connection.

Here is a really well-made video about futuristic interfaces in a completely interconnected home environment. It shows the beauty and usefulness that comes with it, but also points out the inherent problems of complete interconnectivity.