Author Archives | Stuart

Google Page Speed

In April 2010, Google made an announcement that they were including web page loading speed as a metric for page rank. This reiterates the importance of having strong technical skills to hand in achieving SEO. At the same time, Google offered a number of tools to help webmasters achieve faster page loading times.

One of these tools is a browser plugin for Firefox/Firebug, once installed you access the information from the Firebug console. Page Speed rates elements of your page, how quickly it loads and offers advice on how to speed it up. This includes tips such as minifying JS and CSS, serving static content from cookieless domains, putting JS and CSS in the right order in your pages and so on and hundreds of other rules. There have been other such plugins available before, such as Yahoo’s YSlow which does much the same although both can be used in conjunction with each other as they cover slightly different rule sets.

The other ‘tool’ that Google offer is an Apache module, mod_pagespeed, that actually does a lot of rewriting on the way out. The module works only for Apache 2.2+ and can be configured to make a lot of the changes that are recommended by the plugin. For example, it can strip whitespace out of files it serves, minifies JS and CSS, can reduce images, serve images as inline data:// and do all manner of other things.

Installing mod_pagespeed on Debian or Ubuntu proves pretty straightforward. The steps, as root on a 32 bit system, are:-

wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-beta_current_i386.deb
dpkg -i mod-pagespeed*.deb
apt-get -f install

Once installed, you can configure the module:-

vi /etc/apache2/mods-available/pagespeed.conf

By default, very little change is made to your serving environment but you can add in ‘filters’ to the config file. For example, to have the server combine all CSS files into a single file, add the filter:

ModPagespeedEnableFilters combine_css

To minify CSS, add this filter:-

ModPagespeedEnableFilters rewrite_css

After installation and any configuration changes you must restart Apache and straight away you will see the results, with pages being rewritten on the fly to reduce the amount of data being transferred and the number of round trips to the server. Familiarise yourself with the different filters available for mod_pagespeed and make sure that you configure the module in the way that you wish. Be aware that each module carries an element of risk which is outlined in the documentation. For example, some of the page rewriting may break your pages if you walk the DOM using an expected structure rather than dynamically. Risks associated with each filter are clearly outlined and you must decide whether each is likely to cause problems on your site.

mod_pagespeed is still only in Beta, it was only launched in November 2010 so this is still early days, but our experience with this module shows that it is a good weapon to add to the SEO arsenal, provided you are running Apache 2.2, and webmasters should welcome it, particularly in environments where there are many developers contributing to web content, some of whom may not have much of an insight into optimising pages.

Posted in SEO0 Comments

Writing Apps for iPhone OS3, 3.2 and iOS4

The recent launches of iPad and iPhone4 have led to a flurry of activity on the iPhone operating system front. iPad launched with iPhone OS 3.2 but this OS was never destined for iPhone itself. iPhone 4 has introduced another OS release, with a nameshift from ‘iPhone OS’ to ‘iOS’ 4. iPhone and iPod users are expected to migrate to iOS 4, but the upgrade isn’t mandatory. Eventually no doubt the iPad will join iPhone on a universal OS, in the meantime, you’re likely to find that your having to support three, and maybe more, different versions of the OS, across various devices.

When you’re coding for a specific OS, you should not look at the version number and base your logic on that. Here is an example of what to avoid:-

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2)
        { /* do iPad stuff here */ }
    else
        { /* do iPhone stuff here */ }

Whilst that is a perfectly legitimate way to be looking up the OS version, in reality you are less interested in the OS version per se so much as the capabilities of the underlying OS. Code that might work today can easily break. Here for example, you iPad intended code is going to run on iPhone’s upgraded to iOS4.

Instead, you should use the class method available to NSObject and all descendants:-

+(BOOL) instancesRespondToSelector: (SEL) aSelector

So you could write, for example:-

if ([[UIApplication sharedApplication] respondsToSelector: @selector(setStatusBarHidden: withAnimation:)])
        { [[UIApplication sharedApplication] setStatusBarHidden: YES withAnimation: UIStatusBarAnimationFade]; }
    else
        { [[UIApplication sharedApplication] setStatusBarHidden: YES animated: YES]; }

Here we test whether we use the method setStatusBarHidden: or the newer method setStatusBarHidden: withAnimation:. This will compile and run under different OS versions and give us the required means to act according to OS capabilities.

This test can be particularly important when writing for newer version of the OS but looking to support older ones. Occasionally additional classes and methods that have previously been private are promoted to public use and are documented, but using these under older OS’s will still trigger the automatic rejection for using undocumented methods in the Cocoa Touch libraries. For example, UINib is a new class made available in iOS 4.0 for working with cached NIB files. Although this class was always there, it used to be out of bounds. Using this class in an app written for iPhone OS 3.x will lead to rejection. Testing methods for this class with ‘respondsToSelector’ will only return true if the method is public and you are entitled to work with it.

If you are looking to change screen layouts or other functionality depending on the actual device, Apple have created a new property of a UIDevice object. This macro will test whether you are on an iPad (UIUserInterfaceIdiomPad) or iPhone/iPod Touch (UIUserInterfaceIdiomPhone).

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
     {     /* The device is an iPad running iPhone 3.2 or later. */ }
else
      {  /* The device is an iPhone or iPod touch. */ }

Wrap this around views where you want to achieve different layouts according to the screen sizes, and anywhere else that you have iPad specific behaviour.

Posted in Development, iPhone, iPhone Development, Objective-C0 Comments

Delegation and Notifications, Oddities or Pure Elegance?

Objective-C and Cocoa Touch are strong on design patterns and principles. If you adhere to Apple’s way of coding then you’ll create reliable and reusable code. If you’re new to Objective-C, some of the design principles can be quite daunting and if your background is in other object oriented languages, some of the design patterns may initially appear quite alien.

Delegation and notifications present two such slightly odd patterns, but once you understand them they are actually rather elegant in what they achieve.

Delegation

Most people describe delegation as a method of subclassing, and essentially that’s right. Delegation wouldn’t exist though if it were simply an alternative to subclassing, so you can be sure that it solves other problems. I like to think of delegation almost as a work in progress – a class knows what it has to achieve and is implemented accordingly, but delegation allows a broad class to be written in such a way as to leave the final detail to future imagination. This is achieved by assigning your object as a delegate to a predisposed object; your new object can implement a bunch of methods that will be called by the delegating object whilst benefiting from the much broader underlying library.

The most common use of delegation must be handling UITableViews. The core Cocoa Touch library implements nearly everything a table requires in order to handle display itself, but how the cells are laid out, how your app responds to touches and so on is all left to your implementation. Most of the table handling code is given and you need not concern yourself to the inner workings, but you have to complete the final part – you must define how many sections there are in your table, how many cells in each section, how each cell will be laid out, whether there is a disclosure button and what should happen if the table is selected. All of this behaviour is defined by you – you are offered templated ‘hooks’ that you can fill in or remove depending on how you want your actual implementation to behave. Sometimes delegate methods are required to be completed, other times they are optional.

Cocoa Touch uses delegation extensively, indeed the main application is executed via delegation, hence your appDelegate. You’ll come across delegation in many other situations as you start creating apps for the iPhone and iPad.

Notifications

Another peculiar design pattern in Objective-C is that of notifications – that’s NSNotifications, not the more recently implemented Push Notifications. Notifications are very different to delegation and yet they share a common goal – both offer a way for remote classes to interact with your own objects.

An app has a ‘notification centre’ that is like a central switchboard within your app. Any method can send notices to the notification centre as it does its work. Any object can ‘tune in’ to the notification centre, choosing to listen to all broadcasts, or just to notices relating to particular topics. The API’s that you use with Cocoa Touch broadcast messages extensively in the background. You won’t be aware of this until you subscribe to notifications, and suddenly you’ll be inundated with reams of information as your app goes about its duties!

You can take advantages of notifications by responding to events that you wouldn’t otherwise have visibility of. For example, MPMoviePlayerController prior to iPhone OS 3.2 gave almost no access to know when a movie was stopped, started or when other buttons were pressed. Monitoring when a movie was stopped was widely documented – you subscribed to the relevant notification that the movie had stopped. But you could also subscribe to other notifications for other events triggered by the player controller and implement your application’s response accordingly.

In the same way that delegates can be used for a remote object to call a method on your own object, so notifications can be used as a way of triggering methods in your classes from a remote object. Whilst delegates can only have one object respond to them, notifications allow for many objects all to respond to a single event. Beware if you are working in a multithreaded environment because you can only subscribe to notices broadcast within your own thread.

Final Words

Delegation and notifications offer two design patterns used widely in Cocoa Touch, there are many more besides. All in all they each offer a distinct way of achieving some task; on the whole they add flexibility to the main workings of many of the Cocoa API’s, decoupling the bulk of the workings from the finer implementation. Often they allow the programmer to achieve some monumental tasks in just a few lines of code. How many lines of code to implement a table? …now consider how easily you could do it just using views and subviews and coding it from scratch!

Delegates and notifications are not the exclusive preserve of Apple – you too can create your own delegates and fire your own messages to the notification centre. Once you are familiar with Apple’s design patterns, perhaps you will adopt best practice and model them in your own classes?

Posted in iPhone Development, Objective-C0 Comments

Web Apps vs. Native Apps

When the iPhone was first launched, it didn’t launch with a marketplace for apps – indeed Apple didn’t even enable programmers to create applications for the platform at all. Quite quickly though, people worked out that you could create a web based application and style it specially to run in the iPhone screen. The Web App was born, and Apple quickly embraced this entrepreneurial approach by setting up a Web App directory. To have an app listed you just have to submit your URL to Apple and if it conforms to their loose rules and guidelines, it will be added to their listings.

The iPhone runs a very competent and capable Safari web browser which supports current web standards. Interactivity can be achieved using Javascript, there are even a few proprietary extensions to HTML and Javascript (undergoing formal approval to become standards) to cater for some of the capabilities of a touch and multitouch environment.

With the success of Web Apps, Apple took the bold decision to open up the iPhone platform to any programmer, making the SDK freely available, introducing a nominal fee to join their developer program, adding app support into iTunes and introducing a revenue-share model for app publishers. This was a game changing move which other mobile platforms have tried to replicate with mixed results.

Native applications are written in Objective-C, a superset of C and C++, and the SDK includes hundreds of API’s and libraries that allow any programmer to create the true ‘iPhone experience’ for their own applications. There’s a steep learning curve for anyone that hasn’t developed for the Mac platform before, but it’s a rewarding experience – Objective-C is an elegant language and the rich SDK often makes complex tasks relatively straightforward.

Programmers can still create web applications in favour of native applications, and if you don’t want formal listing in the app store or the web app directory, then there are no restrictions on what your app can do, how it behaves or on your business model – you can encourage people to add your app to their iPhone from your own website. However, you cannot recreate the rich experience of native applications, and such apps require an internet connection at all times. Much of the iPhone experience is down to the Wow factor given by:-

  • the animated interface
  • tab and navigation controllers
  • access to the camera, contacts and iTunes library
  • access to location information, compass data and movement data from the accelerometer

Most of this can only be replicated in a web app in a ‘hacky’ way that won’t make your app stand out, and doesn’t do the platform justice.

You can create ‘hybrid’ applications for the iPhone and many apps in the store take this approach. They take advantage of the native SDK to give the app the overall iPhone navigational experience, but they are filled with HTML content, either stored locally or on a remote web server. If your company has web content that you want embedded in your app, then this presents a great way to do this without having to maintain different information sources. Beware that apps taking this approach may display no content if there isn’t an internet connection, and part of Apple’s requirement is that apps handle lack of internet connectivity gracefully.

The ‘hybrid’ nature of such apps is achieved through a few simple mechanisms:

  • A screen (view) can contain a web ‘canvas’ (UIWebView) that you can populate with HTML, CSS and Javascript
  • The content of a UIWebView is addressed by a URN pointing to a local file or a remote resource
  • You can have multiple UIWebViews in a single screen (view)
  • Javascript can call out to Objective-C methods
  • Objective-C methods can call Javascript functions within a UIWebView

Learning just enough Objective-C to enable you to build hybrid applications is a great first step to learning how to do much more. At Mindsizzler’s we’re convinced that once you set out, you’ll enjoy the experience and will be thirsty to learn more!

If you need that introduction to learn how to create iPhone applications and achieve a good understanding of Objective-C, Xcode and the iPhone SDK then why not join in one of our training courses?

Posted in iPhone, iPhone Development0 Comments

Objective-C and the Properties of BOOL

At a basic level, boolean logic allows for a value to be either true or false, on or off, 1 or 0. The ways in which boolean types are implemented vary widely across languages and implementations. At the most granular level, computers work with bits that are either set to on or off, whereas some boolean data types in databases cater for three or even four values: 1, 0, null or undefined. Dennis Ritchie’s original C language lacked a boolean type at all but it was added in C99, and C’s primitive ‘bool’ type is available in Objective-C. ‘bool’ can be set to either true or false, 1 or 0.

Objective-C has implemented a more standard boolean property – it offers the BOOL type in addition to the primitive ‘bool’. The Cocoa and Cocoa Touch API’s use BOOL as the standard message response in favour of ‘bool’, so it is a property you must get to understand, and should code your own methods using BOOL as well.

Unlike most other things in Objective-C, BOOL is NOT an object, it is a raw data type. The standard values of BOOL are YES and NO rather than true or false, or 1 or 0. However, under the bonnet YES and NO are simply definitions given to the preprocessor as aliases for 1 and 0. In Cocoa Touch YES and NO are defined in NSObjCRuntime.h:-

#if !defined(YES)
    #define YES (BOOL)1
#endif

#if !defined(NO)
    #define NO (BOOL)0
#endif

This means that BOOL values are NEVER ‘YES’ and ‘NO’ so you cannot test them as such:-

if (myBOOL == 'YES') { ... }

…and they are NOT objects, so you cannot send the message:-

if ([myBOOL isEqualToString: @"YES"]) { ... }

Instead you must test them for true or false, or zero or non-zero:-

if (myBOOL) { ... }

or

if (!myBOOL) { ... }

If you want to log the value of a BOOL property using NSLog, then you can use the decimal signed integer format identifier %d:-

NSLog(@"MyBOOL value is %d", myBOOL);

Because BOOL represents 1 and 0 internally, you can also use the ternary operator to test BOOL values:-

myBOOL ? NSLog(@"Yes") : NSLog(@"No");

…and you can use this technique to convert between bool and BOOL should you so wish:-

mybool = myBOOL ? true : false;

Remembering that BOOL is NOT an object type makes it easy to remember how to declare BOOL properties, namely:-

BOOL myBOOL = YES;

…rather than using a pointer:-

BOOL *myBOOL = YES;

BOOL properties can be set with any of YES / NO, true / false or 1 / 0. All map back to 1 or 0.

Understanding that Objective-C’s BOOL data type is simply mapped to 1 and 0 makes working with BOOL values completely straightforward!

Posted in Development, iPhone Development, Objective-C2 Comments

KVO and Bindings on iPhone

‘Google’ for KVO and bindings for iPhone, and too many results tell you that KVO is not supported on the iPhone platform.  Well, if it wasn’t once, it is now, and it’s a really powerful feature.  KVO is Key-Value Observing – essentially you can add have one object ‘observe’ changes to a property of another object.  When that property changes, a callback is fired and you can trigger an action.  In many respects it’s similar to delegation or notifications, in this instance allowing a callback event to be triggered by changes in your objects.

KVO is commonly used to bind your application data to the interface so that whenever your data changes, the interface is automatically updated to reflect the change.  Here’s an example: imagine that you are writing a game and your score is stored in a property.  Rather than looping continually and updating the score on every iteration, you can observe your score and every time it changes, trigger the display to update automatically.

There are countless uses for KVO, and once you understand how it works, you will probably start using it regularly in your applications.  KVO also helps to implement a clean MVC architecture, although the callback MUST be implemented, so your view controller does require some prior knowledge of the architecture.

Implementation is really straightforward, but you do need to understand key-value coding.  Key-value coding (KVC) offers a different way to access properties of an object.  You’re probably familiar with:-

[anObject setProperty: @"Some string"];
 

or:-

anObject.property = @"Some string";
 

KVC allows you to access an object property by using a key, thus:-

[anObject setValue: @"Some string" forKey: @"property"];
 

If you are writing your own accessors you MUST comply with traditional naming conventions (setter = setPropertyName, getter = propertyName) because KVC assumes the names based on the key.  If you only need standard accessors, you can synthesize your properties and KVO works fine.

If you’re comfortable with that, then setting an observer is as simple as:-

[anObject addObserver:self forKeyPath:@"property" options: 0  context: NULL];
 

…then when ‘property’ in anObject is changed through the KVC method:

[anObject setValue: @"Some string" forKey: @"property"];
 

The observer fires an observer callback, passing in the key of the changed property.  By looking at the key value, you can trigger the appropriate work:-

- (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id)  object
change: (NSDictionary *) change context: (void *) context {
     if ([keyPath isEqualToString:@"property"] ) {
         // update your interface or do something else here...
     }
}
 

You MUST implement the observeValueForKeyPath: ofObject: change: context: method otherwise your app will crash.  Change allows you to access the old or new value, or both, and context allows you to pass in a pointer, enabling you to pass more information into your callback.

That’s pretty much all there is to KVO.  Observing can be quite resource intensive so try to avoid setting lots of observers.  If you want to track a lot of properties, look at implementing a single flag that can trigger work to update all of your properties.

Posted in iPhone Development, Objective-C1 Comment

“We Have Got to Sort This Thing Out”

“There is a real issue here. We have got to sort this thing out” comes a rallying cry from the Cabinet Office as the Leader of the House of Commons, Harriet Harman, has her Twitter account hacked and a tweet posted widely on her behalf. Amongst the bemused, and undoubtedly by now amused, was shadow counterpart Alan Duncan. This comes only two weeks after a similar allegation made by another MP, David Wright, although I believe we’re still awaiting results from the content analysis in this case!

These stories serve to illustrate a number of purposes. First, one suspects that computers used by Cabinet members have pretty tight security – there are probably all manner of authentication tunnels and dongles between the keyboard and GCHQ. Yet, despite this, it still seems that a cabinet minister sees it as being perfectly acceptable to inform the country of their triumphs through a social networking site. Yes, it’s ‘right on’, ‘cool’ and proves you’re in touch – it’s also very democratic. Too democratic – everyone can send tweets, and everyone can send tweets posing as someone else. It also begs the question that if it’s so easy to be that democratic, why do we still elect representatives to our parliament, why can’t we all have our voice?!

But the main point I would like to highlight from these incidents is not political, but the fact that the majority of security breaches in any environment, political, commercial and social, are caused by our own selves.  ‘Hacking’ is much rarer than you would be led to believe by the media; the majority of security breaches are caused when we offer our security details to unknown people on request!  Don’t believe me?  Take a read of Kevin Mitnick and William L. Simon’s eminently readable book The Art of Deception.

I have received phone calls from my bank in the past where they have asked me for my security details – mother’s maiden name, date of birth etc.  Now on the odd occasion that this has happened, I’ve stopped and before blurting it all out, I apologise and say that I have no idea that they are really calling from my bank.  If I banked with Lloyds and heard Bach’s cantata Sleepers Awake playing gently in the background and it was 2002 then I would probably have believed them straight off, but I don’t, it wasn’t and it isn’t – so I have halted the conversation and said that I will call back.  The last time this happened the chap at the other end took quite an afront, he clearly had an important message, but he wasn’t prepared to tell me until he had authenticated me, and I wasn’t prepared to tell him what he wanted to know until I had authenticated him!  Impasse!  I called the bank back on a number published on my bank statements, went through security, and eventually someone else was able to pick up the issue – they suspected fraudulent use of my credit card; fortunately for both parties, they were mistaken.  I am, however, grateful for the occasional false positive because it shows that my bank has systems in place to spot a problem potentially days before I do!

Back to the point… I would be prepared to bet money that in Harriet Harman’s and other similar cases, their social networking accounts weren’t ‘hacked’, but that they fell victim to a simple phishing scam.  Someone asked Harriet harman for her personal login details, and she willingly tyoed them in, forgetting to check that it was indeed Twitter who was asking.  The truth is a bit embarrassing; somehow it seems acceptable that some really smart MIT dropout with an IQ of a gazillion but the social skills of a turnip hacked into a government computer and stole the login details of a cabinet minister.  Slightly less easy to swallow is that a cabinet minister probably logged into the wrong web site (albeit from a secured government computer).

Something has to be done about this!  I see two options.  First the government could upgrade its systems so that its estate of, I don’t know, quarter of a million internet capable devices, is channelled better to prevent this sort of thing happening.  The second option is to train our 500,000 civil servants to be more cautious and to be able to spot these sorts of attacks.  There’s no subterfuge, just looking at the URL of the web page you’re logging into, and a basic understanding of domain name schemas will tell you all you need to know.

Both of these options cost money and will take time – and at a time when we’re not quite sure whether we should be spending as much as possible, or reigning back spending, clearly there’s not going to be a decision taken quickly!

Maybe while the jury is out, there’s one more thing that could be done.  Why doesn’t the government put out a notice to every civil servant to migrate from whatever web browser they use to Firefox?  Once that in itself would have taken an age to communicate, luckily now every civil servant subscribes to the 10 Downing Street Twitter feed, so it’ll only take a moment of the Prime Ministers time to issue a 140 character edict and effect a massive change.  Also lucky for Gordon Brown, Twitter and Firefox are free, so no direct costs there!

Why do I offer this as a stop gap?  Well, take a look at these two web sites and join me, in 850 pixels, after the break…

Twitter ye not!

Twitter ye not!

Hmmm, the first is familiar – we all know Twitter don’t we?!  But the second, ooh, scary!  That’s the sort of screen I’d expect to see if my computer had just been hacked!

But wait, look again, really closely, look at the URL!

Both pictures show the same website!  What a great optical illusion – identical, but different!  One screenshot comes from Internet Explorer (although it looks just as Twee in all other browsers I’ve checked on), the other shot comes from Firefox.  Firefox has spotted a phishing attempt – the website in question is not from Twitter at all, but a fake site that looks suspiciously identical!  It’s a shame that when Internet Explorer 8 launched with this grandiose claim:

Internet Explorer 8 offers the best security protections among leading browsers: a study released today by NSS Labs indicates that Internet Explorer 8 blocks two to four times as many malicious sites as other browsers on the market today.

…that Microsoft forgot to instigate a mechanism to block phishing scams!

If you’ve never understood what a web phishing scam is, then you should by now.  Someone creates a page identical to one that you are familiar with, and you simply type in your username and password unsuspectingly.  They now have your account login details!  If they’re smart and the site you’re logging into poorly written, they’ll even be able to set up a session for you and pass you straight in to the real site – you will appear to have logged in to your real web account even though you entered through a completely different site…you won’t even be suspicious!

How did I come across this particular Twitter scam site?  It was linked from a direct Tweet I received this morning, obfuscated by a tr.im’ed URL…only it wasn’t from Harriet Harman’s office!

Posted in Personal0 Comments

Note to Jonathan Ive…

We’re quite excited about the launch of the iPad. Yes it’s the subject of much controversy (isn’t it just a tablet PC nearly 10 years on from Microsoft’s first announcement? Is it a computer or an oversized phone? Won’t it be useless without a keyboard? …and many are uncomfortable with its closed software model), but for me it’s exciting because it looks set to take this form to a wider market than ever before. What’s the point of the iPad? I can’t tell you right now, but by creating a broad market, the market will define its purpose, and in turn will spur innovation across portable computing. The iPad may not be obvious today, but I am willing to bet it will have a significant impact on the PC market over the next decade.

Jonathan Ive is the darling of the product design world – he is credited with a host of innovative designs that have characterised the Mac world from the late 1990′s, including the iMac, iPod, iPhone and now iPad. For a designer to have created one of these ranges of technology would be an achievement, but to be able to wow the world time after time requires genius! Product design is all about solving problems that the end user never even knew existed; Ive does that so magnificently that he wraps his solutions in forms that are also highly desired.

I like the iPhone, it’s a great device, but there’s a design flaw that bothers me, and from the pictures released of the iPad to date, it looks as if it is about to be repeated! I’m going to call it the ‘orthogonal interface transform paradox’ partly because that sounds grand, but also because the flaw is difficult to summarise briefly! Maybe the problem has been identified before and described elsewhere – I’d be interested to hear comments from product designers who might know? It’s not peculiar to the iPhone, but this is how it manifests itself on this device…

Volume on the iPhone is controlled with a ‘volume rocker’ situated on the top left of the device as you hold it upright. Press the top to increase volume, and the bottom to decrease volume. So far, so good: up is louder, down is quieter – and that’s what common sense dictates. One of the neat things about the iPhone is it’s ability to detect which direction the interface is oriented – rotate the phone sideways and in some applications, the display rotates with you.

The natural orientation for video playback on the iPhone is in a landscape mode. In iTunes you can rotate either clockwise or anti-clockwise and the video player rights itself accordingly. On other applications that play video, the natural orientation requires an anti-clockwise twist to view correctly. Unfortunately, an anti-clockwise transformation now sees the volume rocker working paradoxically – now you have to press left to go louder and right to reduce volume. The onscreen volume control works as you would expect – drag right for loud and left for quiet. Suddenly there are two volume controls available to the user, but ‘loud’ and ‘quiet’ operate in opposite directions on each.

As I mentioned, this isn’t the first technical device to suffer the ‘orthogonal interface transform paradox’. The paradox arises because a fixed physical interface doesn’t adjust to a dynamic display of information. I first noticed this with television remote controls. TV remotes have a channel rocker – press the top to go up a channel, and the bottom to go down. If they don’t have a single ‘rocker’ button, they will have two separate ones to navigate up and down through channels. If you are watching BBC1 and wish to navigate to Channel 5, you simply press ‘Channel Up’ four times. To flick back to ITV1, click ‘Channel Down’ twice. That seems pretty logical – BBC1 – UP – BBC2 – UP – ITV1 – UP – Channel 4 and so on… However, bring up the onscreen channel guide, and channels are listed with BBC1 at the top. Place the TV pointer on BBC1 and in order to get to Channel 4 you now have to press ‘Channel DOWN’: BBC1 – DOWN – BBC2 – DOWN – ITV1 – DOWN – Channel 4. The interface is completely reversed.

This isn’t a hugely serious issue, it’s unlikely that it’s led to loss of life, but it is a problem that product designers should look to solving in order to give a consistent interface experience. Furthermore, should such flaws ever be resolved, then we will all forget that they ever existed. As you can see, there’s little ‘thanks’ returned to the good product designer – all the problems were resolved before we were ever aware of them and the genius of the likes of Jonathan Ive goes largely unnoticed. Perhaps a future version of iPhone or iPad will switch the behaviour of the volume rocker in software as the device is rotated, then it’ll just be another neat feature designed into the device that is lost on most of the punters!

Posted in iPhone Development, Personal0 Comments

SQLite, Firefox and Vacuuming Databases

As I mentioned in my post on persisting data on iPhone, Firefox uses SQLite under the bonnet for a variety of tasks.  I use Firefox on all platforms and from time to time I find that it gets sluggish.  Unfortunately this is largely down to SQLite.  As with any database, even SQLite needs managing over time, and this is something that Firefox doesn’t seem to do well.

To write data into a row, a database will allocate some space and then write into it.  As a database grows, so this hapens over and over.  Usually a table will have grabbed a volume of space when it was created and initially rows are written sequentially into this block.  When it fills, a new block is added and so on.

To retrieve information, your RDBMS will seek through the records stored in those blocks of data, scanning through record by record, unless of course your data is indexed in which case it can jump much more accurately to the correct location.

When you delete a row of data, the information is dropped from your database, but the space allocated to that row remains in place.  When the database scans through, there is an overhead to recognise that space and jump on to the next location.  Also over time, the blocks of data dedicated to each group of rows in your table get dispersed over your disk.  This all makes for higher overhead when you come to read your data.

Just as most disk drives need the occasional ‘defrag’ run on them, so a database does too.  In PostgreSQL and SQLite this is achieved using the ‘vacuum’ command, simply:-

vacuum myTable;

or just:-

vacuum;

…to defragment the entire database.   MySQL also requires defragmenting but this is done using the ‘optimize’ command.  This process will rewrite your data into a new, sequential block, clearing out any space left by redundant data.  After a vacuum you should see a reduction in the storage space allocated to each table.

Returning to the point of this post, Firefox can get quite tardy if it is not periodically vacuum’d.  To manage this, on Windows and Linux download and install the SQLite command line tool, go to the directory where your profile is stored and then issue the following command (for Linux/Mac):-

for i in *.sqlite; do echo "VACUUM;" | sqlite3 $i ; done

or Windows:

for %i in (*.sqlite) do @echo VACUUM; | sqlite3 %i

Another option is to go into Tools -> Error Console and paste in this line:-

Components.classes["@mozilla.org/browser/nav-history-service;1"].getService(Components.interfaces.nsPIPlacesDatabase).DBConnection.executeSimpleSQL("VACUUM");

…and click ‘Evaluate’. The interface will freeze for a few seconds while the vacuum is perfomed, then the console will close to signal completion.

A tip for using Firefox on Mac, make sure that you clean your ‘Downloads’ list regularly, letting this list grow can also bring Firefox to a standstill!  You don’t need to move the files, just clear the list from the Downloads window.

If things had become sluggish then hopefully you’ll notice an improvement!  From a development perspective, if you use SQLite in your own projects, make sure you manage the database by issuing the occasional vacuum on it!  Done frequently, a vacuum takes almost no time at all.  Left for a long time, this process can lock up the database for a noticeable time.

Posted in Development, SQL0 Comments

Data Persistance on the iPhone

If you’re writing apps for the iPhone, sooner or later you will want to be able to persist data between sessions. You might want to store hi-scores, preferences, favorites, log metrics or achieve some other task. The iPhone supports three main interfaces for persisting data, ultimately they all write out to disk. In time you will probably find you use all three methods, each one suits different tasks.

Property Lists

Property lists, or plists, offer a way to write a dictionary of data (key – value pairs) out to a file. The native format is XML file, but you don’t need to load the file and parse it, you can simply read the file and de-serialize the information back into objects. To write out, you just create your dictionary object and serialize it to a file. Plists offer a lightweight method to store data and work well when you have a clearly defined set of objects to persist, perfect for hi-scores, favorites and preferences. Read the data in your application delegate in applicationDidFinishLaunching, and write it back out in applicationWillTerminate.

Reading and writing to Plists is pretty trivial. Once your ‘favorites’ data is stored in a dictionary:-

- (void)writeToFavorites: (NSDictionary *) myFavorites
{
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSString *filePath = [path stringByAppendingPathComponent:@"favorites.plist"];
    NSMutableDictionary* plistDict = [[NSMutableDictionary alloc]
                                      initWithContentsOfFile:filePath];
    [plistDict setValue:myFavorites forKey:@"Favorites"];
    [plistDict writeToFile:filePath atomically: YES];
}

…and to read it back in again:-

- (NSDictionary *) readFavorites
{
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSString *filePath = [path stringByAppendingPathComponent:@"favorites.plist"];
    NSMutableDictionary* plistDict = [[NSMutableDictionary alloc]
                                      initWithContentsOfFile:filePath];
    NSDictionary *myFavorites = [plistDict objectForKey:@"Favorites"];
    return myFavorites;
}

Plists support various data types including strings, numbers, arrays and dictionaries, so they can be used to store complex data structures and best of all, there’s no parsing to do!

SQLite

For more complex data interactions, nothing beats a good old fashioned database.  SQLite has been available on iPhone since its launch and historically was used in Apple’s core applications.  SQLite is available across platforms and is the workhorse for tasks inside many applications, for example Firefox uses  SQLite for tracking downloads, bookmarks, history and other tasks.

SQLite offers a lightweight SQL interface to your data.  Your application must create tables and write data into them using SQL commands.  As it’s name suggests, SQLite is ‘lite’ – although it offers RDBMS functionality, it has some quirky features when compared to traditional RDBMSs such as Oracle, Microsoft SQL Server, MySQL or PostgreSQL.  For example, most data formats boil down to a string representation, this leads to the dynamic typing capabilities of Perl or PHP!  Binary data can be stored in SQLite databases which means that whole objects can be stored out in much the same way that Plists can store data objects.

Working with SQLite on iPhone requires tools to support being able to view the state of your data as you develop your application.  Because of the app’s sandbox environment, you will need to store your database in the Documents folder inside your app directory.  There are a number of viewers for SQLite databases, I use the SQLite Manager plugin for Firefox which is perfectly adequate. When compiling for iPhone simulator you can drill down into the application directoryand view your database in situ,  To view a database on your iPhone, first you must pull the SQLite file onto your Mac using Xcode’s Organiser.  Download the database to your local disk and then open in the manager.  Be aware that each time you compile your app for Simulator, the app id changes, moving the database location with every run.

In order to use SQLite in your own projects, you must add the framework into your project in Xcode.  Right click on the Frameworks folder in your Xcode project and choose ‘Add existing framework…’.  SQLite is located at:-

/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOSx.x.sdk/usr/lib/libsqlite3.0.dylib

Make sure that you select ‘libsqlite3.0.dylib’ as this always points to the latest build of the version 3 framework.

The main SQLite website offers full documentation, learn more there about what SQL features are and are not supported.

Core Data:

This Cocoa framework was made available to iPhone OS 3 and is Apple’s preferred way to persist data.  Under the bonnet, Core Data actually uses either SQLite or Plists to store your data – it makes the choice.  Although this is Apple’s preferred method for persisting data, it may not be yours!

As with SQLite you must add the Core Data framework to your project – this is located with the other Cocoa frameworks.  Use Xcode’s Data Modeller to create your data structure, this is much like creating a SQL database with a GUI tool.  Once you’ve done that, Core Data methods give you a powerful interface to your data.

One good reason to favour SQLite over Core Data is that SQLite is more portable, and if you are looking to migrate your app between iPhone and Android, then you’ll be able to share code more easily.  Core Data does give you some pretty compelling features should you need them – undo capabilities in your app, spell checking and it automatically looks after persisting your data to disk.

- (void)readPlist
{
    NSString *filePath = @"/System/Library/CoreServices/SystemVersion.plist";
        NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

        NSString *value;
        value = [plistDict objectForKey:@"ProductVersion"];

        /* You could now call the string "value" from somewhere to return the value of the string in the .plist specified, for the specified key. */
}

Posted in Development, iPhone Development, Objective-C0 Comments

Advert

For more information about our services…

Contact Us

Wordle of the Day

Image from software at http://wordle.net
Data by Web Trends Now

Categories