I wanted to be able to download a sound file from the internet and
then play it. Here is how I attempted to create a 'download and play'
javascript function in phoengap. I say attempted, because although it
works in simulator, I can not get it to work on my actual phone. If
the sounds are compiled into the bundle I can get them to play on the
phone, but when they are downloaded to the App Bundle's documents
directory, they won't play on the iphone but they will play in
simulator.
I'm about ready to move on and try something else, but hopefully
someone else can learn something from this, or perhaps someone with
actual cocoa skills can implement it into the master.
I have some web development skills, but absolutely no experience using
cocoa. I made various attempts at getting NSDownload NSURLConnection
NSURLResponse to work for me, but I could not figure it out.
Eventually I discovered the URLCache example on apple's website. I
grabbed some files from their project: URLCacheAlert.h URLCacheAlert.m
URLCacheConnection.h URLCacheConnection.m
and added them to my project.
Now I needed to call these new methods...
edit GlassAppDelegate.m, about half way down in the webview
shoudStartLoadWithRequest method
add these lines:
} else if([(NSString *)[parts objectAtIndex:1]
isEqualToString:@"download"]) {
NSLog(@"Download request!");
NSString *dlurl = [@"http:" stringByAppendingString:[parts
objectAtIndex:3]];
NSLog(dlurl);
(void) [[URLCacheConnection alloc] initWithURL:[NSURL
URLWithString:dlurl] delegate:self];
You will also need to import the UrlCacheConnection files into the
GlassAppDelegate.h file:
#import "URLCacheConnection.h"
Next edit gap.js (I had to use an old version, the latest from github
has errors for me...)
Just below the recently added playSound function, I added a new
function called download
playSound: function(clip) {
if (Device.isAndroid)
{
window.DroidGap.playSound(clip);
}
else
{
return Device.exec('sound:' + clip);
}
},
download: function(clip) {
if (Device.isAndroid)
{
//not supported
}
else
{
//alert("downloading "+ clip);
return Device.exec('download:' + clip);
}
}
That takes care of the download part. Now to play it when it is
finished.
Edit URLCacheConnection.m and modify the connectionDidFinishLoading
method to make it look like this:
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
[self.delegate connectionDidFinish:self];
[[NSFileManager defaultManager] createFileAtPath:filePath
contents:self.receivedData
attributes:nil];
NSLog(filePath);
sound = [[Sound alloc] initWithContentsOfFile:filePath];
[sound play];
[connection release];
}
You'll also need to edit the .h files to include:
#import "Sound.h"
and add the new variables to the interface:
@interface URLCacheConnection : NSObject {
id <URLCacheConnectionDelegate> delegate;
NSMutableData *receivedData;
NSDate *lastModified;
Sound *sound;
NSString *dataPath;
NSString *filePath;
NSError *error;
}
At the end of all of this I'm left with some questions...
Can we use curl? Seems like this would be so much easier if curl was
enabled. I've read rumors that in the new firmwares you can compile
curl libraries into the bundle. If so, I think that would make a great
addition to phonegap and would probably port easily to all of the
platforms.
Another user on this group reported sounds not working on an actual
device, but they do work in simulator, i poked around the sound.m file
and it's pretty simple..
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
What could be wrong? I'm passing the correct path to the newly
downloaded sound file.
I am not using the Cache part of URLCacheConnection. Right now it
downloads the file each time, it does not check to see if it already
has the latest copy in cache.
You can only download one thing at a time. If you call multiple
download commands, only one will run. I think it's because javascript
is not blocking until the download finishes. How could I send status
messages back to javascript to let it know the download percentage
complete and notification when the file is finished downloading?
I would post a zip if it was going to be useful to anyone, but with
the info in this post you should be able to easily recreate the half-
working mess I have here.
Thanks to whoever is leading this effort. I was an early adopter of
Jiggy for the early jailbreak and was upset to see it die after the
jump to 2.0. With a little more polish, this looks like it can be just
as good as jiggy for us web developers to easily create iPhone apps.
It's very promising to see web apps make it to the app store. Keep up
the great work!
-WebShotsPro