Matching UI Behavior with User Behavior

November 7th, 2011 by Craig 1 comment »

The viewport is a direct window into what the user sees, and a lot can be learned by watching it. In my previous post I introduced Within Viewport and I want to discuss how, particularly through my Twitter app signal:noise, I’ve found it useful in making interfaces respond sensibly to user behavior.

Dynamic content loading

A common solution for developers looking to increase their site’s performance is to load data on demand, for example using Infinite Scroll. But sometimes the scroll position isn’t enough — you need to know about the content on screen.

In signal:noise I want to control how heavier content is loaded. Since a tweet is a paltry 140 characters, and dynamically adding more of them to the top of a page causes it to scroll, it’s reasonable to start out by loading fifty or so at the initial page load. But when you factor in images and video previews linked within those tweets (which signal:noise presents inline) the page can take longer to load. I use Within Viewport to make sure I’m only loading media for tweets that are on screen or just about to be shown.

Responding to user behavior

The obvious thing to do when a user reaches the boundary of their timeline is to load more tweets. But it takes time to call the Twitter API (possibly more than once), process that response, and send the new content back to the client. By comparing the number of tweets in the user’s field of view to the number that are out of sight, and tracking the speed with which those tweets move in and out view, the app can get a sense of the user’s momentum. With this knowledge the app can avoid calling the API too late (not having tweets ready to go) or too soon (unnecessarily hitting the API rate limit).

Making appropriate measurements

The app also tracks each user’s reading position so the can resume reading at the same place in future sessions. When determining which tweets have been read, it only makes sense to consider ones that are fully in view. The app has a fixed header that shrinks the viewport by about 60 pixels, so I need to make sure a tweet is not covered by that.


Diagram showing elements of a Twitter feed being in and out of view

Larger version

Live updates

My app also allows keyboard navigation from tweet to tweet, similar to Google Reader. When the user jumps to a tweet that is not completely visible, the app needs to know so it can scroll the page.

Tracking usage

While not directly applicable to a Twitter app, you may want to find out what areas of your site a visitor actually sees. By firing events when sections move into and out of the viewport, you can use Google Analytics’ Event Tracking to find out how often users actually see parts of your page. Wondering why a particular widget doesn’t result in many click throughs? Perhaps the answer is as simple as not many people even get to see it.

And more?

All that from just a viewport? I initially wrote Within Viewport to solve only one of the problems above, but I soon found many other uses for it. It wasn’t until I began using it that I realized, as obvious as this may seem, how pertinent the viewport is as an insight to the user’s experience.

If you have any other ideas, or suggested additions to the script, I’d love to hear it in the comments.

Within Viewport: JavaScript and jQuery Plugin

November 7th, 2011 by Craig 3 comments »

Within Viewport indicates whether an element is entirely within the viewport. It also allows you to specify your site’s effective viewport (eg, to account for fixed header and navigation bars) and provides a few handy shortcut notations.

It’s quite simply to use:

var elem = document.getElementById("myElem");

// Returns true if it's completely visible
withinViewport(elem);

// Same as above, but using the jQuery plugin
$(elem).is(":within-viewport");

// Run some function on all visible divs
$("div").withinViewport().myFunction();

There are a few “in view” scripts out there — namely, Mika Tuupola’s Viewport Selectors for jQuery provides some convenient selectors that can be tested against elements, and Remy Sharp’s Element ‘in view’ Event Plugin fires events when elements pass in and out of the viewport.

While useful, these utilities only detect whether elements are partially in view. The aim of Within Viewport is to determine what content the user can see and interact with.

Use Cases

A lot can be learned from monitoring the viewport, especially on a site with content that spans well outside of the user’s view. I will discuss how I use Within Viewport in much more detail in my next post. But here’s a quick overview of what you can do.

  • Dynamic content loading

    A site’s performance can be increased effectively by loading data on demand, for example when the user scrolls near the bottom of the page. But perhaps the content on screen is more pertinent than the scroll position. For example, you may want to load the entire structure of your site during the initial page load, but then populate that structure with heavier media as it nears the user’s field of view.

  • Responding to user behavior

    You may also want to tailor when that content is loaded based on how rapidly the user moves about the page. If you are relying on a third party API for content, you may want to start the process sooner than you would begin requested content from your own server.

    For example, the script below would find and load items with local content that is merely just beyond the viewport, but also load third-party content that appears much further down the page.

    // Image placeholders at most 100px below the fold
    $('img:not([data-src^="http://"]')
        .withinViewport({bottom:-100})
            .loadTheseImages();
    
    // Image placeholders as far as 500px below the fold
    $('img[data-src^="http://"]')
        .withinViewport({bottom:-500})
            .loadTheseImages();
    
  • Making appropriate measurements

    If you want to know what your user has seen, for example to remember their reading position in a feed, you can only consider ones that are fully in view. You also need to take into account the actual viewport, avoiding things like fixed header bars that cover parts of the page.


    Diagram showing elements of a Twitter feed being in and out of view

    Larger version
  • Live updates

    If you implement keyboard navigation between items, similar to Google Reader, you need to make sure a newly-selected item is actually visible.

  • Tracking how your app is used

    You can tap into Google Analytics’ Event Tracking to find out how often items enter your visitor’s field of view.

I built Within Viewport to accomodate those needs, but I made it generic enough that any site or web app could benefit from it. There are configurable defaults and several shorthand notations described with examples in the documentation.

No jQuery? No problem

I wanted to write a tool that was independent of jQuery so it could be dropped into any project. Of course jQuery does offer some useful mechanisms such as filtering and custom selectors, so I added an optional plugin to provide that functionality.

Complete cross-browser console.log()

April 12th, 2011 by Craig 18 comments »

Many front-end web developers make use of the wonderful browser consoles that have matured in the past few years. While the tried-and-true console.log() often does the trick, its lack of support (particularly in IE) has led to the use of proxy functions, such as Paul Irish’s console.log wrapper and Ben Alman’s Debug() which prevent unsupportive browsers from throwing errors.

I had a need for logging data in every browser, not just ones that natively support console.log(). So I forked Paul’s function and expanded it to work with every browser I could test — IE6+, Firefox 3.6-4, Chrome 10-11, Safari 5, and Opera 11.

This will be exhaustive, so you may want to jump directly to:

Current state of the console

Like Paul’s implementation, we’re simply going to create a function called log() and pass along any arguments it receives to console.log(). But before that we need to do a little setup to ensure that, when possible, console.log() is properly defined as a function in every browser.

First, let’s review console support in today’s browsers:

  • Chrome, Safari, Opera: native console.log()
  • Firefox: native console.log() with Firebug
  • IE9: native console.log(), but it needs a little nudge to turn on
  • IE8: While console.log() exists, it’s an object rather than a function — But we can still write to the console with a clever trick.
  • Others: We can inject Firebug Lite which will define console.log() as a function

Note that when I talk about IE I’m referring to the native versions — “IE8″ means IE8, not IE9 switched to IE8 mode with the Developer Tools.

IE's developer toolbar tricking you into thinking that it's running as a different version

IE9

Before we build log() we need to tell IE9 to use its own console and to consider console.log() to be a function. Many thanks to Andy E for this piece.

if (typeof console.log == "object" && Function.prototype.bind && console) {
	["log","info","warn","error","assert","dir","clear","profile","profileEnd"]
		.forEach(function (method) {
			console[method] = this.call(console[method], console);
		}, Function.prototype.bind);
}

For this particular case we really only need to define the log method, but it can’t hurt to flip the switch on the others as well.

Modern browsers

Now we can define log(). There’s no sense in re-inventing a very round wheel, so I’m just going to fork Paul Irish’s original console.log wrapper.

if (!window.log) {
	window.log = function () {
    log.history = log.history || [];  // store logs to an array for reference
    log.history.push(arguments);
	if (typeof console.log == 'function') {
		// Modern browsers
		if ((Array.prototype.slice.call(arguments)).length == 1 && typeof Array.prototype.slice.call(arguments)[0] == 'string') {
			console.log( (Array.prototype.slice.call(arguments)).toString() );
		}
		else {
			console.log( Array.prototype.slice.call(arguments) );
		}
	}
	// to be continued...

Notice that if() condition. Paul’s use of Array.prototype.slice.call() is great because you can pass along any amount and variety of objects, strings, functions, etc directly to the console. However, there’s one unfortunate side effect: in Firebug and Chrome (and possibly others), if the argument array’s sole content is a single string greater than 50 characters, it will be truncated faster than you can say Llanfairpwllgwyngyllgoger…wllllantysiliogogogoch.

So we’ll check the array length, and if it’s 1, and that 1 thing is a string, then we’ll convert the entire argument array to a string before passing it along. You could use console.error() to avoid truncation, but then it will look like an error when it’s not.

Opera

So that takes care of the modern browsers… except Opera. Opera seems to display the arguments as a whole Array() rather than splitting them apart. So if you passed several arguments you’d just see this:

Opera console showing "Array()" rather than the actual arguments

And that’s not too helpful. We can get around this with a rather boring while() loop to log each argument one by one.

var log = function () {
			// Modern browsers
			if (typeof console != 'undefined' && typeof console.log == 'function') {
				// Opera 11
				if (window.opera) {
					var i = 0;
					while (i < arguments.length) {
						console.log("Item " + (i+1) + ": " + arguments[i]);
						i++;
					}
				}
				// All other modern browsers
				else if ((Array.prototype.slice.call(arguments)).length == 1 && typeof Array.prototype.slice.call(arguments)[0] == 'string') {
					console.log( (Array.prototype.slice.call(arguments)).toString() );
				}
				else {
					console.log( Array.prototype.slice.call(arguments) );
				}
			}
			// to be continued...

Which results in:

Opera's console listing each argument on a separate line

It’s a little messy and if you use log() a lot you’ll find that your console will fill up fast, so you’ll have to decide how important Opera support is to you.

IE8

As we discussed earlier, IE8 has a console but your scripts can’t call console.log() directly, so we’re going to add a special condition for it. Andy’s aforementioned post included a similar bit of code for writing to IE8′s console, however in actual IE8 (as opposed to IE9 switched to IE8 mode) Function.prototype.bind is not defined. Instead, I’m using @kangax‘s alternative, Function.prototype.call.call().

			else if (!Function.prototype.bind && typeof console != 'undefined' && typeof console.log == 'object') {
				Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
			}

One slight alteration: I changed the second part of the condition from console to typeof console != 'undefined'). It seems a little silly, but IE7 actually throws an error without the typeof check.

Older browsers

Now we’re going to inject Firebug Lite (“FBL”) for all the other browsers — namely, IE7 and older — by adding a <script> tag to the DOM. (Personally, I like FBL better than IE’s and Opera’s consoles anyway, so you may want to use this for any browser where (typeof console.log != 'function' || window.opera) is true.) Doing this will expose console.log() as a function, which means your calls to log() will end up being handled by the “Modern browsers” section in the beginning of the function.

You can pull it directly from getfirebug.com, or use a local copy (point to the /path/to/firebug-lite/build/firebug-lite.js file).

In my experience FBL takes a few moments to load and begin accepting console logs, even locally. To compensate for this delay, this piece of code is split into two conditions. The first one loads FBL and will only run the first time you call log():

		else {
			// Inject Firebug lite
			if (!document.getElementById('firebug-lite')) {
				// Include the script
				var script = document.createElement('script');
				script.type = "text/javascript";
				script.id = 'firebug-lite';
				script.src = '/lib/js/firebug-lite/build/firebug-lite.js';
				// If you want to expand the console by default, uncomment this line
				//document.getElementsByTagName('HTML')[0].setAttribute('debug','true');
				document.getElementsByTagName('HEAD')[0].appendChild(script);
				setTimeout(function(){log(Array.prototype.slice.call(arguments));}, 1500);
			}
			else {
				// Script was included but hasn't finished loading yet
				setTimeout(function(){log(Array.prototype.slice.call(arguments));}, 500);
			}
		}
	} // <= that's the end of log(), btw
}

The second condition is caught when your script calls log() before FBL has finished loading. Notice the id that I added to the <script> tag in the first condition — that tells us that FBL has begun loading. But since console.log is still not defined (otherwise we wouldn’t have gotten to this point in the code) we know that the script hasn’t fully loaded yet. Therefore we can simply use a setTimeout to try our call again every half second until it succeeds.

“It is so big”

Yeah, it is. Compared to Paul’s 6 lines, this version is a beast. But consider this: you log to the console during development. You’re not going to leave this in your production code (I hope!). So this function — and let’s face it, it’s not that long, especially when minified — is likely to be used only via localhost or over a LAN connection. I think the ability to log data in every browser is well worth a couple dozen lines of code tucked out of sight down at the bottom of dev.js.

I look forward to any suggestions or improvements you may have.

My wish: that Google would preload its CDN libraries

April 9th, 2011 by Craig 2 comments »

The idea behind using a common CDN such as Google’s, as opposed to your own CDN (or none at all), is that by the time a person reaches your site there’s a chance they already have your JavaScript libraries cached. While it’s likely that an übergeek with fifty opened tabs will have jQuery cached before hitting one of your pages, the same isn’t so true for every Joe Facebook.

But what if a very popular site, one that nearly everyone would hit before reaching your site, loaded those libraries? I imagine the number of users running cached libraries would increase dramatically.

So which site? How about the most popular default home page — Google Search. (Sure, Facebook is popular, but we all know that even Facebook user’s hit up Google first.)

Think about it: a typical user begins their browsing session by loading Google’s search page, searches for something or other, and moves on with their task. But in the mean time, Google has silently loaded — not used, just loaded — jQuery, some popular web fonts, etc in the background. Perhaps the libraries are even chosen as the most likely ones the user will encounter based on his or her search terms. Those libraries are now cached in the user’s browser and your page will load that much faster with zero effort.

Of course there are some glaring drawbacks that would need to be addressed, but the solutions are pretty straightforward:

  • Page load speed. Among other things, one could use a setTimeout() to lazy-load the library after, say, 8 seconds. (If you’ve been on the page for 8 seconds, chances are you’re hanging around for another 0.5 seconds to allow the download to finish.)
  • Bandwidth. Obviously mobile devices are out, at least until there’s some way to detect whether the user is on wifi and running a buff enough browser not to blink at the <script> parsing. Even so, there are ISP bandwidth caps to consider, but is a one-time 20KB download going to push anyone over their limit?
  • Privacy. People will kick and scream at the thought of something loading without their explicit request. Surely there should be an option to turn this off; but really, if you’re paranoid enough not to want MooTools in your cache than you’ve surely installed NoScript anyway.

Naturally this is all just a wish. It’s something I think Google could certainly pull off smartly, but I’d love to see it in practice even in a limited test (Chrome beta channel users, perhaps?) to see what effect it has on a typical person’s web experience.

How to Use Your iPhone Overseas

July 29th, 2010 by Craig 10 comments »

If you’re preparing to travel overseas and you’ve had an iPhone for any amount of time you’re probably excited about its usefulness as a travel aid. In particular, you’ll be keen to make use of its always-on Internet connection.

But you’ve probably heard the horror stories of arriving home to a thousand-dollar cell phone bill littered with roaming charges. Fortunately, you have some options to make use of your iPhone’s capabilities outside of the United States.

While this topic has been covered before, most approaches are far too conservative. You don’t want to spend your entire vacation with your iPhone locked down in airplane mode, or constantly toggling Data Roaming on and off — nor do you need to. That defeats the entire purpose of a smartphone and prevents you from enhancing your trip with the iPhone’s many tools.

Note that this post is specific to American AT&T users, but the fundamental principles still apply to other smartphones on other carriers. It is also a bit Europe-centric — I’m just sticking to what I have experience with.

I also assume that you’re familiar with what a SIM card is, as well as the difference between voice and data where cellular networks are concerned.

An Offline Frame of Mind

When your iPhone is in its most helpful state, it’s probably consuming a lot of data, which unfortunately is your primary concern when it comes to roaming charges. So the first order of business is to concentrate on orienting yourself to being less network-reliant. This isn’t as daunting as it may seem.Google provides Mobilized links for web pages in its search  results

An important note to consider is that native apps tend to consume far less data than web browsing. For example, it uses a trivial amount of data (tens of kilobytes) to complete a simple FourSquare check in, so have a ball boasting about all the exotic locations you’re visiting. (Just be safe and don’t overshare.) And while Google Translate‘s mobile interface is slim, consider an app such as iTranslate which will only transfer the actual text you’re translating.

If you must perform a simple Google search away from wifi, hit the mobile link for a stripped down (read: image-lite and less data gobbling) version of the site.

A Few ‘Offline’ Tips

  • Wifi
    This seems a bit obvious, but try to book hotels with free wifi. Assuming your travel is for leisure, you’ll probably want to enjoy your day and save the web browsing, RSS feeds, and Facebook for when you’re unwinding in your room at the end of a long day.

    Save your cellular data for the situations that are truly helpful while on foot — finding out where you are, checking for nearby points of interest, and verifying other time sensitive information.You can also use a service such as JiWire and their Wi-Fi Finder app to find and download a map of wifi locations in your city.

  • Maps
    Perhaps the killer app of the iPhone when it comes to travel is its mapping capabilities and location awareness. Maps, however, are extremely data-intensive, so you’ll want to have them preloaded on your device.

    • OffMaps (99 cents) is an excellent app which allows you to freely download maps. On the ground, it will utilize the phone’s (free, non-data-consuming) GPS abilities to display your position on the map. (It can, of course, stream maps on-the-fly if you have a generous data plan.) It typically locates you within a second or two; it’s much faster than the GPS devices of the past.Before you leave home, use the maps to download the maps at several zoom levels for the destinations you will be at. A typical city may take a couple hundred megabytes at the most detailed zoom level, so be sure to use Wifi. You might also consider their useful but less-than-polished city guides which highlight sights, hotels, restaurants, and other travel-related points of interest collated from WikiTravel.org and other free sources (in-app purchase; first one’s free, then 99 cents for three or $9 for unlimited).
    • Navigation apps (various products and prices, usually $40-$100) are available for many worldwide locations if you intend to do some driving. Just make sure you choose the right region, and that the maps are included in the download for offline access.
  • Guides
    Search the App Store for the name of your destination city or country and you’ll find a range of guides, from basic “WikiTravel in a nice package” apps to sleek but more costly Lonely Planet guides. Also consider using a service like Instapaper to collect articles and download them to your phone using the Instapaper app. As a last resort, paste the text into an email or the Notes app.Or you could just lug around a dead-tree guidebook, which has its benefits.
  • Toggle Cellular DataCellular Data switched to "Off" in Settings

    An easy way to ensure no data will be sent over your cellular connection, while still maintaining the ability to make and receive phone calls and use the phone’s location awareness, is to turn off cellular data in Settings.

    That’s it. There is no need to turn on airplane mode to avoid data usage. Note that you do not need to explicitly turn off data roaming when toggling this setting.

    If you’re confident that you’ve turned off all background processes (fetching mail, etc) then you can just leave cellular data flipped on to avoid the hassle of constantly toggling it. I recommend testing this at least once: make note of your current data usage (e.g., dial #3282* if you’re on AT&T’s plan described below), leave the phone idle for an hour or two, then check your data usage again and make sure it hasn’t gone up. If it has, you’ve still got something running in the background.

Getting Connected

You have three basic choices when it comes to connecting to a cellular network abroad. The first is the cheapest but requires a bit of research and a little leg work at your destination, while the other two are more expensive but just plain work with no hassle.

  1. Foreign SIM Card
    This is the cheapest option which gives you the most flexibility, and depending on the country, even the possibility of having so much data at your disposal you won’t even need to monitor your usage. Unfortunately, it requires jailbreaking and unlocking your device. This has its own implications; I’ll leave it up to the reader to decide whether this is a path worth taking, and to figure out how to do it (the process and ability depends on your device and OS version, not to mention your tech savviness).If you do unlock your phone, you will be free to use any SIM you can find. You will quite likely want to use a contract-free prepaid SIM which will allow you to just pay for what you use and can usually be found all over, from airports to convenience stores to specialty phone shops. These options are country-specific, so if you’re traveling to three or more countries you’ll want to look into “global SIM” cards such as Telestial or GO-SIM.

    Start by perusing the Pay As You Go SIM Wiki and PrepaidGSM.net which includes a roundup of the options for each country, listing the data and voice rates. It may seem a little daunting at first, so concentrate on the data rate and assume you’ll use Skype for voice calls. Note that the main legacy carriers, such as Vodafone, O2, Orange, and T-Com — the rough European equivalents to AT&T, Verizon, et al — are ubiquitous and feel ‘safe’, but there also exists a culture of “virtual operators” who utilize the big companies’ networks but offer lower rates. Often these VOs (or sometimes MVNOs) will specialize in some ‘angle’ that may not work for everyone, such as cheap data subsidized by more expensive voice calls — which is actually just what you want. (Think of low cost airlines like RyanAir which offer cutthroat prices based on limited services and alternate airports — it’s not entirely mainstream-friendly but it may just suit your needs.)

    Take a moment to peruse the site’s forums for tips on your country and read about people’s experiences, taking into consideration how recent the posts are.Once you’ve narrowed your options down to three or four networks, head over to other travel forums such as FlyerTalk or Lonely Planet’s Thorn Tree and search for the network’s name to see what people have to say.

    Finally, write down three or four operators (on paper or digitally), as well as how/where to buy them, to bring with you on your trip. You can’t be sure exactly which SIMs you’ll actually be able to find, so it’s good to have a backup. You may get a different story from the shop clerk who says you can’t actually use the SIM as you’d expect, or they may be difficult to find in stock. A piece of paper also provides a convenient tool to hand to a non-English speaking clerk (unless you know the Dutch/Hungarian/Romanian/Turkish phrase for “I need a prepaid SIM card for my unlocked phone with a good data rate” and can interpret his or her possibly jargon-laden response).

    Note that the availability of SIMs can vary in both senses of that word. For example, in the UK, SIM cards are practically given away — you can throw a stone in any direction and, after bouncing off a kebab joint, it will land in front of a shop selling £10 SIMs that come with £10 of credit (meaning the SIM is free assuming you use all the credit). Often these can be bought anonymously with cash. In the middle are countries like Spain and Germany which may require a passport and/or in-country address (the standard practice is to use your hotel’s address) to purchase a card. Then there are countries like Turkey, where the security theatre had ascended to the point where the SIM card vendor must verify your national tax ID (similar to an American social security number in both function and sensitivity) and register it with your SIM before it’s activated, meaning a foreigner is basically out of luck unless they have a good friend or family member willing to buy one for them.

  2. AT&T’s International Data Package
    This option is as simple as it gets — just log in to your account on AT&T’s website and add an international data package to your account. Once you’re overseas, you’ll just use your iPhone like you would at home and it will work seamlessly.The catch? It’s not exactly cheap. You can choose from a paltry 20MB for $25, 50MB for $60, or even 100MB for a whopping $120. That’s not much data for a pretty hefty chunk of change. Figure that you’ll use about 50MB a month, or 12-15MB per week, if you’re careful about your usage and stick with the tips discussed above. You don’t want to go over — overage fees are an almost comical $5 per megabyte (though mercifully charged by the kilobyte should you go just a hair over).

    There’s one other point to consider which may or may not work out in your favor. The international data package takes affect immediately and is prorated, which may or may not align with your billing cycle and trip. Consider how the 50MB plan would pan out over the following example:Time line showing a trip from July 7 to July 27, with only 33MB available from July 7 to July 22 when the billing cycle restarts, but then 50MB for the last 5 days of the tripIn this example, notice how inconveniently the amount of data aligns with the actual trip. The first fifteen days, representing a sizable bulk of the trip, only gets 25MB, while the last 5 days have 50MB at their disposal. (True, you will still end up paying for the amount of data you actually use, but remember the overage fees compared to the normal price per MB, not to mention the convenience of having a lot of data available should you unexpectedly encounter a day or two of unavoidable high usage.)

    Here’s how it works, and why part of the trip only has 25MB available. The billing date here is the 22nd of the month, and the data plan began on the same day as the trip, the 7th. Since that’s only half of the billing cycle, you only get half of the data. When your next billing cycle begins, you’ll be reset back to the full 50MB. In this case, you’d be better off signing up on the 22nd of the previous month (June, in the above example) so that you have the whole 50MB available during your two-week trip. I’ve read that you can have this adjusted (so that the data charge aligns with the date of your trip instead of your billing cycle) by calling AT&T; I recommend talking to them first if your dates aren’t aligning in your favor.

  3. Legit iPhone SIM providers
    These aren’t any cheaper per megabyte than AT&T’s plan, and they’re not as dead simple, but they give you a few more options: Mobility Pass,

Conclusion

If you’re comfortable with jailbreaking and unlocking your phone, and the country to which you’re traveling has SIMs available, then a 3rd party SIM is easily the cheapest and most flexible option.

If you don’t want to (or can’t) jailbreak or your country is on SIM lockdown, AT&T provides an easy-as-pie option at a cost.

Either way, you’ll need to follow good data usage practices to keep your usage at more of a minimum than you’re used to. Also be sure you’ve got all the apps you need and prepare them before leaving home.

Above all else, don’t forget to leave the iPhone in your pocket most of the time and enjoy your vacation!

Why the Germany-Spain Semi-Final Isn’t a Foregone Conclusion

July 5th, 2010 by Craig No comments »

Disclaimer: I’m a fan of both teams, but I have a bit at stake (no, not gambling-related) with regards to Spain winning the Cup. Nevertheless, I hope to make an objective case for Spain’s chances of victory.

With 4-0 and 4-1 (or was it 4-2) thrashings over Argentina and England (and Frank Lampard), respectively, Germany go into their semi-final with Spain as the likely favorites. It’s hard to deny that a team with such excellent players, a gelling of individual talents, and a strong history should be able to beat a Spain side who has looked shaky in their attempt not to repeat their usual early exit from the Cup.

That said, I can see Spain pulling off a surprise win in this one, even while disregarding the difficult-to-ignore fact that Müller being out on suspension for Germany.

Team play

In this tournament, Germany have not demolished teams that play well as a team. Argentina and England, in particular, were merely a collection of stars just riding along on a combination of individual performances and luck (more so luck in England’s case) until they were found out by a solid team. While Spain is star-studded, they gel as a team in a way that Argentina and England don’t (admittedly, Germany are even better in this respect).

Possession

Spain dominate possession and if they score first they are very solid for the rest of the game. Germany will have a tough time pulling off their counterattacks (despite Spain’s not-quite-world-class defense) with the way Spain move the ball around. Germany will score, I’m sure, but not with the ease that they have in the last two games.

Pressure

Spain have also been hampered by being favorites, and suddenly they are not favorites, almost underdogs in fact. I think this will lift a lot of the pressure that has hampered Spain’s usual groove. And Villa’s confidence is soaring compared to that of any individual German’s.

Germany, on the other hand, were not widely favored to win the tournament, and the sudden mounting enthusiasm of the media, fans, and the players themselves must be reaching a critical point.

Those thrashings I mentioned…

While I would never say Germany’s results against Argentina, England, and Australia were flukes, look at their other results. They narrowly defeated Ghana 1-0, a team who only just missed out on the semis themselves. They even lost to Serbia, a squad with solid team play who were pre-tournament favorites to reach the quarterfinals. Germany has tripped during these finals, and it’s unlikely they won’t trip again.

Resilience

It won’t be a blowout in either direction; 2-1 or 3-2 is my guess, if it doesn’t go to penalties. And with the resilience and composure that Spain showed in Euro 2008 (penalties against Italy, and of course the final against Germany, holding on to a narrow lead for an hour) as well as in this tournament (defeating Paraguay despite being frustrated by their defense and flustered by the penalty debacle), I’d give the edge to Spain.

I certainly won’t be too sore if Germany prevail — they’re a fantastic team playing the sport the way I like to see it be played: no BS, just solid playmaking, composure, and clinical finishing.

How to Keep Sites from Spying on Your Copy and Paste

January 15th, 2010 by Craig No comments »

?Many news sites, from Wired to my local newspaper, have taken to adding a ‘feature’ to their articles — any text you copy and paste is silently broadcast to another site. That other site, Tynt, keeps track of what you copy and paste to your friends in an effort to track demographics.

Text copied and pasted from a news article into an IM window

While some find it useful that Tynt also appends the URL of the article you’re viewing, many find the behavior obtrusive and a violation of their privacy. Want to share a snippet of a story with a friend? Go ahead, Tynt (and presumably the news site) are watching.

Here’s how to get rid of it, depending on your browser of choice.

Firefox iconFirefox

With AdBlock installed (and why wouldn’t you have it?), open the AdBlock preferences — either through the Tools menu or with the shortcut Ctrl-Shift-E. Click Filters > Add new, then paste in this line:

http://tcr.tynt.com/javascripts/Tracer.js

AdBlock preferences window

Google Chrome icon

Chrome

Chrome as a few ad-blocking extensions, such as AdBlock and AdThwart. Once one is installed, go to your extensions page by clicking the wrench icon in the upper right corner of Chrome, then choose Extensions. Open your extension’s options and add the same line shown above for Firefox.

Internet Explorer, and everyone else

First, ask yourself why you’re not using a safer, faster, better browser. Safari lacks add-ons (and therefore ad-blocking). And nobody uses Opera. (Kidding, sort of.) Surprisingly, Internet Explorer version 8 does offer ad-blocking. Follow these easy steps from ghacks.net to block this script.

The Apple Tablet Will Be Exactly What We Think It Will Be

December 28th, 2009 by Craig No comments »

With the rumors around the Apple tablet reaching a fever pitch, a number of sites have taken to rounding up pre-iPhone speculation and using it to push the idea that we don’t know anything about the so-called iSlate. The thing is, we probably do.

The iPhone came out of nowhere and surprised just about everyone. It made the various speculative mockups look laughable. But there are a couple reasons why we do know what the iSlate will be about.

Apple has done touchscreens before

It will probably look similar to this

By definition, a tablet PC is going to have a large touchscreen. Normally it’s hard to guess what a company might do with such an interface, however the iPhone has been around for 3 years (and 3 iterations), so we know have an idea of how Apple likes to use touchscreens.

Apps

Not even Apple saw how big apps would become, although it’s now obvious that they must be a focal point of the tablet — they just make too much money to ignore. It’s unfeasible that the Apple tablet would not feature apps front and center.

We’re expecting a computer this time

But it won't look like this

In the build up to the iPhone, all anyone could think about was the iPod, which led most of the rumors to involve an iPod with phone capabilities tacked on. Finding out that the iPhone was actually a computer in your pocket was a pleasant surprise. But a tablet is supposed to be a mini computer. No surprise there.

Basically, as long as Apple does indeed release a tablet PC, there is little room for the speculation to be too far off base. It has to be an app-centric, touchscreen-based PC (not a glorified media player or e-book reader). Other than the keyboard implementation and the size, not much else can be a huge surprise.

But of course, I still can’t wait for it.

Gaping Hole in Penalty-Taking Rules?

December 20th, 2009 by Craig 1 comment »

During Chelsea’s draw with West Ham, an incorrect penalty decision led to Frank Lampard placing the ball on the spot. Immediately after his successful first attempt, the referee blew his whistle and ordered a retake of the penalty, citing encroachment from several West Ham players.

Lampard retook the shot, then retook it once more, following another encroachment. He made all three shots, but each time, keeper Robert Green looked closer and closer to saving the shot. Meanwhile, there was no specific punishment doled out to the West Ham players.

This raises the possibility of an interesting strategy, but one that would be detrimental to the sport. Keepers are given a slight advantage when a penalty is retaken — they have an idea of whether the taker is likely to fake, which side they like to aim for, etc. It can also unsettle the taker, who doesn’t expect to have to retake each attempt.

Based on this, it would seem a good strategy for a team who has just given up a penalty to purposely encroach two or three times. Assuming they agree on the number of times in advance with the keeper, it could give he keeper a much needed opportunity to analyze the situation while the penalty taker becomes increasingly frustrated.

We know that watching a player’s previous penalty attempts is helpful — just ask Ben Foster and Jens Lehmann.

Obviously this is not how the game should be played and it would be aggravating for fans and players alike to watch. I’d liken it to the strategy in American football or basketball of the defensive team calling a timeout to ruin the flow of the game in the final crucial moments.

Surely the rules need to be changed, or referees need to hand out yellow cards more liberally when a several players disrupt the game. Thoughts?

Mobile Twitter bookmarklet displays the new, updated Twitter on your smartphone

December 9th, 2009 by Craig No comments »

Twitter recently unveiled a new interface for their mobile site located at mobile.twitter.com loaded with the features you’re accustomed to having on the desktop version of the site. However, when you browse to Twitter or follow a link from an email on your mobile phone you’re still shown the older, far less useful interface by default.

To automatically view any page in the new interface, just use the bookmarklet below. If you’re currently on a Twitter page you’ll be redirected to the same page on mobile.twitter.com; or, if you’re anywhere else at all, you’ll simply go to the mobile home page.

The bookmarklet: Mobile Twitter

Or, to install it on an iPhone, follow these steps.

  1. Click here, and bookmark the resulting page once it loads by clicking the + icon at the bottom of Mobile Safari. (It will look just like the page you’re on.) Call it something like “Mobile Safari”.
  2. Tap the bookmarks icon to open your bookmarks, then click Edit
  3. Tap on the bookmark you just made. Then tap on the second line, containing the URL, to edit it.
  4. Hold your finger down on the URL until the magnifying glass appears. Slide your finger to the left until you see “#__javascript”. Put the cursor just before “javascript”, then hit Backspace to clear out everything that comes before it.
  5. Click Done. The URL should now be a bunch of code beginning with “javascript”Edit bookmark dialog, complete

And that’s it. To use it, just open your bookmarks and tap on your new Mobile Twitter bookmarklet while you’re viewing any page.