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

问题描述 投票:0回答:1

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

  • 用户可能会将应用程序发送到后台
  • 文件大小最大为15MB
  • [我们何时获得它们,我们都不在乎。我们愿意为此安排任务。

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

NSURLSession允许我们创建任务以:

  1. 通过网络和设备中断传输内容。
  2. 上传和下载大文件(后台传输服务)。

因此,看来NSURLSession是此类工作的不错选择,但我想知道我是否正在重新发明轮子。 WindowsAzure.Storage客户端库是否使用基于NSURLSession的上载实现来尊重应用程序背景,或者是否要在后台上载数据,是否有必要将其上载到我用POST方法控制的中间服务器,然后中继数据到Azure存储?公共Azure文档似乎没有任何迹象表明可以通过计划任务完成上传。

azure xamarin xamarin.ios azure-storage-blobs nsurlsession
1个回答
1
投票

我得到了这个工作。我已经将类和方法简化为单个方法。这里只有必需品。

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为我指出正确的方向。

© www.soinside.com 2019 - 2024. All rights reserved.