×
A new build of Corona SDK is now available to subscribers. Not a subscriber? Subscribe now.
CoronaSDK 2014.2482 | Released: 30 Oct 2014, 1:36am | What's New | Download Now

network.download( )

Description:

This API is similar to the asynchronous network.request() except that it downloads the response to a local file that you specify, rather than cacheing it in memory. This is recommended for large HTTP/HTTPS responses (for example, long XML documents), and can also be used for downloading remote images.

You can also use display.loadRemoteImage() to download and display a remote image in a single API call.

Syntax:

network.download( url, method, listener [, params], destFilename [, baseDir] )

Example:

The following example downloads a remote image to a local file, and then displays it on the screen:

local function networkListener( event )
        if ( event.isError ) then
                print ( "Network error - download failed" )
        else
                myImage = display.newImage( "helloCopy.png", system.TemporaryDirectory, 60, 40 )
                myImage.alpha = 0
                transition.to( myImage, { alpha = 1.0 } )
        end
        
        print ( "RESPONSE: " .. event.response )
end
 
network.download( "http://developer.anscamobile.com/demo/hello.png", "GET", networkListener, "helloCopy.png", system.TemporaryDirectory )

Parameters:

url
String: The HTTP request URL.

method
String: The HTTP method; valid values are "GET" (the default) or "POST".

listener
Function: The listener function invoked when the HTTP operation has completed. It is passed an event object that contains the following properties:

  • event.response
    A string containing the destination filename. This is useful if you're writing a general event handler for a variety of file downloads.
  • event.isError
    A boolean value: true in the case of a network error, false otherwise. As of build 2012.744, "event.isError" only returns true if we failed to connect to the server or upon response timeout
  • event.status
    A number value: The HTTP status code. (Only available starting with build 2012.744)

params
Table: An optional table that specifies custom HTTP headers or body to include in the request. To specify custom headers, attach a headers table that specifies header values with string keys. To specify a custom body message, attach a body property to this table whose string value is the HTTP body.

params.headers -- A table specifying header values with string keys.
params.body -- A string containing the HTTP body.

destFilename
String: The name of the file to which the HTTP response will be saved.

baseDir
The directory where the file will be saved to. Defaults to system.DocumentsDirectory if not provided. Cannot be set to system.ResourceDirectory since that directory is read-only.

Returns:

Nothing.

Remarks:

Sample Programs Using This API
/Networking/AsynchImageDownload

Supported on operating systems and platforms for build numbers shown:
  • Mac OS X:
    Build 2011.268
  • Windows:
    Build 2011.484
  • iOS:
    Build 2011.268
  • Android:
    Build 2011.336

Replies

bruno.simoes7
User offline. Last seen 2 years 15 weeks ago. Offline
Joined: 15 Mar 2011

None of these methods is working for me:

display.loadRemoteImage( )
network.request( )

If I use display.loadRemoteImage( ) then I get an exception: Unsupported key for network: loadRemoteImage. The second is complete silent apart from event.isError = true.

Any idea why ? http.request works fine for the same request. Can it be related with proxy settings ? I'm using a proxy, but the server i'm using is local.

Note: Env. Windows / Android

Solved: The problem resulted from the existence of a symbol "\n" in the URL.

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

Try running the network sample apps included with the Corona SDK. In particular:
- Networking\AsynchHTTP
- Networking\AysnchImageDownload

We don't officially support network communications via a proxy server yet, but that said, we have tested it with the Corona Simulator on Windows and it worked. However, that said, since you're communicating to a machine on the LAN instead of the Internet (via a Proxy) then this shouldn't be an issue. The network sample code that we have should help make it clear how to use Corona's network APIs.

Good luck!

a3mg
User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 26 Jul 2010

Is it possible to kill or stop the download when using network.download()?

We have a function that starts the download of a few videos and want to allow the users to cancel out of downloading at any time.

I do have code that gets me out of the video downloading routine but what happens though is it always finishes up the one it is on and then triggers the listener for that one. I need to be able to kill the download at any time and for it to stop downloading immediately.

Any suggestions?

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

Unfortunately, there is no way to abort a download in Corona. It would be nice to have for sure, but at the moment we don't

The only work-around that I can think of is to use Lua sockets and coroutines. Lua socket requests are blocking, but a Lua coroutine allows you to multitask to give the illusion of threading. I know that a Lua socket object gives you the ability to close it. So if you want, you can give this a go. I don't know if it'll work because I've never tried it for myself.

coderebelbase
User offline. Last seen 1 year 25 weeks ago. Offline
Joined: 1 Feb 2010

Are we able to download any filetype, and size with network.download, or are they some restrictions to size/type?

a3mg
User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 26 Jul 2010

We have it working well downloading multiple 40MB mp4s. Someone else in another thread mentioned downloading mp3s.

coderebelbase
User offline. Last seen 1 year 25 weeks ago. Offline
Joined: 1 Feb 2010

@a3mg Thx, good to know! I noticed it doesn't handle spaces in the uri, but replacing with %20 works.

url = string.gsub( url, "% ", "%%20" )

swijaya0101
User offline. Last seen 3 years 10 hours ago. Offline
Joined: 31 Jan 2011

I am using network.download to download 100MB files from external server.

Is there anyway in IOS to check the progress of this download?

This is what I did:
network.download( "http://download.services.openoffice.org/files/stable/3.3.0/OOo_3.3.0_MacOS_x86_install_en-US.dmg", "GET", networkListener, "helloCopy4.dmg", system.DocumentsDirectory )

However, the file is not available at DocumentsDirectory until it is fully downloaded.

Thanks

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

swijaya0101,

Unfortunately no. Corona does not provide any download progress info. Corona only provides an event when the download has finished or when errors occurred (timeout, connection issues, etc.).

maarten.koopmans
User offline. Last seen 7 weeks 1 day ago. Offline
Joined: 29 Mar 2010

This consequently tries to download with a / before the filename, outside the sandbox on iOS. So I get errors like:

Sep 14 13:07:07 unknown sandboxd[1169] : TestApp(1167) deny file-write-create /README.txt

when I call it like this (on r619, but basically anything):

network.download(source_file,"GET",networkListener,destination,system.DocumentsDirectory)

source_file and destination are correct; same thing works in blocking mode with LuaSocket HTTP but much slower. Networklistener as per the example.

Any clues? Bug?

Tom
User offline. Last seen 14 hours 36 min ago. Offline
Staff
Joined: 13 Jul 2010

You need to provide a real example of what you are doing. Does the Async Download example app work okay?

Also, please use "code ... /code" tags when entering code to make it easier to read.

maarten.koopmans
User offline. Last seen 7 weeks 1 day ago. Offline
Joined: 29 Mar 2010

1
2
3
4
5
6
7
8
local function networkListener( event )
        if ( event.isError ) then
                print ( "Network error - download failed for" .. event.response)
        end
        
end
 
network.download(http:/10.0.1.4./files/readme.txt,"GET",networkListener,readme.txt,system.DocumentsDirectory)

And this in a for iterator for a few hundred files, hence the variable names source/destination. Like I said: think simple web crawler, with async http. And yes, the samples work, but they don't do much concurrent requests.

maarten.koopmans
User offline. Last seen 7 weeks 1 day ago. Offline
Joined: 29 Mar 2010

Off note: using LuaSockets http.request with a ltn12 file sink works fine - but sequentially and has a slow feel to it. I am hoping to avoid writing my own http client for this.....

a3mg
User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 26 Jul 2010

Does this need some quotes to work?

1
network.download("http://10.0.1.4/files/readme.txt","GET",networkListener,"readme.txt",system.DocumentsDirectory)

--- EDIT ---
Sorry, just re-read that you are using variables for the source and destination, but it must be that with missing quotes it is not working correctly.

Tom
User offline. Last seen 14 hours 36 min ago. Offline
Staff
Joined: 13 Jul 2010

I don't know if this was pulled from working code, but your example code is missing quotes around the source and destination parameters. You also have an extra "." before the "/files..." portion of the source.

Also, shouldn't your url start with "http://"?

maarten.koopmans
User offline. Last seen 7 weeks 1 day ago. Offline
Joined: 29 Mar 2010

Typos; the working code uses source/dest variables in a loop. I can print them, and use them correctly with LuaSocket http

I think the issue is unpredictable behaviour hence errors whn doing lots of async requests. If so, I should be able to make a test case. Is there an upper limit on the #async requests? (concurrent, that is)

Tom
User offline. Last seen 14 hours 36 min ago. Offline
Staff
Joined: 13 Jul 2010

If you can read one file at a time, I would say there is no problem with Corona. The async API means it doesn't block the Lua code waiting for a server response.

This API along with network.request, calls the OS's network APIs which may not be able to handle lots of async requests. This is something we don't test for, nor do we make any claims about making multiple requests because it depends on the OS (Mac, Windows, iOS, Android).

a3mg
User offline. Last seen 4 weeks 6 days ago. Offline
Joined: 26 Jul 2010

Does it matter that for each request iteration it uses the same networkListener listener?

I do mine sequentially with the network download where the networkListener code triggers the next one to download. But each time I use a different listener name like networkListener1, networkListener2, and so on. Perhaps not needed, but it works for me.

Would be interested if it is possible to download multiples at the same time.

maarten.koopmans
User offline. Last seen 7 weeks 1 day ago. Offline
Joined: 29 Mar 2010

I'll stick with hecsequential code then, thanks.

@a3mg: check out LuaSocket's http.request

troynall
User offline. Last seen 1 year 10 weeks ago. Offline
Joined: 8 Nov 2010

is there a network.file method/function that will allow me to get the files size in bytes ?

ALSO

is there a network method that allows me to get the RATE of speed of the connection ?

if so, we could produce a expected delivery time and maybe produce
a count down to file download.

dale7
User offline. Last seen 48 weeks 6 days ago. Offline
Joined: 13 Jun 2011

I need to use network.download for my app and I really need to be able to cancel the download.

Is this on the horizon Ansca? Maybe in a daily build?

Skatan
User offline. Last seen 46 min 40 sec ago. Offline
Joined: 11 Jan 2011

This doesn't seem to be working over EDGE?

FX1122334455
User offline. Last seen 2 years 39 weeks ago. Offline
Joined: 24 Jan 2012

Can I use https??

Tom
User offline. Last seen 14 hours 36 min ago. Offline
Staff
Joined: 13 Jul 2010

Yes, it supports HTTP and HTTPS.

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

Mitaten, it should work via EDGE. You may want to double check that your URL is reachable via your device's web browser.

FX1122334455, yes you can use a URL with HTTPS in it.

aleeri
User offline. Last seen 1 year 39 weeks ago. Offline
Joined: 25 Nov 2010

Once a file is downloaded should I calculate a sha1 hash for it to ensure it was downloaded correctly or is this already included in the api?

Could it be that some bits fall over and the downloaded file is "corrupt" or would this be prevented by corona?

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

aleeri, you shouldn't have to. The TCP protocol does this for us by applying and verifying a checksum to every TCP packet. The only way a corrupted packet can make it through is if there was a problem with the network hardware/firmware that was incorrectly accepting corrupted packets when it shouldn't have. That can happen due to a bug in the firmware or if the network device was horribly misconfigured.

Perhaps doing your own hash check may be necessary if you are worried if the server might swap an old version of a file with a new version while your app is in the middle of downloading it.

simon.ong
User offline. Last seen 1 year 15 weeks ago. Offline
Joined: 30 Apr 2011

Inside the event listener, is there a way to determine what URL was requested in the event of a network error?

1
2
3
4
5
6
7
8
local function networkListener( event )
        if ( event.isError ) then
-- How to check which file was requested here?
        end
        
end
 
network.download("http://www.test.com/pic.jpg","GET",networkListener,"pic.jpg",system.CachesDirectory)

event.response just gives me "The Internet connection appears to be offline." when I switch of wi-fi and I'm not sure how I can know what was the requested URL??

I'd like to be able to load a file locally (if available from Caches directory) during "offline mode".

Thanks in advance.

simon.ong
User offline. Last seen 1 year 15 weeks ago. Offline
Joined: 30 Apr 2011

On a related note to cached copies...

If I switch off wifi and request something that was already cached, there does not seem to be a way to tell that I got the cached copy. network.download does not throw any "error" per se. I guess I just have to check the connection status and assume I got the cached copy if something was loaded and there was no error?

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

Hello Simon,

As of daily build 744, we added "event.url" to do exactly what you are looking for. Try it out!

It's not documented yet because we plan on making some additional changes to the API... but all in due time. If you need to use an earlier build, then what you can do is set up a different Lua listener for different network requests.

Joshua Quick
User offline. Last seen 9 hours 47 min ago. Offline
Staff
Joined: 31 Jan 2011

Simon,

Regarding the cached copy issue when you lose your Internet connection, you can detect if you have lost your connection to the server by using our "reachability" API. Please see the following documentation...

http://developer.anscamobile.com/reference/index/network/detect-network-status/networkcandetect
http://developer.anscamobile.com/reference/index/network/detect-network-status/networksetstatuslistener

Also see sample app "Networking\Reachability" that is included with the Corona SDK.

One more thing. Please be aware that the above mentioned API is only supported on iOS and Mac. It is not supported on Android and Windows. But that said, Android should not return a cached copy to your network request, so you might be okay in this case.

simon.ong
User offline. Last seen 1 year 15 weeks ago. Offline
Joined: 30 Apr 2011

Thank you Joshua, event.url is just what I need :)

Tom
User offline. Last seen 14 hours 36 min ago. Offline
Staff
Joined: 13 Jul 2010

The comment section for this API has been closed. Please continue the discussion on the Corona forums.
http://developer.anscamobile.com/forum/2012/04/03/networkdownload