Usability

The new iTunes Connect has only been out a few days. Overall, I think it’s probably better than the old version – there are just a few things to get used to. It seems there’s a noticeable lack of communication within the new web app – enough that I filed a couple of bug reports.

Two surround the situation where you have uploaded a binary to iTunes connect. The first issue – you are not allowed to re-upload a binary with the same version and build number. However, there is no way to remove the old one. The second is a little less obvious: Uploading the new binaries will place them in a “Processing” state with no indication about what is happening. Fearing something had gone wrong, I tried the upload a few more times with different build numbers & formats – all went to “Processing” with no icon – only the version, build number, and upload timestamp. None of them were available to select so I could submit for App Store review. Xcode said everything was OK, Application Loader said everything was fine. An hour later, all four builds were processed. Thanks, I guess.

No matter the technical process, there are a few key points of communication they missed out on:

There’s no indication what “Processing” actually does, or how long it should take. Minutes, hours, days?

This little bit of code is going to be useful to those of you developing a “singe page” app inside of PhoneGap. This applies to Sencha Touch (big fan), but doesn’t as much to jQuery mobile and jQTouch, as it’s a multi-page/navigation based event framework (it uses the app’s url string to do things like move around to different link anchors). This is really important on these single page apps because the Android hardware back button will send the PhoneGap app to the background. You need some way to intercept it so you can start building your own history management mechanism. Sounds fun, right? It’s actually not that hard.

On app initialization, add an event listener for Android’s back button, and the callback to handle it. PhoneGap takes care of the interface between Android and your app.

Swift

1

2

3

4

5

document.addEventListener("backbutton",backKeyDown,true);

functionbackKeyDown(){

// Call my back key code here.

alert('go back!');

}

That’s enough to get you started, and it should be pretty apparent if it works or not.

How about history management? It will depend on the app and what makes sense, BUT you’ll probably want to create a history array, and pop off some value that directs the app each time you hit the hardware back button. Here’s another idea: change the destination of the back button depending on the view. I personally like the idea of the latter because apps built on Sencha Touch are going to have easy tie-ins through predefined listeners JS Objects that define screen elements like buttons.

Here’s a quick note for the frustrated:
When setting the readonly parameter on a form element via javascript, make sure you use a capital “O” as follows:elem = document.getElementById('myInputElement');
elem.readOnly = true;

Why it took me so long to find that out, I have no idea why. Most forums threads by others seem to think the disabled parameter is the best way to go. Actually, the sheer number of people suggesting that makes me think it’s a bad idea – just following the crowd. This is why readOnly might be the right option: You’re still allowed to post the form value, but the user isn’t able to change what’s inside the box. When using disabled *nothing* gets posted from that element. So if all you want to do is prevent a user from editing the value of a form element, use readOnly. If you don’t want that value posted, then go ahead and use disabled.

Harley Bergsma at the UXB and I devised this brainchild together. From there he took care of project management and I took care of developing the back-end. The idea is that users can decorate their own pink duck on the site (using Flash), then forward their creation to all their friends. For each person that receives the duck and opens (don’t even have to click links!) the email five cents is donated to Susan G Komen for the Cure. One of the coolest things is that the email dynamically shows how much the duck raised (how many emails were sent) and how much the project’s running total was. If you were to come back to the email a few minutes, days, weeks later, it would continue to show fully-updated information. Rad!

In just a couple months there were over 131,000 forwards, for a total of over $6550 raised just from this part of the campaign alone.

The problem recently presented itself to me when writing some new functionality for revealCMS: I needed to set some variables to load in the page head, but could only be set after a portion of the body had completed rendering. I wrote a plugin that essentially loads a different stylesheet depending on the input of the Smarty template function. The hard part wasn’t assigning the variable – it was figuring out the best way to get that assigned data to appear in a part of a page that had already been rendered – the head.

It makes sense why Smarty would work this way – that you can’t go back and re-assign variables. It would be too messy. So somehow you need to assign the variable first in the body, then go back and render the head. It’s simple… really. Believe it.

But why bother? Why not put <style> tags directly into the page body where the plugin is located? The reason is simple: <style> tags (and <script> tags, for that matter) MUST be in the page header. It’s a web standards thing.

First, break-up your page templates into two sections: the header (containing everything before the <body> section of your template), and the body, which contains the <body> section. First render the body using$body = $smarty->fetch('body.tpl');
At this point, I’ll just assume that your page functions have loaded and you’ve either placed an {assign} tag somewhere in the template, or you’ve used a $smarty->assign() inside the template function. If you’re not familiar with $smarty->fetch(), it’s just like $smarty->display(), except it outputs the contents to a variable rather than the screen. And just like display() it can also take $compile_id and $cache_id as optional parameters.

Now render the head:

$head = $smarty->fetch('header.tpl');
By this point everything should work-out as we expect it. Our dynamically loaded css file is loaded in the head and our standards friends are happy. The beauty about this example is that you can now render a number of items in any order you need them then display properly, so long as it makes logical sense.

Here’s a tip: You can use this method to dynamically load javascript files and frameworks if your fancy web 2.0 page functions/plugins need it at some times, but not at others.

Smarty is becoming more and more popular in the PHP community lately, especially as developers are moving away from mixing business and display logic in the same scripts and towards a cleaner MVC design pattern implementations.

If you’ve followed my blog for any amount of time, you’ll know that I’m currently working on my own CMS/Framework, to be completed hopefully in early 2007. I don’t know what it was – maybe procrastination – but something make me take a look back at my plugin implementation for the CMS.

Previously I took a rather odd, round-about way of including custom functions and plugin templates into my main pages:
Step 1: include the plugin template
Step 2: The plugin template called the template FUNCTION
Step 3: The function does a lot of business and assigns data to template variables
Step 4: the rest of the template is rendered with the newly-found data from the function
That’s a little too awkward, even for me!

If you’re looking for some help on learning mod_rewrite, this post isn’t for you. sorry. Instead, I’m going to show you a neat little trick that will make sure you always have one the www in front of your domain name. Why is it important? Potentially for your stats package, definitely for search engine ranking (no duplicated content), and even for uniformity across brand(?). Though it’s not necessarily part of your “brand” it is important to be consistent with the URLs you send people or have others link to.

For the purposes of this example, we want our URLs to always have the www in front: www.digitalfishlibrary.org

Step 1:
Open (or create) your .htaccess file and add RewriteEngine On if it isn’t already in there.

We use the http 301 response code to tell browsers and search engines that this is a permanent redirect, thus updating their records. Little-known fact: web browsers are supposed to automatically update bookmarks to the new URL from a 301 code. Search engines probably do the same with their indices.

I’m just going to throw this out there… if you have a piece of software, site, etc that isn’t quite at the QA stages, no matter how rockin’ in might be, you might want to consider holding off on showing it to others until you know the demo is going to work. I think I’m done showing people demonstrations of Mr. Fish Lite until the backend VTK issues are ironed out, which thankfully is *not* my job. There are some pesky UI issues I need to iron-out with IE box models and transparent PNG support as well, but at least those are things I can fix pretty quickly.

My advice, show some screenshots or maybe even make a snazzy video demonstration where you can control all the variables.

I found an interesting “bug” in Apple’s Safari today while updating a page on Flood’s deprecating website (new version coming up in September). First of all, for the record, nobody on the team designed the template currently in-use (Aug, 2006).

I just needed to put an anchor near the end of the page… pretty standard stuff. The problem is that Safari wasn’t jumping down the page – only a couple lines. Odd because IE and FireFox jumped just fine. I’d never had that problem before, but I traced it down to something pretty simple (and maybe even conceivably reasonable). Safari jumps to the beginning of the paragraph or div that the named anchor resides in. The problem with the Flood page is that the original designers didn’t really use p tags, or divs, for that matter (in fact, simply adding a p tag will disrupt the page design… go figure). So Safari would simply jump down to just below the heading tag.

Maybe I’m not a great designer, but I will say I may be a better designer than a lot of other web designers (and average Joes, for that matter). Hmm sounds a bit cocky, doesn’t it? Consider it an attempt to balance confidence with the proper humility.