martes, 18 de marzo de 2014

Hybrid Mobile Apps: The worst of two worlds

When you ear the word hybrid you think of something made joining the best parts of two (or more) different things. Like the hippogriff, a winged horse with the head of an eagle, you can ride it (because it's a horse) and it can fly (because it has wings). Well, in the RealWorld™ things aren't that simple.

In the mobile apps world, it's often called hybrid apps those that are written in HTML+JavaScript and then executed in a webview but also are packaged in a native wrapper so they can be distributed through the corresponding store.

All the apps that run inside a webview (hybrid and webapps) are always slower than the native ones. This is so because they need a really big chunk of code, called the webview, to be loaded into memory in order to interpret the code your actual app is written in (HTML+JavaScript). This is like a lazy clerk between you and the System (or between your app and the OS).

It is also bad in the other world: you still need the native development environment (even though, you make all the coding in other language) to create the binary wrapper. And then, you need to submit it to the store to pass the validation process with all the waiting time.

If you want to access some of the hardware capabilities (like the camera, or the compass) you'll have a very bad time dealing with complex libs or plugins. And they will add another layer to your, already slow, app.

They say that another big advantage is that your app will look and feel consistently among all platforms. Sorry to say, but I don't think that's an advantage. I, as a user, want all the apps in my device to look and feel consistently, I don't care about other platforms. As users from other platforms don't care if the apps they use look the same like in my device. The only person (or group of) interested in that is the ones that pays the bills, so they can look at the app and see they all are the same and be satisfied (but only because they don't care about the users they only pay the bills, and while they don't realise they should care about the users they will be doing bad apps).

Another of the "advantages" of the hybrid apps, they say, is that you only need to know HTML and JavaScript and you can begin doing apps for all the platforms. Well, I must say, once you know object oriented programming is not very hard to learn another language (so you can make native apps). The problem comes when the bill-paying guys don't want to spend too much and they hire cheap programmers that only/hardly can code in HTML to make an app in a couple of weeks (if you pay peanuts you get monkeys)

viernes, 18 de octubre de 2013

Automatic app creation and binary upload

So, you finally realized that all the apps you are doing are very similar. They all have some many things in common that you created a pool of parts from where you pickup the ones you need for you next project and compile all together. If you are as lazy as I am, you probably made all of this automatic so you only needs to select the modules needed and everything else is made by your steward (mine is called Jenkins).

The problem now is that you cannot upload your new and shinny app automatically to the store. There's a tool from Apple (iTMSTransporter) to make lots of things automatically but not the creation of the app profile. I was looking for a tool that helped me with this task and I found itc.cli, a great tool indeed, but it doesn't do all I needed. What to do in this cases? Easy: modify it to fit your needs (and share the changes so everybody can benefit from them). So here is my version:

With this two tools I could create a script to upload apps automatically to the AppStore. Deatails are as follow:

First, we need to create the App profile in the AppStore. For that we can use itc.cli. It needs a config file with all the information for the profile (sure you can get all of this from your database, and create this file automatically). Config file example:
{"config": {
    "images": {"file name format": "app_data/{device_type}/{index}.png"},
    "device type aliases": {
      "ipad": "iOS-iPad",
      "iphone": "iOS-3.5-in",
      "iphone 5": "iOS-4-in"
  "application": {
    "new app": {
      "default language": "en",
      "name": "Test App",
      "sku number": "myOwnIdentifier",
      "bundle id": "*",
      "bundle id suffix": "myOwnIdentifier",
      "availability date": "Jan 01 2014",
      "countries": {},
      "price tier": 0,
      "discount": false,
      "version": "1.0",
      "copyright": "Me",
      "primary category": "Productivity",
      "app rating": [0,0,0,0,0,0,0,0,0,0],
      "large app icon": {"file name format": "app_data/icon.png"},
      "screenshots": {"iphone": [1,2,3,4,5],"iphone 5": [1,2,3,4,5]},
      "description": {"file name format": "app_data/description.txt"},
      "keywords": "test,keywords,deleteme",
      "support url": "",
      "marketing url": "",
      "privacy policy url": ""
    "app review information": {...}}}
And then run the tool with the commandline:
/usr/local/bin/itc create -c /apps/upload/myOwnIdentifier.json -v --username --password myS3cr3tPassw0rd
This will create a profile for your app in the AppStore. Now, we need to upload the binary, and can be done easily with iTMSTransporter, except for one thing: you need to setup the app in the waiting for upload state before you make use of the transporter. That's probably because of that stupid question from the US Export Regulations: Does your app use cryptography?

If your apps are simple and you always select NO in that question you can use my modified version of itc.cli to do that automatically:
/usr/local/bin/itc binary -a APPLE_ID --username ...
But, now we have a problem, we don't know the APPLE_ID of the newly created app. Well, you can use iTMSTransporter to get it:
/usr/local/bin/iTMSTransporter.woa/iTMSTransporter -u -p myS3cr3tPassw0rd -v off -m lookupMetadata -vendor_id myOwnIdentifier -destination /tmp/ >/dev/null 2>&1 && cat /tmp/myOwnIdentifier.itmsp/metadata.xml | grep apple-id | cut -d ">" -f2 | cut -d "<" -f1
And, finally, we can upload the binary. For that we'll need a config file like this:
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="" version="software5.1">
            <asset type="bundle">
                    <checksum type="md5">
The command line for this last step:
/usr/local/bin/iTMSTransporter.woa/iTMSTransporter -u -p myS3cr3tPassw0rd -m upload -v critical -t Aspera,Signiant -k 100000 -f /apps/upload/itms/ -success /apps/upload/success -failure /apps/upload/failed -loghistory /apps/upload/logs/iTMSTransporter.log -errorLogs /apps/upload/logs/errors
This will upload all packages in the /apps/upload/itms/ directory and move them to the success or failed directories as the result of the upload.

As a summary, you can put everything together in a script:
# Create JSON config file:
/usr/local/bin/access_DB_and_build_JSON > /apps/upload/$APP_ID.json
# Create a new profile in AppStore:
/usr/local/bin/itc create -c /apps/upload/$APP_ID.json -v --username --password myS3cr3tPassw0rd
# Get the apple_id of the new app
APPLE_ID=`/usr/local/bin/iTMSTransporter.woa/iTMSTransporter -u -p myS3cr3tPassw0rd -v off -m lookupMetadata -vendor_id myOwnIdentifier -destination /tmp/ >/dev/null 2>&1 && cat /tmp/myOwnIdentifier.itmsp/metadata.xml | grep apple-id | cut -d ">" -f2 | cut -d "<" -f1`
# Change status of the app
/usr/local/bin/itc binary -a $APPLE_ID --username --password myS3cr3tPassw0rd
# Create XML config file:
/usr/local/bin/access_DB_and_build_XML > /apps/upload/itms/$APP_ID.itmsp/metadata.xml
# upload binary
/usr/local/bin/iTMSTransporter.woa/iTMSTransporter -u -p myS3cr3tPassw0rd -m upload -v critical -t Aspera,Signiant -k 100000 -f /apps/upload/itms/ -success /apps/upload/success -failure /apps/upload/failed -loghistory /apps/upload/logs/iTMSTransporter.log -errorLogs /apps/upload/logs/errors
I hope you find this useful. Any questions or comments?

miércoles, 12 de junio de 2013

Extreme Jigsaw Puzzle

With that descriptive name my last application has been approved. You can download it from the AppStore, it's free. It is only available for iPad right now, but I will add more platforms in the future.

If you have any question or feedback, you can leave a comment here, but make sure you read the tips and tricks before.

martes, 30 de abril de 2013

Fallback URL, a simple plugin for YOURLS

I've just written a simple plugin for YOURLS and I would like to share it with you.

YOURS stands for "Your Own URL Shortener" and it's a really nice URL shortener that you can install in virtually any hosting that has PHP enabled. Pretty cool, isn't it?

I was missing a way to redirect to a custom URL (instead of give an error) when the short URL does not exist. So I made this plugin. It is really simple and you can use it in your YOURLS installation (or use as a template to make your own plugins).

You can download it from:

viernes, 23 de noviembre de 2012


Few months ago I released a ContainerViewController called DPTopTabsViewController. It is a viewController for managing tabs like those found in Google Chrome. It is implemented as a container view controller so it is as easy to use as a UITabBarController. You can find a test project in bitbucket, among with this class.

Have a look to DPTopTabsViewController.h file, you'll see some comments there and the default values. If you still have questions, you can leave me a comment.

jueves, 8 de noviembre de 2012

LP Cheater

As many of you may already know there's a new word game. It's called Letterpress and I like that kind of simple design. The main goal is to turn your color as many letters as possible by forming words with them. You can steal your opponents letters if they are not protected (surrounded by the same color).

I wrote a program, called LP Cheater, to help people choose better words. It tells you the words you can make and which ones give you more points (the points you get plus the points you take from your opponent).

You can find it in the AppStore, if you have any problems post them here or send me an email to And remember: "with a great power comes great responsibility" ;)


Hello world!

This entry is mandatory, you know.

And, by that title you may guessed it, yes: it's all about Objective-C programming.

See you around.