Author Archive

Design a Simple Tab Based Widget

Widgets appear all over web sites these days. Little boxes of context that you can unwrap to reveal all sorts of wonderful information.

As a web developer, you will often be asked to provide them, and there are various ways of doing this.

Here is my recipe. It doesn’t use any graphics, and relies instead entirely on CSS and JQuery, which makes it really light and easy to use.

Stuff you can’t do with an iPhone: the definitive list

This is a list of stuff you can do with an Android phone, but can’t with an iPhone.

View Flash movies in websites

Use Bluetooth to transfer files or control remote devices

Connect to a Samba Network share to save your photos and videos

Take a photograph with a flash

Delete more than one photograph at a time

Mount your phone as an external drive to pull/push files to/from your PC

Buy music from someone other than iTunes

Install an application that hasn’t been approved by Apple

Use an older version of your operating software

Use an SD card to expand your storage capacity

Buy a replacement battery

Use a second, backup battery

Remove the SIM card without a paper clip

Turn on/off WIFI with a single key press

Use a standard mini-USB cable to charge it

Receive a WAP Push SMS message

Update your operating system without having to connect to a computer

Upload a file to a website through your web browser

Choose a different on screen keyboard

Schedule tasks to occur automatically eg turn down volume after 11pm

Customise your home screen

Add widgets to you home screen

Access more than 3 panels on your home screen

Control your phone from your computer

How I solved the iPhone Restore Error 3194 problem

This is a saga, but if you’ve been tearing your hair out trying to upgrade to version 5.0 of the Apple iOS on your iPhone, its probably worth reading.
Here’s the background.
Up to Oct 2011, iPhones came installed with iOS 4. iOS 5.0 was then released, and all iPhones sold after this time were sold with iOS 5.0.
To be honest, I don’t know what the difference between iOS 4 and iOS 5 is. I needed an iPhone to test some mobile websites (I wouldn’t buy one for personal use under
any circumstances, because they’re just hand candy) and all I know is that somebody gave me an iPhone 3GS phone that they had finished with, and had it unlocked from
Vodafone so that I could use it on O2. To complete the unlock process I had to do a restore of the iPhone with iTunes, and iTunes would not let me do this unless I
upgraded to iOS 5.
And so the story begins.
When I first attempted to do the upgrade, iPhone happily started downloading the new software. The payload is approx. 700MB, so I knew  it would take a while. However,
it crapped out after approx. 50MB, so I started it again. Same thing, crapped out again, and again, and again.
I did a bit of research on this, and was told by the Apple Support web site that I should ensure I had the latest version of iTunes. My version was about 6 months old,
so I went ahead and downloaded the new version.
Now when I tried, iTunes wouldn’t connect at all to the software update server, and just crapped after waiting 30 seconds to connect.
More research.
I discovered that this was a very common problem, and one that not too many were able to resolve. The most common suggested resolution involves editing the local hosts
file on your Windows system (C:\windows\system32\drivers\etc\hosts). This is in fact a load of crap.
The reason why this is a suggested solution is because lots of people have installed Jailbreak software on their PCs. This software inserts and entry into the hosts
file so that iTunes is directed away from Apple’s software signing server when doing restores. If that hosts file entry remains, you won’t be able to contact Apple’s
signing server when you want to do a genuine restore, for a software upgrade for example, so removing the entry helps. However, for people who have never tried to
Jailbreak, this is just a waste of time. In fact, such users won’t even find the rogue entry in their hosts file.
Digging a bit deeper, I discovered that iTunes lets you load the software upgrade from a local source, by pressing the Shift key at the same time as you click Restore.
Hence, if I could get my hands on the .ipsw file (this is the file type for Apple iOS updates) that needed to be loaded, I could bypass any issues Apple was having in
connecting to the software upgrade server.
I looked around on the web for a source for such files and found this link:
http://appldnld.apple.com/iPhone4/041-8356.20111012.SQRDT/iPhone2,1_5.0_9A334_Restore.ipsw
The server, appldnld.apple.com, is located in the apple.com Top Level Domain, so I figured this was pretty safe. I opened the link in my browswer and the file started
downloading. However, after 50mbs, it crapped out again.
Not wanting to give in on this, I tried a few other things. Suspecting that maybe my local network connection was not roboust enough to deal with whatever crap was
coming out of the Apple network, I logged onto my Linux hosting server in the Amazon EC2 clould and initiated the download from there with wget. This worked a treat,
and I pulled the .ipsw file down onto the server in about 2 minutes.
I then connected to this server using Filezilla and ftp’ed the file down to my local PC. I used Filezila because it can restart failed downloads without having to
restart the download all over again, which is handy for large files like .ipsw files. Witin 30 minutes or so, I had the .ipsw file on my laptap.
Feeling certain that I had now conquered the Apple iOS 5.0 upgrade connundrum, I cranked up iTunes and used the Shift-Restore option to load the locally stored .ipsw
file. It loaded it up and unpacked it, and then told me it was going to verify the software with Apple.
Bang. Game over. An unknown error has occured (Error 3194).
Not to worry, I thought, lets see what Error 3194 means.
http://support.apple.com/kb/TS3694#error3194
Error 3194: Resolve error 3194 by updating to the latest version of iTunes. “This device is not eligible for the requested build” in the updater logs confirms this is
the root of the issue.
Excellent. An obscure meaningless error message that Microsoft would have been proud of. I really shouldn’t have expected anything else.
So back to Google for some more research, and this time I found all sorts of interesting stuff.
Apparently, since the release of the iPhone 3GS, Apple will know longer let you install operating software on your iPhone unless that software is approved by Apple.
That means that whenever you use iTunes to upgrade or restore your iPhone, iTunes will scurry off home to Apple and check that the software you are trying to load is
approved for your model of iPhone. This, it seems, is an attempt to stop people jailbreaking their iPhones, because Apple doesn’t really like people doing things with
their hardware that they don’t approve of.
Anyway, armed with this nugget of information, I contacted Vodafone to ensure that my iPhone was definitely unlocked. If Apple was refusing to allow me upgrade it, I
figured this must be something to do with the status of the handset with the mobile operator to which it was issued.
Not so. Vodafone said that as far as they were concerned the handset was unlocked, and that I would have to copy Apple for technical support.
I did as I was instructed, and was eventually put through to one of their agents to whom I described my problem. He said that Error 3194 meant that I had security
software running on my PC, which I needed to shut down. I assured him I hadn’t, and directed him to the Apple Support website which stated that Error 3194 concerned
the eligibility of phones for upgrade. He then suggested I reboot my PC. I told him I wasn’t going to do this, and that he was wasting my time.
He got a bit flustered at this and put me through to one of this supervisors. This guy seemed to know a little bit more so I explained the actions I had taken thus
far. However, when I told him that I had downloaded the .ipsw file directly from a download server, he sprang to life, and I knew I had made a mistake.
This was not possible to do, he stated, the only way to get the software was through iTunes, and the software that I was now trying to load was obviously a jailbreak
image from a 3rd party and that this was why the upgrade wasn’t working.
I tried to explain to him that the download came from within the apple.com domain, which meant it was legit, and asked why iTunes allowed you to load a locally stored
.ipsw file if it was not possible to get such a file directly from Apple.
No, he said, he worked for Apple and he knew what he was talking about.
I tried to convince him still further. I showed him that the appldnld.apple.com resolved to an IP address that was leased to Akamai Technologies, the company that
manages all of Apple’s media downloads.
No, he said, he worked for Apple and he knew what he was talking about.
At this point, I let him and off and we went through his checklist for solving software upgrade issues.
We cleared the DNS cache. No difference. We created a new user account under Windows and tried the download using that (!!). No difference. We cleared the comments out
of the Windows hosts file and rebooted (!!!!!!). No difference.
I asked him if he knew what server iTunes tried to connect to when doing upgrades, and on what TCP port, so that we could test that he independently. He didn’t know
any of these details, and seemed incredulous that he should be expected to know.
He eventually told me something to the effect that I would have to sign up with a new ISP if I wanted to upgrade my iPhone. At this point, I ended the call.
Some good did come of it, however. Having asked the question about the server iTunes connects to, I set about finding this out for myself.
I installed TCPView on my laptop, cranked up the iTunes upgrade process, and had a look at what it was connected to. I found out that it was connected to ip address
82.52.205.135 on HTTP to do the download. This ip address is leased to an Italian Telecoms company, and obviously forms part of Apple’s new iCloud product.
I also decided to see what Apple was trying to download, and looked in C:\users\garreth\AppData\Roaming\Apple Computer\iTunes\iPhone Software Updates, which is where
iTunes keeps the .ipsw files it downloads from Apple.
Here, I found a file called iPhone2,1_5.0.1_9A405_Restore.ipsw.download, which was obviously the partial download of the full .ipsw file.
Now, notice the difference in this file name the the one I originally downloaded.
iPhone2,1_5.0_9A334_Restore.ipsw
v
iPhone2,1_5.0.1_9A405_Restore.ipsw
Yes, iTunes was trying to download a newer .ipsw file that the one I had downloaded! Of course, iTunes wasn’t letting me use my .ipsw file because a newer one exists,
and Apple doesn’t allow you install older .ipsw files than the current up to date version.
Now, all I had to do was find a copy of the newer .ipsw file that I could download directly and try and load that.
I Google’ed iPhone2,1_5.0.1_9A405_Restore.ipsw and found the following link, which was again on the appldnld.apple.com server, the one that the guy in Apple support
swore blind had nothing to do with Apple and was giving me jailbroken software:
http://appldnld.apple.com/iPhone4/041-3307.20111109.5tGhu/iPhone2,1_5.0.1_9A405_Restore.ipsw
I downloaded this one in the same way as before (via my Linux server) and tried the Shift-Restore option again.
And guess what? It worked! The new iOS was loaded to my iPhone and I now have an unlocked iPhone that I can use on the O2 network.
So what do you need to know from all of this. A few things.
First of all, it is possible to load a locally stored .ipsw file into iTunes. You just need to ensure that it it the most up to date version of the iOS. The Tech
Support guys in Apple are obviously not told this, and it would probably result in them get users to do all sorts of crazy things with their PCs, which could end up in
Apple getting sued (”Woman strangles cat with computer cable while trying to upgrade iPhone” etc)
Secondly, the iCloud service that Apple has started using to distribute media is obviously very flaky. Presumably, I was directed to a server in Italy because I live
in Europe. Users in other parts of the world will no doubt have differing experience, but it certainly seems that the Italian arm of iCould is waaaaay underspec’ed.
Thirdly, you really should give serious consideration to using something other than an iPhone as your smartphone. The saga I have described above if very common in the
iPhone user population, and is unheard for Android users. I myself have an Android. I’ve updated the operating system on it twice. When it needs an upgrade, it tells
me, and I then let it download the upgrade overnight. When I get up in the morning, its done. No hassle.
Also, my hadnset manufacturer, HTC, is quite happy for me to use whatever operating system I want on my phone, which is what I’d expect, given that I paid for it and
own it. The fact that this isn’t the case with Apple should be all you need to know.

This is a saga, but if you’ve been tearing your hair out trying to upgrade to version 5.0 of the Apple iOS on your iPhone, its probably worth reading.

Here’s the background.

Up to Oct 2011, iPhones came installed with iOS 4. Thereafter,  iOS 5.0 was released, and all iPhones sold after this time were sold with iOS 5.0.

To be honest, I don’t know what the difference between iOS 4 and iOS 5 is. I needed an iPhone to test some mobile websites (I wouldn’t buy one for personal use under any circumstances, because they’re just hand candy) and all I know is that somebody gave me an iPhone 3GS phone that they had finished with, and had it unlocked from Vodafone so that I could use it on O2. To complete the unlock process I had to do a restore of the iPhone with iTunes, and iTunes would not let me do this unless I upgraded to iOS 5.

And so the story begins.

When I first attempted to do the upgrade, iTunes happily started downloading the new software. The payload is approx. 700MB, so I knew  it would take a while. However, it crapped out after approx. 50MB, so I started it again. Same thing, crapped out again, and again, and again.

I did a bit of research on this, and was told by the Apple Support web site that I should ensure I had the latest version of iTunes. My version was about 6 months old, so I went ahead and downloaded the new version.

Now when I tried, iTunes wouldn’t connect at all to the software update server, and just crapped after waiting 30 seconds to connect.

More research.

I discovered that this was a very common problem, and one that not too many were able to resolve. The most common suggested resolution involves editing the local hosts file on your Windows system (C:\windows\system32\drivers\etc\hosts). This is in fact a load of crap.

The reason why this is a suggested solution is because lots of people have installed Jailbreak software on their PCs. This software inserts an entry into the hosts file so that iTunes is directed away from Apple’s software signing server when doing restores. If that hosts file entry remains, you won’t be able to contact Apple’s signing server when you want to do a genuine restore, for a software upgrade for example, so removing the entry helps. However, for people who have never tried to Jailbreak, this is just a waste of time. In fact, such users won’t even find the rogue entry in their hosts file.

Digging a bit deeper, I discovered that iTunes lets you load the software upgrade from a local source, by pressing the Shift key at the same time as you click Restore.

Hence, if I could get my hands on the .ipsw file (this is the file type for Apple iOS updates) that needed to be loaded, I could bypass any issues Apple was having in connecting to the software upgrade server.

I looked around on the web for a source for such files and found this link:

http://appldnld.apple.com/iPhone4/041-8356.20111012.SQRDT/iPhone2,1_5.0_9A334_Restore.ipsw

The server, appldnld.apple.com, is located in the apple.com Top Level Domain, so I figured this was pretty safe. I opened the link in my browswer and the file started downloading. However, after 50mbs, it crapped out again.

Not wanting to give in on this, I tried a few other things. Suspecting that maybe my local network connection was not robust enough to deal with whatever bumpf was coming out of the Apple network, I logged onto my Linux hosting server in the Amazon EC2 cloud and initiated the download from there with wget. This worked a treat, and I pulled the .ipsw file down onto the server in about 2 minutes.

I then connected to this server using Filezilla and ftp’ed the file down to my local PC. I used Filezila because it can restart failed downloads without having to restart the download all over again, which is handy for large files like .ipsw files. Witin 30 minutes or so, I had the .ipsw file on my laptap.

(Note: hopefully you won’t have to do the step above, and have a good enough network connection to get the  .ipsw with your browser)

Feeling certain that I had now conquered the Apple iOS 5.0 upgrade connundrum, I cranked up iTunes and used the Shift-Restore option to load the locally stored .ipsw file. It loaded it up and unpacked it, and then told me it was going to verify the software with Apple.

Bang. Game over. An unknown error has occured (Error 3194).

Not to worry, I thought, lets see what Error 3194 means.

http://support.apple.com/kb/TS3694#error3194

Error 3194: Resolve error 3194 by updating to the latest version of iTunes. “This device is not eligible for the requested build” in the updater logs confirms this is the root of the issue.

Excellent. An obscure meaningless error message that Microsoft would have been proud of. I really shouldn’t have expected anything else.

So back to Google for some more research, and this time I found all sorts of interesting stuff.

Apparently, since the release of the iPhone 3GS, Apple will no longer let you install operating software on your iPhone unless that software is approved (signed) by Apple. This basically applies to everything other than the most up to date version of the iOS. Apple doesn’t want you loading older versions, because some of these let you do things that Apple doesn’t want you to do.

That means that whenever you use iTunes to upgrade or restore your iPhone, iTunes will scurry off home to Apple and check that the software you are trying to load is approved for your model of iPhone. This, it seems, is an attempt to stop people jailbreaking their iPhones, because Apple doesn’t really like people doing things with their hardware that they don’t approve of. As noted above, this is why jailbreaking software directs you away from Apple’s signing server, gs.apple.com.

Anyway, armed with this nugget of information, I contacted Vodafone to ensure that my iPhone was definitely unlocked. If Apple was refusing to allow me upgrade it, I figured this must be something to do with the status of the handset with the mobile operator to which it was issued.

Not so. Vodafone said that as far as they were concerned the handset was unlocked, and that I would have to copy Apple for technical support.

I did as I was instructed, and was eventually put through to one of their agents to whom I described my problem. He said that Error 3194 meant that I had security software running on my PC, which I needed to shut down. I assured him I hadn’t, and directed him to the Apple Support website which stated that Error 3194 concerned the eligibility of phones for upgrade. He then suggested I reboot my PC. I told him I wasn’t going to do this, and that he was wasting my time.

He got a bit flustered at this and put me through to one of this supervisors. This guy seemed to know a little bit more so I explained the actions I had taken thus far. However, when I told him that I had downloaded the .ipsw file directly from a download server, he sprang to life, and I knew I had made a mistake.

This was not possible to do, he stated, the only way to get the software was through iTunes, and the software that I was now trying to load was obviously a jailbreak image from a 3rd party and that this was why the upgrade wasn’t working.

I tried to explain to him that the download came from within the apple.com domain, which meant it was legit, and asked why iTunes allowed you to load a locally stored .ipsw file if it was not possible to get such a file directly from Apple.

No, he said, he worked for Apple and he knew what he was talking about.

I tried to convince him still further. I showed him that the appldnld.apple.com resolved to an IP address that was leased to Akamai Technologies, the company that manages all of Apple’s media downloads.

No, he said, he worked for Apple and he knew what he was talking about.

At this point, I let him and off and we went through his checklist for solving software upgrade issues.

We cleared the DNS cache. No difference. We created a new user account under Windows and tried the download using that (!!). No difference. We cleared the comments out of the Windows hosts file and rebooted (!!!!!!). No difference.

I asked him if he knew what server iTunes tried to connect to when doing upgrades, and on what TCP port, so that we could test that independently. He didn’t know any of these details, and seemed incredulous that he should be expected to know.

He eventually told me something to the effect that I would have to sign up with a new ISP if I wanted to upgrade my iPhone. At this point, I ended the call.

Some good did come of it, however. Having asked the question about the server iTunes connects to, I set about finding this out for myself.

I installed TCPView on my laptop, cranked up the iTunes upgrade process, and had a look at what it was connected to. I found out that it was connected to ip address 82.52.205.135 on HTTP to do the download. This ip address is leased to an Italian Telecoms company, and obviously forms part of Apple’s new iCloud product.

I also decided to see what Apple was trying to download, and looked in C:\users\garreth\AppData\Roaming\Apple Computer\iTunes\iPhone Software Updates, which is where iTunes keeps the .ipsw files it downloads from Apple.

Here, I found a file called iPhone2,1_5.0.1_9A405_Restore.ipsw.download, which was obviously the partial download of the full .ipsw file.

Now, notice the difference in this file name the the one I originally downloaded.

iPhone2,1_5.0_9A334_Restore.ipsw

v

iPhone2,1_5.0.1_9A405_Restore.ipsw

Yes, iTunes was trying to download a newer .ipsw file that the one I had downloaded! Of course, iTunes wasn’t letting me use my .ipsw file because a newer one exists, and Apple doesn’t allow you install older .ipsw files than the current up to date version.

Now, all I had to do was find a copy of the newer .ipsw file that I could download directly and try and load that.

I Google’ed iPhone2,1_5.0.1_9A405_Restore.ipsw and found the following link, which was again on the appldnld.apple.com server, the one that the guy in Apple support swore blind had nothing to do with Apple and was giving me jailbroken software:

http://appldnld.apple.com/iPhone4/041-3307.20111109.5tGhu/iPhone2,1_5.0.1_9A405_Restore.ipsw

I downloaded this one in the same way as before (via my Linux server) and tried the Shift-Restore option again.

And guess what? It worked! The new iOS was loaded to my iPhone and I now have an unlocked iPhone that I can use on the O2 network.

So what do you need to know from all of this. A few things.

First of all, it is possible to load a locally stored .ipsw file into iTunes. You just need to ensure that it it the most up to date version of the iOS. The Tech Support guys in Apple are obviously not told this, and it would probably result in them get users to do all sorts of crazy things with their PCs, which could end up in Apple getting sued (”Woman strangles cat with computer cable while trying to upgrade iPhone” etc)

Secondly, the iCloud service that Apple has started using to distribute media is obviously very flaky. Presumably, I was directed to a server in Italy because I live in Europe. Users in other parts of the world will no doubt have differing experience, but it certainly seems that the Italian arm of iCloud is waaaaay underspec’ed.

Thirdly, you really should give serious consideration to using something other than an iPhone as your smartphone. The saga I have described above if very common in the iPhone user population, and is unheard of for Android users. I myself have an Android. I’ve updated the operating system on it twice. When it needs an upgrade, it tells me, and I then let it download the upgrade overnight, directly to the handset using WIFI. When I get up in the morning, its done. No hassle.

Also, my handset manufacturer, HTC, is quite happy for me to use whatever operating system I want on my phone, which is what I’d expect, given that I paid for it and own it. The fact that this isn’t the case with Apple, explained here, should be all you need to know.

The Metamorphosis of Apple

In 1984, Apple first aired their Big Brother commercial at half-time in the SuperBowl. Remember it?

The voiceover recites the following monologue:

Today we celebrate the first glorious anniversary of the Information Purification Directives. We have created, for the first time in all history, a garden of pure ideology: where each worker may bloom, secure from the pests of any contradictory... thoughts.
Our Unification of Thoughts is more powerful a weapon than any fleet or army on Earth. We are one people: with one will, one resolve, one cause. Our enemies shall talk themselves to death and we will bury them with their own confusion. We shall prevail!

Apple’s message in this commercial was that they were the antidote to this tyranny of thought purification, that they were the guardians of  free expression, that they could empower the individual.

And, for several years, that was true. Apple did bring the PC to the masses, and served to undermine the dominance of the computing megaliths like IBM.

The problem was that as Apple become more of a corporation, with shareholders and sales forecasts, and not least, competitors, it became increasingly difficult to maintain this ideal, and no where was this more true that with the iPhone.

In the beginning, the iPhone was a technological, and commercial, miracle. It was beautiful to look at and use, and Apple sold millions of things, propelling Apple 2.0 into the stratosphere of corporate IT giants.

While the handsets were flying off the shelves, and no one else was making them, Apple weren’t too concerned with what users did with their phones. Provided they used iTunes to buy music, they could use their hardware, that they owned, to do as they wished. The spirit of 1984 was alive, or at least not dead.

But then, inevitably, the competition arrived, and lots of people started developing software for iPhones, and suddenly Apple released that their users might start using their right to “free expression” to do things that weren’t in sync with the commercial interests of the Apple Corporation.

Apple now faced a choice. They could get on board with the likes of Google, Mozilla, HP, Sun etc and participate freely and enthusiastically in the development of standards based technology, or they could do a Microsoft, and put all their efforts into holding their ground, and hope that clever marketing would make up for the inevitable deficiencies that would result from maintaining a Closed Shop approach to product development.

The crunch came with the release of the Apple iPhone 3GS, the first major revision of the Apple’s flagship product.

Prior to the 3GS, iPhone users were free to load any sort of operating system onto their iPhone they so wished. There were numerous variations out there, which could be loaded via a shortcut in iTunes. This allowed users to do things on their iPhone (that they had bought and paid for) that were not possible with the software loaded by Apple.

This changed with the 3GS. From that point on, it was only possible to load an operating system to your iPhone if that software was signed by Apple. A new version of iTunes was released, which checked the software you were trying to load, and if that was not approved by Apple, iTunes would not complete the installation to your phone.

The significance of this is probably lost on most iPhone users, but it is significant none the less.

For millions of users worldwide, Apple now has complete control of what software they use on their hardware.

Imagine if this were the case with a PC that you bought from PC World. Imagine if you were not allowed to install any software on that PC unless it was approved by a private company like Microsoft?

Now, go back and watch the SuperBowl commercial again.

Which protagonist reminds you more of the Apple Corporation in 2012? The girl with the sledgehammer, or the face on the screen?

Amazon EC2 Documentation confusion

I recently received a notification from Amazon EC2 to the effect that one of my server instances was running on degraded hardware, and that if I didn’t take action, this would result in loss of the instance.

The Cloud Computing service offered by Amazon EC2 is a great service, but it does throw up new challenges that do not exist in more traditional hosting environments. The tendency for server instances to simply ‘disappear’ is one of them, and you need to have your Cloud Computing setup well organised to ensure that disappearing instances don’t adversely impact on your business.

In this case, I was advised that if my instances was EBS-backed, all I had to do was stop and start my instance and that this would migrate my instance to stable hardware.

I try to use EBS-backed instances for all my servers in Amazon EC2, so this seemed like a fairly straightforward solution.

However, when I consulted the advisory link that Amazon provided in the relevant email, I was a little less certain. This states:

If an instance reboots (intentionally or unintentionally), the data on the instance store will survive.

However, under the following circumstances the data in the instance store will be lost:

o Failure of an underlying drive.

o Running an instance on degraded hardware.

o Stopping an Amazon EBS-backed instance.

o Terminating an instance.

To me, that suggested that if I stopped an EBS-backed instance, I may incur some data loss. That didn’t fit with my previous experience of using EBS-backed instances, which I’ve stopped and started frequently, without issue.

Any way, I went ahead and did the stop/start and everything worked out fine, which left me wondering what the warning was about.

The answer is this.

Whenever you deploy an Amazon EC2 instance, whether it is EBS-backed or Instance Store-backed, it comes with ephemeral storage. What differentiates an EBS-backed instance from an Instance Store-backed instance, is the nature of its root volume, not the totality of its storage.

That means that you can have an EBS-backed instance with an EBS root volume, but which might use ephemeral storage for other purposes, or in other words, and EBS-backed instance doesn’t mean that this instances uses only EBS storage.

This is the situation in the document referenced above. If you have an EBS-backed instance that uses its allocated ephemeral storage, and you stop/start that instance, the data on the ephemeral storage will be lost.

Facebook Apps and the Same Origin Policy

Over recent months, Facebook have become a lot stricter in relation to the use of secure URLs for applications presented in the App Canvas and on Page Tabs.

The bottom line in this is that you need to serve your Facebook application content from a secure (https) URL. You can have your app set up to serve on both http and https, but if  you don’t have this https set up correctly, any Facebook user who has Secure Browsing switched on will not be able to use your application.

My reaction to this was to convert all my applications to use https for all connectivity, so as to remove any uncertainty in this regard.

I figured that the users browser would just communicate with my web server over https, regardless of whether the Facebook use was using Secure Browsing or not.

However, there is a big problem with this if you use AJAX calls in your application.

I had set up all my AJAX calls to use https, but if the viewing Facebook user isn’t using Secure Browsing (ie they are connecting to your application over http), you are going to fall foul of Browser restrictions arising from the Same Origin Policy.

This policy is designed to prevent XSS attacks, in that it prevents Javascript from making calls to URLs domains that are not the same as the URL domain the user is viewing. Crucially, this includes the protocol which is used.

That means that if your Facebook user is connecting to http://facebook.nightbluefruit.com for general application content, and the application makes an AJAX call to https://facebook.nightbluefruit.com, the browser will send the request but will refuse to receive the response.

To overcome this, you should really set up your AJAX URLs based on the protocol used to connect to your application. You can use the $_SERVER['HTTPS'] special variable to do this.

Turning the JQuery Lightbox into a Slideshow

The JQuery Lightbox Plugin is probably one of the most commonly used lightboxes on the Internet.

And for good reason. Its simple to use, both for the developer and the user, and it works in pretty much any browser you can think of.

However, it has one minor deficiency in comparison to other lightboxes: it doesn’t have a slide show feature.

I recently set up a site with this plugin, and while the customer was happy, they did want a slideshow. I contemplated installing a different lightbox, but there was pain involved in this too, so I set about trying to add slideshow functionality to the existing JQuery Plugin.

This post got me started, but it was only half the battle, as it didn’t include any functionality to stop and start the slideshow, which is what people would normally expect. So I made my own modifications to the plugin ,and here they are.

So, we’re editing the actual plugin Javascript file that we load in our HTML header. The logic behind the code may or may not be apparent to you, but basically, we are initiating and terminating a Javascript setTimetout function that calls functions use by the Lightbox. Off we go…

First off, add some settings:

$.fn.lightBox = function(settings) {
		// Settings to configure the jQuery lightBox plugin how you like
		settings = jQuery.extend({
			//SLIDESHOW
		        slideshow: true,
		        nextSlideDelay: 4000,
                        [....]

Next, include the Slideshow in the initiate function:

	function _initialize() {
		//SLIDESHOW
		if(settings.slideshow){
		  var tmFunc = function(){ _doSlideShow(); };
		  t = setTimeout(tmFunc, settings.nextSlideDelay);
		}
                [....]

Next, add a new function to the Lightbox, which creates the slidehow:

		function _doSlideShow(){
		     settings.activeImage++;
		     if(settings.activeImage >= settings.imageArray.length){
			  settings.activeImage = 0;
		     }
		     _set_image_to_view();
		     var tmFunc = function(){ _doSlideShow(); };
		     if($('#jquery-lightbox').length > 0){
			  t = setTimeout(tmFunc, settings.nextSlideDelay);
		     }
		};

The above will give you the guts of the slideshow, but now you need the Pause/Unpause functionality.

First, find the _set_interface function and add some HTML to create a Pause link.

Pause

This will appear in the white navigation section that unfurls below each image. You may want to update Lightbox CSS file too to make this nice and neat.

Now, add another new click event function to the _set_interface function. This controls the Pause/Unpause.

	$('#lightbox-secNav-btnPause').click(function() {
		if (timer_is_on > 0) {
			clearTimeout(t);
			$(this).html('Unpause');
			timer_is_on = 0;
		} else {
			var tmFunc = function(){ _doSlideShow(); };
			t = setTimeout(tmFunc, settings.nextSlideDelay);
			$(this).html('Pause');
			timer_is_on = 1;
		}
		return false;
	});

You also need to create 2 variables at the lightbox object level (ie outside the _set_interface function) to control the state of the slideshow, to say if it is paused or unpaused.

var t;
var timer_is_on=1;

Now, the last part. The Prev and Next click functions are still part of the Lightbox in Slideshow mode. It would be my expectation that if I had paused the slideshow, and then clicked Next, that the slideshow would revert back to unpaused mode. Therefore, I also need to add some extra functionality to the Prev and Next click events. This occurs in the _set_navigation function, which is reproduced in its entirety below:

function _set_navigation() {
	$('#lightbox-nav').show();

	// Instead to define this configuration in CSS file, we define here. And itŽs need to IE. Just.
	$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });

	// Show the prev button, if not the first image in set
	if ( settings.activeImage != 0 ) {
		if ( settings.fixedNavigation ) {
			$('#lightbox-nav-btnPrev').css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' })
				.unbind()
				.bind('click',function() {
                                //SLIDESHOW
				clearTimeout(t);
				var tmFunc = function(){ _doSlideShow(); };
				t = setTimeout(tmFunc, settings.nextSlideDelay);
				$('#lightbox-secNav-btnPause').html('Pause');
				timer_is_on = 1;
                                //
				settings.activeImage = settings.activeImage - 1;
				_set_image_to_view();
				return false;
			});
	} else {
		// Show the images button for Next buttons
		$('#lightbox-nav-btnPrev').unbind().hover(function() {
			$(this).css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' });
			},function() {
				$(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
			}).show().bind('click',function() {
                                //SLIDESHOW
				clearTimeout(t);
				var tmFunc = function(){ _doSlideShow(); };
				t = setTimeout(tmFunc, settings.nextSlideDelay);
				$('#lightbox-secNav-btnPause').html('Pause');
				timer_is_on = 1;
                                //
				settings.activeImage = settings.activeImage - 1;
				_set_image_to_view();
				return false;
			});
		}
	}

	// Show the next button, if not the last image in set
	if ( settings.activeImage != ( settings.imageArray.length -1 ) ) {
		if ( settings.fixedNavigation ) {
			$('#lightbox-nav-btnNext').css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' }
				.unbind()
				.bind('click',function() {
                                        //SLIDESHOW
					clearTimeout(t);
					var tmFunc = function(){ _doSlideShow(); };
					t = setTimeout(tmFunc, settings.nextSlideDelay);
					$('#lightbox-secNav-btnPause').html('Pause');
					timer_is_on = 1;
                                        //
					settings.activeImage = settings.activeImage + 1;
					_set_image_to_view();
					return false;
				});
		} else {
			// Show the images button for Next buttons
			$('#lightbox-nav-btnNext').unbind().hover(function() {
				$(this).css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' });
			},function() {
				$(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
			}).show().bind('click',function() {
                                //SLIDESHOW
				clearTimeout(t);
				var tmFunc = function(){ _doSlideShow(); };
				t = setTimeout(tmFunc, settings.nextSlideDelay);
				$('#lightbox-secNav-btnPause').html('Pause');
				timer_is_on = 1;
                                //
				settings.activeImage = settings.activeImage + 1;
				_set_image_to_view();
				return false;
			});
		}
	}
	// Enable keyboard navigation
	_enable_keyboard_navigation();
}

You can download a copy of the converted file from here. You can view a demo on any post on gigape.com

Multiple JPlayers on the same page

JPlayer is a very nice Javascript library that allows you to create HTML5 media players in your HTML pages.

http://www.jplayer.org/

The site creates pretty decent documentation and examples, but I recently came to a dead halt when I had to create multiple audio players on the same page.

The JPlayer site provides an example of this, but it isn’t exactly clear how it works. This post explains exactly what you have to do.

First thing to understand:

In HTML5, when you want to create a media player, you either use the default interface or create a custom interface. If you want to create a custom interface, you have to create separate HTML for the interface. The default JPlayer installation includes a custom interface, so if you want to create multiple players, you have to create multiple interfaces, each of which must be carefully constructed from the point of view of the DOM and CSS.

Each of your interfaces will have a DOM Element ID, which of course must be unique. That ID determines which players activates when a control in that interface is clicked (play, stop, pause etc). If you don’t have this correctly set up, either multiple players will start at once, or nothing will happen at all.

If you only create one player on a page, the default Interface Element ID that JPlayer looks for is “#jp_interface_1″.

If you want to create multiple players, you need to tell each JPlayer instance which interface it is associated with.

To do this, you specify the cssSelectorAncestor property for each player instance you create:

eg

function js_audioPlayer(file,location) {
	jQuery("#jquery_jplayer_" + location).jPlayer( {
	    ready: function () {
	      jQuery(this).jPlayer("setMedia", {
		mp3: file
	      });
	    },
	    cssSelectorAncestor: "#jp_interface_" + location,
	    swfPath: "/swf"
	  });
return;
}

In this example, I’m passing a file and location variable into a wrapper function, which then constructs the player.

In my script, I dynamically create Player DIVs with IDs:

jquery_jplayer_1
jquery_jplayer_2
jquery_jplayer_3
etc

and Interface DIVs with IDs:

jp_interface_1
jp_interface_2
jp_interface_3
etc

and then run the js_audioPlayer() javascript function as many times as I want players:

js_audioPlayer(’file1.mp3′,1);
js_audioPlayer(’file2.mp3′,2);
js_audioPlayer(’file3.mp3′,3);
etc

More: http://www.jplayer.org/latest/developer-guide/#jPlayer-predefined-css-selectors

Adding text to images to promote your site

Promoting a new website is always difficult, and you really need to give yourself every advantage possible if you want to get it out there.

One technique that I don’t see used very often is writing the name of your website on any images that are uploaded to it. When you do this, and your images are picked up by Google, and then used by others when they find them in an Images search, your website gets a free plug.

Writing on images isn’t very difficult at all. Most PHP installations will have GD, and after that, all you need is a TTF font file and the imagettftext PHP function. Basically you just pass your image resource through the function and it comes out the the other end with text on top.

I’m trying to promote the following site at the moment:

Minifigure Mix

which is all about Lego Minifigures.

All of the image filenames contain the words ‘lego’ and ‘minifigure’ and each image has ‘minifiguremix.com’ written on the top left hand corner.

How to update a Facebook Fan Page from PHP

Note: Facebook changes its API as frequently as you change your socks. These instructions worked as of Apr 19th 2011.

In a previous post, I outlined how to update your Facebook Profile from a PHP script.

This is fine if you are using Facebook as an individual, but if you are a business or an organisation, you won’t have a profile, you will have a Fan Page, which people ‘Like’.

Updating a Fan Page from a PHP script is a lot more difficult, because Fan pages are managed by users with standard profile accounts, and you need to obtain a extended range of permissions in order make updates to their Pages.

Anyway, its is possible, and here’s how.

Firstly, this is what you will need:

A proper browser (ie anything other than Internet Explorer) that you can be confident will send long HTTP GET requests

cURL, which can be run from a command line (for testing)

A good text editor

A credit card (weird, I know, but go with it)

A standard Facebook account

Overview

We are going to create a Facebook Application, and add that Application to the Facebook User Account/Profile which manages the Page we want to update. The Application will have the necessary permissions to update Pages which the Facebook User Account/Profile manages.

Step 1: Add the Facebook Developer Application to your Facebook Account

Login to Facebook

(If you have added the Facebook Developer application previously, you can skip this bit)

Go to: http://www.facebook.com/developers/

Look for the button that allows you to add the Facebook Developer Application

If you haven’t added this before, you will need to confirm your identity. You may be able to do this with your mobile phone, but if not you will have to enter valid Credit Details. No charge will be made to your Credit Card.

Step 2: Create an Application

Once the Facebook Developer Application is added, you now create an Application. Call it something relevant. You don’t need to enter much in the way of detail for the application. The only important data you need to enter is under Website, where you should enter a Site URL and Site Domain.

These should be something relevant, for instance, the website address of the business/organisation to whom the page relates. Note: enter a trailing slash for the Site URL eg http://www.mysite.com/
Now, save the details, and you will be returned to a summary page which lists the details for your application. You do not need to submit your application to the Facebook Directory.

From this page, copy and paste your Application ID and Application Secret into your text editor

Step 3: Establish access to your Account/Profile for your Application

Starts to get a bit tricky now, so pay attention. Read everything twice.

You now what to obtain an Authorisation Code for your Application. This code will be generated by Facebook based on the permissions your Application requests from your Facebook User Account/Profile when you add your Application to your Faecbook Account/Profile.

Construct the following URL in your text editor:

https://www.facebook.com/dialog/oauth?client_id=<YOUR APPLICATION ID>&redirect_uri=<YOUR SITE URL>&scope=manage_pages,offline_access,publish_stream

YOUR APPLICATION ID = Application ID you took from your Application Details

YOUR SITE URL = The Site URL you entered when setting up your Application

scope = The permissions you are requesting:

manage_pages = allows application to manage pages for which the user is the administrator

offline_access = allows updates to occur indefinitely

publish_stream = allows application to update the feed of the pages for which the user is administrator

Now, ensuring that you are logged into Facebook, paste the URL into your browser and hit enter.

A Facebook page will render, prompting you to add the application with the permissions as described above. Accept this, and you will be redirected to your Site URL. The actual query string to which you are re-directed will contain a long ‘code’ value. Copy this from your browser address bar and paste into your text editor.

This code is your Authorisation Code.

Step 4: Get an Access Token to allow your Application access your Profile

Now that you have an Authorisation Code, which is a sort of once off thing, you can request an Access Token, which will allow your Application have permanent access to your User Profile.

Again in your text editor, construct the following URL:

https://graph.facebook.com/oauth/access_token?client_id=<YOUR APPLICATION ID>&redirect_uri=<YOUR SITE URL, WITH A TRAILING SLASH>&client_secret=<YOUR APPLICATION SECRET>&code=<YOUR AUTHORISATION CODE>

Be extra careful with this. Its a very long string. Ensure you include a trailing slash in your Site URL.

Now, paste the URL into your browser and hit enter. Facebook should return a single line like:

access_token=220088774674094|c7cb68d51ae2f40e9878ab14.xxxxxxxxxx etc etc

(Note: this is not a real access token, its one I made up.)

You now have an Access Token that allows your Application do stuff to your User Profile

Step 5: Get an Access Token for the Page you want to update

Yes, more Access Tokens are needed! You need a specific Access Token for each Page you want to update! Jesus wept!

Construct the following URL in your text editor:

https://graph.facebook.com/me/accounts?access_token=<YOUR ACCESS TOKEN FOR YOUR USER PROFILE>

Paste it into your browser and hit enter. Facebook will now return JSON objects for each of the Pages and Applications that are under your User Profile. You should see an object for the Page you want to update, each of which will include an ‘id’ and ‘access_token’.

Copy and paste these into your text editor.

You now have an Access Token and Page ID for the Page you want to update.

Step 6: Test!

Finally!

Construct the following command in your text editor:

curl -F ‘access_token=<THE ACCESS TOKEN FOR THE PAGE YOU WANT TO UPDATE’ -F ‘message=It works.’ https://graph.facebook.com/<THE ID FOR THE PAGE YOU WANT TO UPDATE>/feed

Paste to a command line and hit enter. If it works, you will get back a JSON object containing an update id, and the message will appear on the Feed of the Facebook Page.

If not, you will get some class of error. Retrace and try again. I can’t emphasis enough how unforgiving the tolerances are here, but if you persist, it will work!

Once you have it working, you can then build the update into your PHP application using cURL.

More here:

http://developers.facebook.com/docs/authentication/
http://developers.facebook.com/docs/reference/api/