Monthly Archives: March 2010

Apple Posts iPad Guided Tours

Apple’s marketing push for the iPad is going into full swing now that the launch date of the device is only days away. There’s the TV ad, for instance, but what caught my attention today was the series of “Guided Tour” videos Apple posted on its website yesterday.

Each video features a narrator telling you about the iPad’s various feature, while an anonymous pair of hand (and crossed legs to support the device, which seems to be the only way to hold it comfortably) demonstrates exactly how to use the feature being described, including how various gesture controls work within that app.

Needless to say, the narrator is quite enthusiastic about how easy, simple, and innovative everything is, though I suppose if they were strictly relaying information this would be a third-party walkthrough, not an Apple marketing tool. In most cases, iPhone owners will already be familiar with many of the gesture controls and interface elements, but the iPad does have quite a few unique features owing to its greater screen size.

Not all of the claims made in the videos are completely defensible. Saying that a keyboard that’s “nearly the same size” as a standard one makes for “effortless typing,” for instance, doesn’t really convince me, especially when the guy doing the demo is hunt-and-peck typing fairly slowly while you’re saying it.

Seeing all the features detailed and laid out in this way definitely does make me want an iPad even more than I did before, though. A lot of the elements seem, upon reflection, to fill gaps present on the iPhone’s OS. Meaning that things I wish I could do on my iPhone, but can’t for lack of space or other reasons, are implemented on the iPad.

My favorite elements are the iPhoto integration in the Photos application, which should help make iPhoto much more interesting, the iPad camera connection kit, which finally means I can shelve my 30GB iPod Video with its camera connector on trips, and the much-improved YouTube app, since using the iPhone version is one of my favorite time-killers.

If you’re still not sure what all the fuss is about, or if you’re just getting anxious waiting for the delivery guy to show up at your door Saturday morning and want the next best thing to a hands-on experience, check out Apple’s Guided Tour series of videos. There’s 11 in total, covering topics from Safari to the iWork suite, and they’re much more rewarding than either the iPad announcement event or the iPad video that features Apple execs waxing poetic about how awesome the thing is sitting in front of a white background.

5 Steps Toward jQuery Mastery

I am plagiarizing myself!

I originally wrote this article for my friend Moses (of Egypt) to be published in the .Network magazine’s inaugural issue, which coincided with this year’s Cairo Code Camp. Since the article turned out well and there was no corresponding online version, we agreed it would be a good idea to republish it online here too.

Most of us get our first taste of jQuery by implementing a simple animation effect or using a plugin for a specific purpose. This is natural because, like JavaScript itself, jQuery lends itself to beginning with the basics and building from there.

As you branch out from the trivial and begin using jQuery for more complex solutions, it’s important that you stay vigilant for new ways to approach those more involved problems. What works well enough for a dozen lines of code may not work for hundreds, and the unforgiving cross-platform environment that comes along with developing for web browsers only magnifies any trouble you run into.

With that in mind, I want to share a few tips with you that I found valuable as my work with jQuery became more complex.

Use Firebug to experiment interactively

If I could suggest only one thing to you, it would be to use Firebug’s console to prototype your ideas in real time. Nothing matches the command line’s immediate feedback when you’re learning. Rather than go through the hassle of editing a JavaScript file, saving it, and then reloading it in the browser, testing at the console allows you to eliminate those intermediate steps and focus on the task at hand.

In particular, the console is invaluable when testing complex combinations of selectors and traversal methods. Simply execute a jQuery statement at the console, with your page loaded in the browser, and you will instantly see the array of matching elements that are returned. If that result set isn’t correct, press the up-arrow key to retrieve the last command entered, refine the statement, and test it again.

That tight feedback loop is phenomenal for quickly learning the jQuery API without leaving the familiar backdrop of your existing markup.

Additionally, one lesser-known feature of Firebug’s console is how it works in conjunction with Firebug’s debugger. When execution is paused, switching to the console tab allows you to interrogate and manipulate the state of the DOM as it was at the time execution was halted. As you step through JavaScript code in the debugger, the execution context of the console remains in sync with the debugger’s.

Cache selector results

jQuery’s concise syntax makes it easy to forget just how much work the Sizzle selector engine is doing on your behalf. As powerful as the terse selectors are, it’s important not to needlessly duplicate the work that they abstract – especially when using selectors without browser-native backing methods (e.g. a[href^=http], tr:odd, p:contains(Encosia), etc).

To avoid wasteful re-querying, always cache the results of a jQuery selector in a variable if that result set will be used more than once. Once stored in a variable, the result of a selector may be used in exactly the same manner as the original selector itself. For example:

// Wasteful duplication of a slow selector
$(':input[id$=name]').val('Type your name here');
$(':input[id$=name]').select();
 
// Nearly twice as fast
var $name = $(':input[id$=name]');
 
$name.val('Type your name here');
$name.select();

Prefixing the cache variable with a dollar sign is not functionally significant, but helps to clearly indicate that the variable contains a jQuery wrapped set. The topic of Hungarian notation is a contentious one, but I’ve found the dollar sign prefix beneficial as complexity increases.

Don’t use jQuery unless there’s a good reason to

Perhaps one of the most elusive keys to jQuery mastery is knowing when not to use it. Once you’re proficient with jQuery, it seems natural to use it everywhere. However, that tendency may easily mislead you into writing less concise code that runs slower than necessary.

For instance, this egregious example is one that you will see often:

// Typical jQuery over-use
$('button').click(function() {
  alert('Button clicked: ' + $(this).attr('id'));
});

In the context of that callback function, this is a reference to the DOM element that raised the click event – often referred to as the execution context. Rather than using the DOM element to create a jQuery object, with all of the overhead that goes along with that, why not use the DOM element itself?

// Not only faster, but more concise.
$('button').click(function() {
  alert('Button clicked: ' + this.id);
});

Another similar misuse is using jQuery as a document.getElementById shortcut. Though jQuery’s ID selector does leverage document.getElementById, it only does so after parsing the selector and then creates a jQuery object to wrap the element. Not only is there more overhead in that process, but starting with a jQuery object by default guides you toward this mistake of overusing jQuery when it isn’t necessary.

Learn advanced selectors, filters, and traversals

A great way to improve your jQuery code is to learn its selectors, filters, and traversal methods in depth. If you find yourself iterating through a selection and manually filtering it for a desired set, there is usually a better way. Double and triple check that there isn’t a combination of selectors, filters, and/or traversals available to accomplish the same end result.

Not only does using the library’s idioms make your code more concise and expressive, but you will automatically benefit from ongoing performance improvements to jQuery’s Sizzle selector engine that come with each new release. It’s hard to beat having an entire team working to improve your code for you, but that’s exactly what happens when you use jQuery syntax that’s as idiomatic as possible.

A less-frequently documented aspect of learning advanced selectors is that you should be conscious of how to work in concert with jQuery to optimize them. Because the Sizzle engine evaluates selectors from right-to-left, being as specific as possible in the rightmost portion of selectors will improve performance.

Selectors that descend from an ID are one notable exception to the right-to-left rule. Sizzle is specially optimized for that case:

// Breaks the right-to-left specificity guideline:
$('#RegistrationForm input.required').append('*');
 
// jQuery automatically optimizes the previous selector
//  as if you had written it using the ID as a context:
$('input.required', '#RegistrationForm').append('*');

Use CDN hosting when available

When you’re developing and testing locally, it’s easy to underestimate the impact that WAN latency will have on your site. Today’s website is often accessed by a geographically diverse set of users that it is impossible to optimally serve all of them from a single datacenter. Serving static resources, such as jQuery, from content delivery networks is one effective solution to mitigate that problem.

Not only do these CDNs provide a faster, more consistent experience to geographically dispersed users, but they also open up the potential for users to visit your site with a primed cache. Since everyone using these public CDNs reference the same URL, a single browser-cached copy of a given asset may be shared between any number of sites visited by a given user.

Even better, because these CDNs serve their content with a far future Expires header, browsers immediately use a locally-cached version of that file if it’s available. They don’t even have to check with the server for a 304 “Not Modified” response, eliminating the extra HTTP request altogether.

Assets freely available on public CDNs include jQuery itself, jQuery UI, all 14 jQuery UI ThemeRoller themes, and the jQuery validation plugin.

Conclusion

I hope that you’ll find these ideas useful on your road to jQuery mastery. Though jQuery’s clear, intuitive syntax may appear simplistic on the surface, the library is immensely powerful. The key to unlocking jQuery’s full potential is to never stop experimenting and learning new aspects of it.

In the spirit of that continued road toward mastery, consider taking the next step by watching my TekPub series: Mastering jQuery.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

5 Steps Toward jQuery Mastery

How to Access the BBC iPlayer (and TV Like Doctor Who) from Outside the U.K. [Web Filtering]

Non-U.S. users frequently encounter the annoyance of geo-blocked content when trying to access popular sites like Hulu, but every now and then we feel the burn in the States, too. Reader hengehog details how to access BBC’s iPlayer from outside the U.K. More »






Apple Planning iAds Service to Take on Google

Apple hasn’t made any secret about its plans to get into the mobile advertising game. It purchased Quattro in January for around $300 million, a firm that was reportedly its second choice after Google snapped up AdMob for $750 million in November of 2009. Apple had apparently made unsuccessful overtures to AdMob earlier in the year.

A new “iAd” service, which is said to be in the pipeline for an April 7 reveal to the Madison Avenue crowd, according to “executives familiar with the plan” speaking to MediaPost, will be built on top of the framework provided by the Quattro purchase. The sources also quote Steve Jobs as saying the service will be “revolutionary” and “our next big thing.”

No other details are forthcoming as of yet, but it does seem clear that Apple intends to take on Google in the mobile advertising space, and it likely intends to do so by waging the war on home turf. Who better to serve ads to Apple’s mobile devices than Apple itself? Tailoring content to the iPad, iPhone and iPod touch should be easy enough, especially given that Apple has access to more of the iPhone OS than do third-party developers and advertisers.

It may seem like an unexpected move from Apple to move into the advertising business, but it actually fits the company’s M.O. quite well. Think about iTunes and music, iTunes and video content, and now the iBookstore and books. In each case, Apple offered a beleaguered industry a way out of a financially disastrous situation. In doing so, it opened up new revenue streams, and made sure the content desires of its hardware user base were met.

Locking down the mobile advertising market doesn’t necessarily cater to users in the same way, but it does fit the other criteria. Advertisers have been struggling following the gradual and continuing weakening of print media and television, and so far, online ads have only met with limited success and have yet to take off in the way its predecessors did. For companies still looking to find that sweet spot in which it is possible to really sell to web-connected audiences, Apple, with its inside knowledge of mobile web user habits and history of commodifying what once was free (i.e. the Internet, via apps) will look like a very fine prospect indeed.

I’m not generally one to dole out business advice, but if Apple does roll out some kind of iAds platform early next month, get in on the ground floor if you’re in the advertising space. Just look at what Cupertino has already done in terms of making advertisers vie for space in magazines launching on the iPad. Now imagine what it can do when advertising is its primary focus, not just a tangential benefit.

Related GigaOM Pro Research (sub req’d):

Why 2010 Still Won’t Be the Year of Mobile Advertising

New OpenSolaris IP administration

The overall objective for the Brussels project is to provide standard interfaces for network administration. Phase I of the project brought a unified way of administering datalinks including aggregations in OpenSolaris/Solaris 10 with the dladm(1M) command. Now phase II of the project have integrated doing the same for IP administration with ipadm(1M).

Besides making it easier to set up and manage interfaces by using ipadm instead of ifconfig and/or editing various files in /etc it will also make it much easier to get a overview of all addresses and interfaces on a host. A think that directly strikes me is that it will now be possible (without complicated regular expressions) to easy parse parse addresses and other information from active IP interfaces. Ifconfig does not provide the best output for parsing. All this will soon be available for testing in a development build (b137).

Example:
Set up an persistent new persistent address on e1000g0 and viewing it:

# ipadm create-addr -i e1000g0 192.168.0.242/24# ipadm show-addr

INTF      ORIGIN    STATE   ZONES   FLAGS   ADDR/MASKe1000g0   static    ok      global  U-p     192.168.0.242/24

PSARC 2009/306 Brussels II – ipadm and libipadm
PSARC 2010/080 Brussels II addendum
6827318 Brussels Phase II aka ipadm(1m)

Shipping Perfume

We all know that different temperature and exposure to strong sunlight can affect scents. So if you are planning to ship perfume, here are some tips you should need to follow:

If you are shipping anywhere, especially overseas, make sure that you investigate the shipping restrictions. You might be mailing an expensive perfume only to find out that customs will sieze it.

Keep the bottles in their original boxes. If this is impossible. Protect first in bubble wrap to avoid breaking.

Find a box where you can fit the bottle or bottles of perfumes. Put padding in between items, making sure that there are no gaps. Use styrofoam peanuts or old newspaper pieces.

Tape the box shut with packing tape. Make sure that it won’t open at any point during transit. Mark the box “fragile” so it will be handled with care.

Taking Care of Stomach Flu

If there is one thing that a person with stomach flu should be careful about is that of being dehydrated. Here are some home remedies for easing the upset caused by stomach flu.

Take slow sips of fluid. This can be water, lemon lime soda, or sports drink. If you are too weak to lift your head, you can suck on ice. This will keep you from being dehydrated.

Try not to eat spicy, oily, fatty, and acidic foods. Your tummy will only find them more difficult to digest, causing it to become more upset. Stick to soda crackers or other bland foods. Avoid eating after throwing up. Wait for at least an hour before you do so.

Stay at home and rest. Get as much sleep as you can. Your body is not getting enough nutrients so you need to conserve all the energy you can get.

Don’t forget to wash your hands to avoid getting sick. Keep contact with other people limited so you do not spread the flu as well.

How to Safely Back Out of the Driveway

Backing out of a driveway is something every driver should know. But there are accidents that happen while motorists are doing this.

Walk around your car just to ensure that there are no pets, toys, or children in the way. Move obstacles out of the way and have another adult see to children while you are backing out.

While backing out, make sure that you position yourself so that you can look out the rear window while your car is in reverse. This will give you a better viewing access, making sure that you won’t run over anything or anyone.

Do not press on the gas pedal hard when you back out of the driveway. Do it slowly but surely. If you’re new at this, take note that the tires go opposite the direction of your steering.

Improved Irregular Shape UIButton

I took some of the feedback and improved the UIButton subclass from my last post. I implemented a cache for the alpha data and also incorporates changes based on Alfons Hoogervorst’s modifications to my original UIImage category.

You can find the new and improved version of the irregular shaped UIButton code here.

©2008-2010 Jeff LaMarche.
iphonedevelopment.blogspot.com

Irregularly Shaped UIButtons

Note: There is an improved version of the code from this blog post right here.

You probably know that UIButton allows you to select an image or background image with alpha, and it will respect the alpha. For example, if I create four images that look like this:

Screen shot 2010-03-26 at 1.02.47 PM.png

I can then use create custom buttons in Interface Builder using these images, and whatever is behind the transparent parts of the button will show through (assuming the button is not marked opaque. However, UIButton‘s hit-testing doesn’t take the transparency into account, which means if you overlap these buttons in Interface Builder so they look like this, for example:

Screen shot 2010-03-26 at 1.04.17 PM.png

If you click here:

pointat.png

The default hit-testing is going to result in the green diamond button getting pressed, not the blue one. While this might be what you want some of the time, typically this won’t be the behavior want. So, how do you get it to work like that? It’s actually pretty easy, you just need to subclass UIButton and override the hit testing method.

But, first, we need a way to determine if a given point on an image is transparent. Unfortunately, UIImage is an opaque type without a mechanism to give us easy access to the bitmap data the way NSBitmapRepresentation does for NSImages in Cocoa. But, every UIImage instance does have a property called CGImage that gives us access to the underlying image data, and Apple has very nicely published a tech note telling how to get access to the underlying bitmap data from a CGImageRef.

Using the information in that technote, we can easily craft a category on UIImage with a method that takes a CGPoint as an argument and returns either YES or NO depending on whether the alpha value that corresponds to that point is transparent (0).

UIImage-Alpha.h

#import <UIKit/UIKit.h>

@interface UIImage(Alpha)- (NSData *)ARGBData;- (BOOL)isPointTransparent:(CGPoint)point;@end

UIImage-Alpha.m

CGContextRef CreateARGBBitmapContext (CGImageRef inImage){    CGContextRef    context = NULL;    CGColorSpaceRef colorSpace;    void *          bitmapData;    int             bitmapByteCount;    int             bitmapBytesPerRow;

    size_t pixelsWide = CGImageGetWidth(inImage);    size_t pixelsHigh = CGImageGetHeight(inImage);    bitmapBytesPerRow   = (pixelsWide * 4);    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    colorSpace = CGColorSpaceCreateDeviceRGB();    if (colorSpace == NULL)        return nil;

    bitmapData = malloc( bitmapByteCount );    if (bitmapData == NULL)     {        CGColorSpaceRelease( colorSpace );        return nil;    }    context = CGBitmapContextCreate (bitmapData,                                     pixelsWide,                                     pixelsHigh,                                     8,                                     bitmapBytesPerRow,                                     colorSpace,                                     kCGImageAlphaPremultipliedFirst);    if (context == NULL)    {        free (bitmapData);        fprintf (stderr, "Context not created!");    }    CGColorSpaceRelease( colorSpace );

    return context;}

@implementation UIImage(Alpha)- (NSData *)ARGBData{    CGContextRef cgctx = CreateARGBBitmapContext(self.CGImage);    if (cgctx == NULL)         return nil;

    size_t w = CGImageGetWidth(self.CGImage);    size_t h = CGImageGetHeight(self.CGImage);    CGRect rect = {{0,0},{w,h}};     CGContextDrawImage(cgctx, rect, self.CGImage); 

    void *data = CGBitmapContextGetData (cgctx);    CGContextRelease(cgctx);     if (!data)        return nil;

    size_t dataSize = 4 * w * h; // ARGB = 4 8-bit components    return [NSData dataWithBytes:data length:dataSize];}    - (BOOL)isPointTransparent:(CGPoint)point{    NSData *rawData = [self ARGBData];  // See about caching this    if (rawData == nil)        return NO;

    size_t bpp = 4;    size_t bpr = self.size.width * 4;

    NSUInteger index = point.x * bpp + (point.y * bpr);    char *rawDataBytes = (char *)[rawData bytes];

    return rawDataBytes[index] == 0;

}@end

Once we have the ability to tell if a particular point on an image is transparent, we can then create our own subclass of UIButton and override the hitTest:withEvent: method to do a slightly more sophisticated hit test than UIButton‘s. The way this works is that we need to return an instance of UIView. If the point is not a hit on this view or one of its subclasses, we return nil.. If it’s a hit on a subview, we return the subview that was hit, and if it’s a hit on this view, we return self.

However, we can simplify this a little because, although UIButton, inherits from UIView and can technically have subviews, it is exceedingly uncommon to do so and, in fact, Interface Builder won’t allow it. So, we don’t have to worry about subviews in our implementation unless we’re doing something really unusual. Here’s a simple subclass of UIButton that does hit-testing based on the alpha channel of the image or background image of the button, but assumes there are no subviews.

IrregularShapedButton.h

#import <UIKit/UIKit.h>

@interface IrregularShapedButton : UIButton {

}

@end

IrregularShapedButton.m

#import "IrregularShapedButton.h"#import "UIImage-Alpha.h"

@implementation IrregularShapedButton- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{    if (!CGRectContainsPoint([self bounds], point))        return nil;    else     {        UIImage *displayedImage = [self imageForState:[self state]];        if (displayedImage == nil) // No image found, try for background image            displayedImage = [self backgroundImageForState:[self state]];        if (displayedImage == nil) // No image could be found, fall back to             return self;        BOOL isTransparent = [displayedImage isPointTransparent:point];        if (isTransparent)            return nil;

    }

    return self;}@end

If we change the class of the four image buttons in Interface Builder from UIImage to IrregularShapedButton, they will work as expected. You can try the code out by downloading the Xcode project. Improvements and bug-fixes are welcome.

Curiously, the documentation for hitTest:withEvent: in UIView says This method ignores views that are hidden, that have disabled user interaction, or have an alpha level less than 0.1.. In my testing, this is actually not true, though I am unsure whether it’s a documentation bug or an implementation bug.

Update: My Google-Fu failed me. I did search for existing implementations and tutorials about this subject before I wrote the posting (I hate reinventing the wheel), but I failed to find Ole Begemann’s implementation of this from a few months ago. It’s worth checking out his implementation to see different approaches to solving the same problem. There’s also some discussion in the comments about the differences in our implementations that may be of interest if you like knowing the nitty-gritty details. Plus, his diamonds are prettier than mine.

Update 2: Alfons Hoogervorst tweaked the code andshowed how you could reduce the overhead by creating an alpha-only context.

©2008-2010 Jeff LaMarche.
iphonedevelopment.blogspot.com
WP Like Button Plugin by Free WordPress Templates