Last active
December 29, 2015 03:49
-
-
Save Clancey/7610128 to your computer and use it in GitHub Desktop.
Background Downloader. Has the same API as WebClient but uses the underlying NSUrlRequest to download in the background.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BackgroundDownload | |
{ | |
public BackgroundDownload () | |
{ | |
} | |
NSUrlSessionDownloadTask downloadTask; | |
static NSUrlSession session; | |
public async Task DownloadFileAsync(Uri url, string destination) | |
{ | |
if (downloadTask != null) | |
return; | |
if(session == null) | |
session = InitBackgroundSession (); | |
Tcs = new TaskCompletionSource<bool> (); | |
Destination = destination; | |
using (var request = new NSUrlRequest(new NSUrl(url.AbsoluteUri))) { | |
downloadTask = session.CreateDownloadTask (request); | |
downloadTask.Resume (); | |
} | |
await Tcs.Task; | |
} | |
public event Action<float> ProgressChanged; | |
float progress; | |
public float Progress { | |
get { | |
return progress; | |
} | |
private set { | |
if (Math.Abs (progress - value) < float.Epsilon) | |
return; | |
progress = value; | |
if (ProgressChanged != null) | |
ProgressChanged (progress); | |
} | |
} | |
NSUrlSession InitBackgroundSession () | |
{ | |
Console.WriteLine ("InitBackgroundSession"); | |
using (var configuration = NSUrlSessionConfiguration.BackgroundSessionConfiguration ("async.background.downloader")) { | |
return NSUrlSession.FromConfiguration (configuration, new UrlSessionDelegate (this), null); | |
} | |
} | |
protected string Destination; | |
protected TaskCompletionSource<bool> Tcs; | |
public class UrlSessionDelegate : NSUrlSessionDownloadDelegate | |
{ | |
public BackgroundDownload controller; | |
public UrlSessionDelegate (BackgroundDownload controller) | |
{ | |
this.controller = controller; | |
} | |
public override void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) | |
{ | |
Console.WriteLine ("Set Progress"); | |
if (downloadTask == controller.downloadTask) { | |
float progress = totalBytesWritten / (float)totalBytesExpectedToWrite; | |
Console.WriteLine (string.Format ("DownloadTask: {0} progress: {1}", downloadTask, progress)); | |
InvokeOnMainThread(() => controller.Progress = progress); | |
} | |
} | |
public override void DidFinishDownloading (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location) | |
{ | |
Console.WriteLine ("Finished"); | |
Console.WriteLine ("File downloaded in : {0}", location); | |
NSFileManager fileManager = NSFileManager.DefaultManager; | |
var URLs = fileManager.GetUrls (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User); | |
NSUrl documentsDictionry = URLs [0]; | |
NSUrl originalURL = downloadTask.OriginalRequest.Url; | |
NSUrl destinationURL = NSUrl.FromFilename(controller.Destination); | |
NSError removeCopy; | |
NSError errorCopy; | |
fileManager.Remove (destinationURL, out removeCopy); | |
bool success = fileManager.Copy (location, destinationURL, out errorCopy); | |
if (success) { | |
controller.Tcs.TrySetResult (true); | |
} else { | |
controller.Tcs.TrySetException(new Exception(string.Format("Error during the copy: {0}", errorCopy.LocalizedDescription))); | |
} | |
} | |
public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error) | |
{ | |
float progress = task.BytesReceived / (float)task.BytesExpectedToReceive; | |
InvokeOnMainThread (() => controller.Progress = progress); | |
controller.downloadTask = null; | |
Console.WriteLine ("DidComplete"); | |
if (error == null) | |
controller.Tcs.TrySetResult (true); | |
else { | |
controller.Tcs.TrySetException(new Exception(string.Format("Error during the copy: {0}", error.LocalizedDescription))); | |
} | |
} | |
public override void DidResume (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long resumeFileOffset, long expectedTotalBytes) | |
{ | |
Console.WriteLine ("DidResume"); | |
} | |
public override void DidFinishEventsForBackgroundSession (NSUrlSession session) | |
{ | |
AppDelegate appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate; | |
var handler = appDelegate.BackgroundSessionCompletionHandler; | |
if (handler != null) { | |
appDelegate.BackgroundSessionCompletionHandler = null; | |
handler (); | |
} | |
BackgroundDownload.session = null; | |
Console.WriteLine ("All tasks are finished"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment