Flash On

Vodafone Micro SIM iPhone 4 Confusion

17-06-2010

Vodafone Micro SIM for iPhone 4

Having ordered my SIM-free iphone 4 on Tuesday morning super-quick before the Apple store got smudged, I then set about trying to aquire a micro-SIM. This has been a rather arduous task.

I would quite like to stay with Vodafone, since they seem to have the best network generally but am not hugely fussed. Quite staggeringly though, none of the UK networks seem to have any firm details on what happens come launch day. Probably due to how miffed they are at not getting any allocation of phones to sell on to their moronic hoards.

Today I went round every shop in Westfield, Shepherds Bush trying to find out what each operator is doing, not to mention various calls to customer services. No information other than a slightly dubious chap at O2 who promised phones and SIMs on launch day.

Luckily when I arrived home I had received a micro-SIM from Vodafone (destined for an iPad given the associated documentation) but confirmed to work in the new iPhone 4 according to customer services. Apparently I just need to call 03333040044 to activate it on the 24th.

The key seems to be that although you can’t use an iPad activated SIM in an iPhone 4, you can use an unactivated micro-SIM in an iPhone 4.

All very confusing…

Written By Tim for the Stuff section Tags: , , , , ,

Integrating AIR Application with iTunes

04-10-2009

iTunes has long been a closed platform and Adobe AIR is not designed to natively launch or interact with other applications except for the browser. I needed a solution to add MP3 files downloaded through an AIR application to iTunes or any other media player that the user may have installed.

Option 1…

Modifying the iTunes library XML file could potentially be done, but this has risks. Firstly, the XML file can get prohibitively big, and given AIR can only use the DOM method for parsing XML, it could crash the application and do untold damage to the XML library itself, which brings up the issue to backing up the library first. Also unknown is the behavior if iTunes tries to modify the library at the same time as the AIR application, not to mention the requirement to restart iTunes after the change to reflect the changes. All in all this was not a good option, with lengthy development, risky outcome and poor user experience.

Option 2…

iTunes has a COM api library accessible from a native java or .Net application, which in turn could be initiated by AIR. This is far from ideal due to having a second application running on the user’s computer, the volume of development effort to create the application and the complexity.

Option 3…

Users can commonly add songs to iTunes by dragging files into it. This is accompanied by the fact that iTunes launches when double-clicking on any file associated with it such as .mp4 or .mp3 and of course .m3u playlist files. By launching an m3u file with a collection of track paths contained within it, iTunes will launch, songs will be added to the library and user experience is not compromised and development is simple. Although AIR cannot natively launch iTunes, it can launch files, via the browser, thus launching any application that is associated with the file-type. m3u files are commonly associated with iTunes, but also windows media player and any other media player worthy of use.

The key area of development is to dynamically create m3u playlists before calling them with a URLRequest. This function uses Fzip to unzip any zip files that may have been downloaded and creates a collection of paths to write to the playlist file. The playlist data is stored in memory with each download item until the user decides to add the item.

private function generatePlaylist():void {
var playlistName:String = (tmpFile.name.split(’.'))[0]
var os:String = Capabilities.os.substr(0, 3).toLowerCase();

var playlistpath:String
if (os == “mac”) {
if (productType == “album”) {
playlistpath = unzip(File.desktopDirectory.resolvePath(tmpDownloadURL + artistPath + tmpFile.name.replace(”.tmp”,”")).url,File.desktopDirectory.resolvePath(tmpDownloadURL + artistPath).url);
} else {
playlistpath = viewableDownloadURL + artistPath + tmpFile.name.replace(”.tmp”,”");
}
} else {
if (productType == “album”) {
playlistpath = unzip(File.desktopDirectory.resolvePath(tmpDownloadURL + artistPath + tmpFile.name.replace(”.tmp”,”")).url,File.desktopDirectory.resolvePath(tmpDownloadURL + artistPath).url);
} else {
playlistpath = viewableDownloadURL + artistPath.replace(/\//g, “\\”) + tmpFile.name.replace(”.tmp”,”");
}
}
this.Playlist = playlistpath;
}

I kind of got into a mini pickle over forward slashes and back slashes that causes this function to be a little more complicated than is probably necessary, but you get the idea. Next it is necessary to create the playlist file and do the URLRequest after a button-click…

public function addToItunes(e:MouseEvent):void {
var playlistfile:File = File.applicationStorageDirectory.resolvePath(”playListCache/” + e.currentTarget.data[6] + “.m3u”);
var playliststream:FileStream = new FileStream();
var dlManager:DownloadManager;

for (var i:uint = 0; i < downloadManagerObjects.length; i++) {
dlManager = DownloadManager(downloadManagerObjects[i]);

if (e.currentTarget.data[2] == dlManager.FileID) {
playliststream.open(playlistfile, FileMode.WRITE);
playliststream.writeUTFBytes(dlManager.Playlist);
playliststream.close();
}
}
navigateToURL(new URLRequest(playlistfile.url), 'quote');
stage.nativeWindow.alwaysInFront = true;
stage.nativeWindow.alwaysInFront = false;
}

Notably I do a bit of mucking about with the stage to make sure the application stays in front when launching the URL through the browser.

Written By Tim for the Stuff section Tags:

Custom Flex Wordpress Frontend

01-09-2009

New Flash version on Imbimp.com

Creating a front-end for wordpress is incredibly easy and great for making weird and unnecessary versions of the site with UI swoops and swishes. All the data you need is available in the RSS feed for the site. You could even add a special feed specifically for the purpose of supporting a flash version of the site. Just make sure you change the settings to add a good number of full posts to the feed. You can always link back to the site for anything older than that.

The flex version of Imbimp just went live and it tries to improve on the standard Imbimp cardboard interface by keeping everything on one page, where arrows allow the user to browse new content. The widget sidebar is also combined with the navigation. There are no huge benefits to either party (ie me or random imbimp reader) but it’s a good proof of concept of what can be rustled together using Flex in about a day.

Fetching the RSS feed is as easy as calling an httpService…

result=”loadWordpressXML(event)” />

and…

private function loadWordpressXML(evtObj:ResultEvent):void {
var myURLPattern1:RegExp = /content:encoded/g;
var myXMLString:String = evtObj.result.toString().replace(myURLPattern1, “content”);
wordpressXML = XML(myXMLString);
}

From here you can then use the XML in whichever way suits your design… For example, here I am creating the navigation dynamically…

private function generateNavigation():void {
for each (var itemXML:XML in wordpressXML.channel.item) {
var navigationItemHBox:VBox = new VBox;
navigationItemHBox.styleName = “navigationBackground”;
navigationItemHBox.width = 280;
navigationItemHBox.height = 37;
var navigationLabel:Label = new Label;
navigationLabel.text = itemXML.title;
navigationLabel.width = 240;
navigationLabel.styleName = “navigationText”;
navigationLabel.truncateToFit = true;
navigationLabel.buttonMode = true;
navigationLabel.useHandCursor = true;
navigationLabel.mouseChildren = false;
navigationLabel.data = itemXML.guid;
navigationLabel.addEventListener(MouseEvent.CLICK,selectPost);
navigationItemHBox.addChild(navigationLabel);
navigation.addChild(navigationItemHBox);
}
}

The most difficult part was to position the main post elements in the right place before whizzing them into view. There is a little bit of dubious logic required to do that. Look at the attached source for that.

Also given the increased size of the feed - ie it loads 100 post in one go (not including images) it’s important to have some kind of preloader in place while things load up.

Download an earlyish version of the source here to see how I did…

…and see the finished version here

Written By Tim for the Web Technology section Tags: ,

Flex 3: LocalConnection fails for no reason

26-08-2009

I have had more problems than worth mentioning with the LocalConnection API, but felt compelled to write about it after finally getting everything up and running.

The setup I have involves an AIR app communicating with a Flex 3 application running on an SSL enabled web page and back again. There seems to be rarely any problems going from browser to AIR, since the AIR app is easily addressable using the applicationID and publisherID strings or by passing strings though outside of the localconnection method in arguments along with the browserInvoke event.

When communicating from the AIR app back to the browser it seems to be rather fragile and fails regularly. Addressing the browser I use the last part of the domain and random ID of the browser flex instance (see previous post) eg “imbimp.com:dhdvgks35357″.

Now unbeknown to me, the domain string should not be the top level domain shown in the browsers address bar but should in fact match the TLD of where the Flex SWF file is hosted if of course it is different from your original site.

There are a few confusing bits and pieces to include around allowDomain and allowInsecureDomain, all of which are fairly well documented on Adobe’s livedocs pages, but seemed to have little effect when faced with inadvertantly addressing the wrong place.

No error event is thown in this case, just a statusEvent classing the connection attempt as an error of no particular type. Annoying.

Written By Tim for the Web Technology section Tags: , , ,

Flex 3: Detecting Network Status

25-08-2009

network

There are a number of methods to detect network connectivity, all of which can be read about here, here, here and here. What I found is that these seem to work fine when there is an actual change in your network connection. eg disconnecting your wireless connection, unplugging a network cable or USB modem. But if there is just a drop in network connectivity, such as a break the router side, invisible to the user’s PC then these methods work less well.

When using a URL monitor in flex, it polls for a URL on first start, and then after that you can configure the poll interval depending on your needs. Unfortunately, this is far from ideal given that people are online more often than offline, and its just not great to poll some URL every few seconds when it really isn’t necessary.

My recent download manager application uses a URL monitor but it also has a timer running in the background for each download. Every 10 seconds it checks to see if the bytes downloaded has changed. The theory being that if even the slowest net connection has downloaded 0 bytes in 10 seconds, its safe to say there is probably a network problem. It then begins polling every 10 seconds until there is a response and then assumes the user is online again and the download can continue. This is done as follows….

Firstly I initiate a timer and update value using a progressEvent tied to my URLStream.

private function onDownloadProgress(event:ProgressEvent):void {
value = Math.round(event.bytesLoaded);
}

Then I compare the bytes downloaded to a running count as follows…

private function possibleNetworkProblem(e:TimerEvent):void {
if (lastLotOfBytes == value) {
lastLotOfBytes = 0;
sendNetworkError();
} else {
lastLotOfBytes = value
}
}

If the values have not changed then I disconnect and reconnect the URL monitor every 10 seconds until network returns….

private function sendNetworkError():void {
if (monitor.available) {
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER,possibleNetworkProblem);
initiateDownloads();
}
monitor.removeEventListener(StatusEvent.STATUS, announceStatus);
monitor.stop();
monitor.start();
monitor.addEventListener(StatusEvent.STATUS, announceStatus);
}

Written By Tim for the Web Technology section Tags: , , ,

Downloading Large Files using Flex/AIR

25-08-2009

During my download manager development I tried a number of different methods to download files. This article was invaluable, as it explains how to download in 50k chunks rather than buffering much larger amounts.

To start with a tried buffering about 5mb. Seemed sensible, since I figured it would cut the amount of writing to disk that would required. Especially since most mp3 files are about that size. Unfortunately it did not work, since for some reason downloaded files were becoming corrupted. 50k is a pretty good level of buffering to improve performance and avoid an infinite level of disk reads.

For a while I figured that changing the method for downloading was impacting performance due to the application hanging and scrolling being disabled. This was due to an unnecessary amount of debugging though. Or rather - writing out to a text field for the purpose of debugging without relying on trace statements.

Written By Tim for the Web Technology section Tags: , ,