Xamarin 的 WindowsAzure.Storage 库是否使用 NSUrlSession 进行文件上传?

Does the WindowsAzure.Storage library for Xamarin use NSUrlSession for file uploads?

问题陈述: 我们需要从 Xamarin.IOS 应用程序将日志数据上传到 Azure 存储。日志不是由应用程序的用户创建的,并且在日志生成后用户保持应用程序打开的时间不受限制。我们希望可靠地上传我们的日志,并牢记以下几点:

在寻找此问题的潜在解决方案时,Xamarin 文档指出 iOS7+:

NSURLSession allows us to create tasks to:

  1. Transfer content through network and device interruptions.
  2. Upload and download large files ( Background Transfer Service ).

所以看起来 NSURLSession 是这类工作的一个很好的候选者,但我想知道我是否在重新发明轮子。 WindowsAzure.Storage 客户端库是否通过基于 NSURLSession 的上传实现尊重应用程序后台,或者如果我想在后台上传数据,是否有必要上传到我用 POST 控制的中间服务器方法,然后将数据中继到 Azure 存储? public Azure 文档中似乎没有任何迹象表明可以通过计划任务完成上传。

我成功了。我已将 类 和方法简化为一个方法。只有必需品在这里。

public void UploadFile(File playbackFile)
{
    /// Specify your credentials
    var sasURL = "?<the sastoken>";

    /// Azure blob storage URL
    var storageAccount = "https://<yourstorageaccount>.blob.core.windows.net/<your container name>";

    /// specify a UNIQUE session name
    var configuration =
        NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration("A background session name");

    /// create the session with a delegate to recieve callbacks and debug
    var session = NSUrlSession.FromConfiguration(
        configuration,
        new YourSessionDelegate(),
        new NSOperationQueue());

    /// Construct the blob endpoint
    var url = $"{storageAccount}/{playbackFile.Name}{sasURL}";
    var uploadUrl = NSUrl.FromString(url);

    /// Add any headers for Blob PUT. x-ms-blob-type is REQUIRED
    var dic = new NSMutableDictionary();
    dic.Add(new NSString("x-ms-blob-type"), new NSString("BlockBlob"));

    /// Create the request with NSMutableUrlRequest
    /// A default NSUrlRequest.FromURL() is immutable with a GET method
    var request = new NSMutableUrlRequest(uploadUrl);
    request.Headers = dic;
    request.HttpMethod = "PUT";

    /// Create the task
    var uploadTask = session.CreateUploadTask(
        request,
        NSUrl.FromFilename(playbackFile.FullName));

    /// Start the task
    uploadTask.Resume();
}

/// Delegate to recieve callbacks. Implementations are omitted for brevity
public class YourSessionDelegate: NSUrlSessionDataDelegate
{ 
    public override void DidBecomeInvalid(NSUrlSession session, NSError error)
    {
        Console.WriteLine(error.Description);
    }

    public override void DidSendBodyData(NSUrlSession session, NSUrlSessionTask task, long bytesSent, long totalBytesSent, long totalBytesExpectedToSend)
    {
        Console.WriteLine(bytesSent);
    }

    public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
    {
        Console.WriteLine(data);
    }

    public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
    {
        var uploadTask = task as NSUrlSessionUploadTask;
        Console.WriteLine(error?.Description);
    }

    public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
    {
        Console.WriteLine(response);
    }

    public override void DidFinishEventsForBackgroundSession(NSUrlSession session)
    {
        using (AppDelegate appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate)
        {
            var handler = appDelegate.BackgroundSessionCompletionHandler;
            if (handler != null)
            {
                appDelegate.BackgroundSessionCompletionHandler = null;
                handler();
            }
        }
    }
}

有用的文档:

希望有人觉得这很有用并且花在这上面的时间比我少。感谢@SushiHangover 为我指明了正确的方向。