Skip to main content

"Delivered" — iMessage's Problem

An iMessage, sent to someone who owns an iPhone, that can not be delivered to that iPhone, can never be "Delivered".

My wife inherited my old iPhone 3GS when I got the iPhone 5. She wasn't with a sanctioned iPhone operator in Belgium so she didn't get the APN settings OTA. I didn't think of checking them and setting them manually. So, she did not have an active data connection to her phone when she was out of the house.

We set up Messages at home when she was on Wi-Fi and Apple recognised her number as being linked to her Apple ID. Or is it iCloud ID? That dichotomy's another story... Now, when I started sending her texts they never reached her because during the day she is not at home, and Apple's servers couldn't connect to her phone.

Yet, whenever I text her Messages.app said the message was "Delivered". It got delivered alright, to her iPad that was lying at home, connected to our Wi-Fi network.

The reason must be that Apple's servers check for any device registered for receiving iMessages with the receiver's Apple ID. When it can reach one device it sends the message through and responds success to the sender. The sender has no idea to which devices the message arrived, all he gets to see is "Delivered".

Usually, when people send texts they mean to reach someone's phone. That's their primary target. If iCloud can sync it to iPads, iPods and Macs that's great but the phone remains most important.

With the above in mind (someone who has an unreachable phone but another device which can be reached) three situations can occur, one of which can be easily remedied, one is a bit harder and one where nothing can be done.

  1. Sending from iPhone. Apple should check the devices registered with the recipient's Apple ID, if it can reach the iPad but it can not reach the iPhone it should send the iPad message as per usual but also fall back to sending an SMS to the unreachable iPhone. Currently it does not fallback to SMS as soon as another non-iPhone device can be reached.
  2. Not sending from iPhone, but the sender has an iPhone. Apple should check the devices registered with the recipient's Apple ID, if one of them is a non-reachable iPhone it should then check whether the sender has a (reachable-via-data-connection) iPhone registered to his Apple ID. If so, then Apple can contact the iPhone and have it send an SMS to the recipient's phone to make sure the text gets delivered. Only if the sender has the fallback-to-SMS setting turned on of course.
  3. Not sending from iPhone and the sender has no iPhone. There is no way the message can be delivered to the non-reachable iPhone. I assume Apple does not have SMS servers in every country to make this happen on their behalf instead of using the sender's iPhone. But then it should not say "Delivered". It could say "Delivery failed." and show a popup with more info.

Solving situation 1 and 2 would help Apple get back on track with their "It just works" meme. It's a technical challenge, trying to get texts delivered any way they can. It's a interesting problem to solve. And when solved it would be magic. The user does not need to know how. It should just work.

Situation 3 would occur less frequently I think. People who don't have iPhones are less inclined to use iMessage.

With all of Apple's new services and software in the past couple of years... it has come to a point where a lot does not "It just works" anymore. More articles like this one will get written until they start fixing their software. Apple's hardware is drastically improving, their software department has been lacking.

I hope Apple will devote 2013 to doing nothing else but making things just work again.
Like it used to be.

Mastering MAMP's Metadata-Munching MySQL

Since this post ran a bit long I've included a TL;DR section.

The Problem

MAMP's MysQL uses a shared InnoDB file "ibdata1" which grows over time and never shrinks. Not even when dropping databases. All the metadata and indices for all databases stay in there forever.

The Solution

Tell MySQL to store medata and indices in separate files per database.

  1. Dump all databases in files and drop the databases.
  2. Delete ibdata1, ib_logfile0 and ib_logfile1.
  3. Add innodb_file_per_table to the [mysqld] section of /etc/my.cnf
  4. Restart MySQL and reimport the dumped databases.

The Article

Recently I had to import a MySQL dump of 9GB resulting in a database of 21GB. I didn't have enough space on my hard drive and after continuously deleting applications and music as the import went on I realised I wouldn't make it. I aborted the process and dropped the partial database. Funnily enough I noticed I didn't get all my space back. After a little scooting around on the file system I understood something I had been suspecting for a while already. MAMP's default MySQL settings suck.

jeroen@liver:/Applications/MAMP/db/mysql$ ls -hl | grep ibdata1
-rw-rw---- 1 jeroen admin 14G Nov 4 16:25 ibdata1

I've always been slightly opposed to using MAMP for serious work but the company I work for uses it and their setup scripts expect folder layouts the way MAMP sets them up. Now, after a year of using MAMP on a 128GB MacBook Air I saw the shared InnoDB file MySQL uses had grown to 14GB. That is a lot of wasted space.

Why is it wasted space you might ask? Surely MySQL needs it for something. Yes, MySQL needs it. It stores the _current_ database-indices in there as well as the metadata for them, you can even restore whole databases, after having dropped them, from this InnoDB data file. But, it also stores all that information for databases you have already dropped. See, MySQL's ibdata1 file never shrinks, it only grows.

As a web developer working with Drupal for about a year now, one of the things I do a lot is importing databases of ongoing projects, dropping them when I screw up and reimporting a backup to try again. Therefore I bet not too many web-developers know about MAMP's hungry MySQL or I would've heard about it earlier.

There is a solution and it is called innodb_file_per_table. When you put this in the MySQL configuration file it tells MySQL to store the metadata and indices for each database in a separate file within that database's folder. Then, when you drop a database and MySQL deletes the folder it will also remove the metadata files.

If you're wondering where you can find the MySQL config file your best guess is /etc/my.cnf unless of course you're using MAMP because it just starts MySQL with any meaningful parameters, neither does it install a my.cnf anywhere MySQL looks for one. (More info here: http://bensch.be/mysql-config-with-mamp) You can copy one of MAMP's default MySQL config files to /etc/my.cnf. Look for them under /Applications/MAMP/Library/support-files/

None of MAMP's MySQL config files however include the innodb_file_per_table setting so make sure to add this to the [mysqld] section of the file you chose to copy to the /etc/my.cnf:

innodb_file_per_table

When you restart your MySQL server it will start putting the medatadata in the database folders that will be created from then on, unfortunately this does not get rid of the huge ibdata1 file. All current databases must be dumped and dropped first, then the ibdata1, ib_logfile0 and ib_logfile1 fils can be deleted. MySQL can be restarted with the innodb_file_per_table setting in place and the dumped databases can be reimported.

You'll be saving gigabytes of disk space in your day-to-day development.

While I was writing this post I came across this Stack Overflow answer: http://stackoverflow.com/a/4056261 It tells the same story but with a bit more detail about what's in the ibdata1 file.

Have Vim Recognise Drupal's .module Files As PHP

OS X's Vim doesn't by default recognise file-types when opening files.
You can turn it on by adding following lines to the .vimrc file in your home directory.

$ echo -e "filetype indent on\nsyntax on" >> ~/.vimrc

This will add "filetype indent on" and "syntax on" to the file, or create it if it doesn't already exist. The "syntax on" is needed or Vim won't recognise the filetypes.

Now Vim will recognise file-types, indent them and colour the syntax of the recognised files.
Drupal however puts a lot of PHP code in .module files. These .module files aren't recognised by Vim as being PHP files.

We can tell Vim to interpret .module files as PHP by modifying the "Virata" piece of code in Vim's filetype file at /usr/share/vim/vim73/filetype.vim from:

" Virata Config Script File
au BufRead,BufNewFile *.hw,*.module,*.pkg setf virata

to:

" Virata Config Script File or Drupal module
au BufRead,BufNewFile *.hw,*.module,*.pkg,
\ if getline(1) =~ '<?php' |
\ setf php |
\ else |
\ setf virata |
\ endif

If you don't have access to the global filetype.vim file you can also put these lines in your own home directory's .vimrc.

Next time you want to edit a .module file in Vim it'll detect it as a PHP file. Some of you might say, no-one uses Vim, but when you quickly need to check/hack something on a server, chances are you'll be connecting through SSH using Vim to make the changes, so this might come in handy. Do set up your server-accounts' vim in such a way that viewing PHP in Vim becomes a bit more bearable.

Other settings you can put in your ~/.vimrc that might help you live with Vim are these:

set ruler " Show a ruler on the bottom
set expandtab " Expand tabs as spaces
set tabstop=2 " A tab is 2 spaces
set softtabstop=2 " Typing a tab in insert mode is 2 spaces
set shiftwidth=2 " Indent 2 spaces
set smartindent " Be smart when indenting
set title
set cindent
set hlsearch " Highlight searches
set incsearch " Search incrementally

Apple's Single-Threaded Mail.app.

Last weekend we bought a new computer for my mother. Until then she had a 5 year old hand-me-down white MacBook whose battery was dead, still had a physical trackpad-button, the power-cable near the connector was completely ripped and the palmrest-edges weren't just cracked, they were gone.

Time for a new one we thought, so we got her Apple's entry-level notebook, the MacBook Air. A notebook no other computer manufacturer seems capable of matching in terms of price, build-quality or industrial-design finesse.

Whatever.

The problem was with setting the thing up. Apparently we got a model of MacBook Air which had been sitting on the shelf for a while as it did not come with OS X Mountain Lion and when running Software Update it had to pull in so much data, both software and firmware updates, that it choked when it tried to install them and just reported an error.

Running Software Update again triggered a re-download of the whole 1.6GB before failing again with the same error. Third time's a charm I thought but I went about it less... intuitive. I thought it'd be a good idea to download the firmware updates first (one by one) and apply those before trying the rest of the software updates. That eventually worked. So Apple, you have a problem when applying these two types of updates in one go.

This is not something "normal" people would be able to pull off. It was quite upsetting. Imagine having to take it back the next day because on day 1 something as simple as a software update kept failing, after having downloaded a huge amount of data, repeatedly.

After downloading 1.6GB of updates, three times, we got an up-to-date OS X Lion. It was getting late already and I didn't even dare mention anymore that another 4.3GB Mountain Lion download was in tow.

Anyway, the title of this post has to do with a single-threaded Mail.app. When we got to setting up her mail account, we found Mail.app beach-balling all the time. Whatever got clicked it beach-balled a minute or two before we could click again. I had enough and said I'd take the MacBook Air home and bring it back the next day because I had had enough. (Why does Apple gear only ever works flawless with me, I don't know.)

That same evening I found out that a MobileMe account got pre-installed, probably after entering her iCloud credentials. OS X Lion's Mail.app pre-populated itself with a MobileMe account. MobileMe, as we know, does not exist anymore. Mail.app was constantly trying to reach MobileMe's mail server, couldn't find it and started timing out, taking the whole Mail application with it. I patiently beach-balled my way through Mail.app's settings until I could hit the button that deleted the MobileMe account.

How could anyone ship a Mail application that completely hangs as soon as one mail account has problems connecting to the server? It's beyond me.

Fortis Fail

Recently Fortis started offering their "Easy Banking" application on iOS, which lets you do bank-transfers from your iPhone or iPad.

Before you can use "Easy Banking" you need to enable it on Fortis' website first where you have to choose a password. The problem I ran into was with their input validation on the password fields.

The default way of choosing a password is to type it twice, in separate input fields. One part of the validation is checking whether the two inputs are the same. Often it will also check the minimum length of the password. Or even the max-length, although I advise against that. You can't argue against longer passwords... Worse is when companies start checking your input and only allow certain character-sets. There's no point in this at all... People make their passwords more complex by adding in non-alphanumeric characters, they type them correctly, twice... and then the company says they have to simplify the password they're used to, or they won't take it. That is just ridiculous.

But with Fortis it's even worse. The problem is two-fold.

First, on the Fortis website where you choose your "Easy Banking" password, it does not allow non-alphanumeric characters in your password. That is silly in itself but the bigger problem is that they skip over input in their fields when a non-alphanumeric character is typed. Try to imagine... when you are hitting a '%' or '(' or '@' or any other non-alphanumeric character it just does not _type_ it in the field. This is so bad I can't even start describing it.

Thus, suppose your password has a '#' in it... let's say "p#ssword", without the quotes. If you type that in Fortis' input fields you will see this: ••••••• You tab to the next input field and repeat your password, again you see, without error: •••••••

You click OK and everything goes well. Fortis accepts the password because the passwords in both fields match. Cool, you think. I've got my password set up. Now let's get my iPhone and try out "Easy Banking"...

This is where we see the 2nd part to the problem.

In their iOS app's password field... unlike on their website, it does _not_ skip over non-alphanumeric characters. So when you type the above password in the app as you try to log in it will show: ••••••••

You hit "Login" and the application will fail to log you in because you provided wrong credentials. You then need to wait 2 minutes before trying again... With the same result, you can not log in. If you go back you'll see that on the website you only really typed 7 characters, Fortis took out the '#'... The iOS app takes 8 chars, as it should. No app should ever alter the password data you input in the field.

A user will not understand this… He did everything right, saw no error, but he cannot sign in.

I do not understand how BNP Paribas Fortis, a major bank, can be this outright ridiculous in the way they create their applications. Who do they think they're doing a favor by not allowing non-alphanumeric chars _and_ not telling their customers about it when they're just skipping over those characters. People effectively think they typed something twice but the password that is accepted by the website will be different from what you typed... You actually have to start counting the dots in the input fields to know if they match the amount of characters you have in your password.

Hopefully this will soon be fixed, but I'm afraid they don't even know about it themselves. This is a typical case of UX fail when companies try to validate too early and auto-correct input, definitely when dealing with people's passwords, on a banking website.

Location Of my.cnf With MAMP

"How on earth do I tell MAMP to use my own MySQL configuration?"

Chances are you've heard this question one too many times if you're a web-developer... It's also been driving me crazy for about an hour.

Turns out MAMP isn't that bad after all, good thing I refrained from tweeting angry things about them. Granted, they do still suck (their little UI that never disappears is horrid, as well as the incapability of restarting one service, and, they should put their stuff in System Preferences as a PreferencePane, just like the official MySQL has)

In any case, here's what to do if you can't figure out where to put your my.cnf when working with MAMP. To have MySQL print out its help, listing the different paths in which it will look for a my.cnf configuration file, sorted by order of preference, type the following on the command line:

mysql --help | grep cnf

Part of the output should be the following line:

/etc/my.cnf /etc/mysql/my.cnf /Applications/MAMP/conf/my.cnf ~/.my.cnf

Perfect, a couple of locations MAMP's MySQL will look for the my.cnf for and /etc/my.cnf is the first location it will try.

If you were like me you didn't even consider putting it in /etc and tried figuring out where to put it under MAMP's folder. Turns out it's not necessary as /etc/my.cnf will do. But, as an added bonus, it tells you where to put it should you want the my.cnf file under MAMP's folder anyway.

Another tip: in case you've got multiple MySQLs installed make sure you're using MAMP's MySQL by entering the following command: which mysql

We Should Not Use Azerty In Flanders.

Opmerking: Dit hele artikel is in het Engels, wat raar is want ik spreek hier tot Vlamingen. Wie snel wil zijn scrollt naar de onderste lijn van het artikel om de synopsis te lezen.

There is no reason at all why the people in Flanders (northern part of Belgium) should type on computers with azerty keyboard layout. Azerty is for optimized for people who speak, and thus write, French.

Here in Flanders we speak Dutch. Dutch is our mother tongue. It's all we hear, speak and write. The reason why Belgium has azerty keyboards is historical. The french-speaking used to reign over Belgium and so it became the standard keyboard layout, because it fitted the ones in control best. Our country is indeed bilingual, but its regions where each language is spoken are so well-defined that it's absurd to force one keyboard layout upon the whole country. There are even more people who speak Dutch than there are who speak French!

The less-populated southern part of Belgium speaks French, they benefit from having azerty keyboards, but not many people in Flanders speak French well enough (let alone need to write in French a lot) to warrant the optimized-for-French azerty keyboard layout, the country wide standard, while all they'll ever do is type in Dutch or English. English is far better known among young flemish people than French these days.

In The Netherlands, bordering Flanders, they also speak Dutch. We share the same language. Guess what keyboard layout they use in a country where everyone speaks Dutch... Right. Qwerty. Qwerty is the keyboard layout for people that speak Dutch. The second language in The Netherlands is English, and if we're honest it is in Flanders as well. French has withered away to being a course-subject in school.

So, the Flemish would be way better off typing on qwerty keyboards. They're also far more convenient on notebooks than azerty. Plus you won't freak foreigners out when they quickly want to show you something on your computer. People say that they're used to typing on azerty and it would be difficult for them to switch to qwerty. That's not true. It's not difficult but you'll only see the azerty-drawbacks once you type qwerty. The Flemish are typing on azerty out of habit. Well if it's a habit it's a bad one. Nothing that can't be unlearned.

These are the main disadvantages of azerty:

  • The 'a', a vowel, is not under your finger, but in the worst possible location.
  • You need to hold shift for every digit you want to type.
  • You need a special key (Alt+Gr) just to type an '@' or a backslash.

For programmers there are extra disadvantages:

  • The placement of the parentheses and curly/straight brackets is horrible.
  • You need shift for every dot ('.') you type.

It's even worse on Apple keyboards. I would definitely advise against buying an Apple notebook with an azerty keyboard layout because it makes you miss out on basic OS X functionality.

Switching between apps in OS X is done with cmd+tab. Switching between windows of the same application in OS X is done with cmd+backquote, where backquote is conveniently placed right above the tab-key on a US Qwerty Apple keyboard. Guess what, the backquote isn't even on an Apple azerty keyboard.

For programmers on Macs it gets downright ridiculous, it's not even funny anymore. Here's the list of keys you don't have on an azerty Apple keyboard, but are indispensable for programmers:

  • No backquote:`
  • No tilde: ~
  • No backslash: \
  • No pipe: |
  • No curly brackets: { and }
  • No square brackets: [ and ]

You then ask yourself, but what if I do have to type French characters on my qwerty keyboard in Belgium? Well, if you're using a Mac there's no problem at all, because that got fixed in software. You can type any variation of a vowel by holding down that key and a pop-up dialog will appear where you can choose the variation, or you can learn the very logical keyboard shortcuts for the french vowel-variatons. To be complete I'll sum them up:

  • alt+e e = é
  • alt+` e = è
  • alt+u e = ë
  • alt+i e = ê
  • alt+c = ç

And then, again Apple specific, if you are convinced you don't need to type on azerty, a keyboard not fit for your primary languages, and you decide to go with qwerty, buy a US QWERTY keyboard and not Apple's hideous International Qwerty. I don't know why they ever even came up with this aberration. But unless you want your backquote, tilde, backslash and pipe in other-than-the-default locations, and a ridiculously small vertical return key to boot, you should buy US QWERTY, the only standard qwerty keyboard layout on an Apple computer.

To sum it all up, people of Flanders:

Koop geen azerty, het is niet gemaakt voor onze taal. Wij spreken geen Frans. Wij spreken Nederlands, zoals Nederlanders. Dus koop qwerty, en als je een Mac koopt, koop US QWERTY.

Nexus S ICS Update... Clarity?

Some people at work have Nexus S phones. Last month in December Google announced those devices would get Android 4.0 (ICS) via an Over The Air (OTA) update. The guys at work are still waiting. Apparently with Android updates you just have to wait indefinitely until an update notification pops up and then you'll get to download the new software update. Such uncertainty would drive me nuts.

To illustrate "Android Clarity" just google for iPhone iOS 5 update. The very first result at iPhone's company website [ http://www.apple.com/ios/ ] explains how to do it. It says:

"Update to iOS 5. Just connect your device to your Mac or PC and follow the onscreen instructions in iTunes."

Now google Nexus S ICS update. All you get are lots of shady tech-blogs without real answers. No google.com page in sight. When I did the search the first link to google.com was the 17th result. It was a forum post from someone who was clearly very angry with how his update process had gone.

Google has stopped the OTA update in "certain regions" but they're not saying which regions. From searching around the Internet it seems everyone (read: a vocal minority) is having problems with Google's OTA ICS update on Nexus S phones.

Is anyone still getting ICS updates on Nexus S or has Google completely halted the rollout? And if you look around the Internet for what ICS is doing to your Nexus S, would you still want to update?