google drive partial download

824 views
Skip to first unread message

foxtrot...@gmail.com

unread,
Mar 2, 2016, 10:22:57 AM3/2/16
to Google APIs Client Library for Objective-C
Hi,
I'm using GTMSessionFetcher to download large files (> 1 GB) from Google Drive on iOS. Two questions:

- when I disconnect wi-fi then re-connect it (with no cellular connection), the download progress starts over; how to save and resume the partial download instead?

- what should I do to make sure that the download continues with cellular connection when wi-fi disconnects, or to make sure that it gets suspended (depending on the user's choice)?

Thanks for any pointer

Jérôme

Greg Robbins

unread,
Mar 2, 2016, 3:27:49 PM3/2/16
to google-api-obj...@googlegroups.com
The Drive API documents support for a byte range header that I would expect will work when downloading Drive files with the fetcher.



Your app could monitor Apple's Reachability API status, and when a fetcher error occurs, base a decision for immediate retry or not on the current type of network connection, if any. Since the fetcher is just a wrapper on NSURLSession, this is really a general issue of trying to get reliable network behavior on iOS.


foxtrot...@gmail.com

unread,
Mar 2, 2016, 3:58:11 PM3/2/16
to Google APIs Client Library for Objective-C
Thanks; this would mean I have to manually stop the download when the reachability API says that there is no network, then manually resume, then manually merge de partial data etc? Well, I would have assumed that all of this would be handled by GTL or the underlying NSURLSession..... :-(

Greg Robbins

unread,
Mar 2, 2016, 6:24:46 PM3/2/16
to google-api-obj...@googlegroups.com
When the network disappears, the transfer will fail, so NSURLSession and the fetcher should immediately pass an error to the callback in the app.

Since the client app knows how many bytes have already been downloaded, it can start a new fetch request with a byte range header.

foxtrot...@gmail.com

unread,
Mar 3, 2016, 10:33:11 AM3/3/16
to Google APIs Client Library for Objective-C
I tried using GTMSessionUploadFetcher instead of GTMSessionFetcher, just in case as I am only downloading, but in this case, finishedWithData is called, but with a nil resumeData, and with empty (or nil) data. :-(

foxtrot...@gmail.com

unread,
Mar 3, 2016, 10:33:11 AM3/3/16
to Google APIs Client Library for Objective-C
In fact, nothing happens when the connection is dropped (at least when I manually disable Wi-Fi on my iPad). My delegate's didFinishSelector is not called. Then when I re-enable Wi-Fi, my progress callback fires again but with bytesWritten back to 0. In fact it seems to me that this situation is handled directly by NSURLSession, not by Google API.

The strange thing is that even when I manually stop the download, by calling [fetcher stopFetchingafter having set fetcher.resumeDataBlock, resumeDataBlock is called with a nil resumeData. I think I am missing something here... It looks like the API supports resuming from a partial download, but Drive is not supporting it??

Maybe I should only download chunks of fixed size with the method you suggested (byte range header), then concatenate them manually? There is GTMSessionUploadFetcher that seems to do this automatically for upload, but nothing for downloads???

Thanks

Greg Robbins

unread,
Mar 3, 2016, 6:50:50 PM3/3/16
to google-api-obj...@googlegroups.com
Try enabling the GTM_LOG_SESSION_DELEGATE macro in GTMSessionFetcher.h (just change the #if 0 to #if 1) to see the delegate callbacks from NSURLSession. 

The behavior in response to changes in network state are really up to the OS. Once it gives up on a connection, it should fail the fetch with an error. I don't think an app should second-guess that OS behavior since it knows more about the network availability.

A nil value for the resume data means the connection cannot be resumed; it needs to be restarted. Most downloads cannot be resumed; it's basically for servers supporting ETag headers. See Apple's documentation for [NSURLSessionDownloadTask cancelByProducingResumeData:] for all of the resume criteria.

The upload fetcher implements unique chunked, resumable upload protocol supported by Google APIs.

There's no resumable download protocol that I'm aware of, aside from clients keeping track of the bytes received so far, and reissuing the request using a byte range header (which is likely what NSURLSession's resume is trying to do in a conservative fashion. ETags guarantee that the server data hasn't changed since the download began.)

foxtrot...@gmail.com

unread,
Mar 4, 2016, 11:42:12 AM3/4/16
to Google APIs Client Library for Objective-C
When I enable GTM_LOG_SESSION_DELEGATE, then [GTMSessionFetcherSessionDelegateDispatcher URLSession:didBecomeInvalidWithError:] is called, but my fetcher's didFinish block is not.

I would have expected from a Google framework for a Google storage service to handle background download intelligently by itself! The app developer should just initiate a download, and be notified when it has completed, without manually handing network state, chunks, partial files, Etags etc...

Kind regards
Reply all
Reply to author
Forward
0 new messages