【问题标题】:Does the WindowsAzure.Storage library for Xamarin use NSUrlSession for file uploads?Xamarin 的 WindowsAzure.Storage 库是否使用 NSUrlSession 进行文件上传?
【发布时间】:2020-03-02 23:40:28
【问题描述】:

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

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

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

NSURLSession 允许我们创建任务来:

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

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

【问题讨论】:

  • WindowsAzure.Storage客户端是纯dotnet(使用httpclient),不使用平台专用API,来源在线:github.com/Azure/azure-sdk-for-net/tree/master/sdk/storage
  • 通读一遍。谢谢!那么推荐的做法是使用 Azure 存储 REST API 为 blob 上传编写自定义实现吗?
  • 如果您想利用 NSURLSession 功能,那么可以,只需在自定义 iOS 实现中直接使用 REST 端点

标签: azure xamarin xamarin.ios azure-blob-storage nsurlsession


【解决方案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 为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 2014-02-14
    • 2018-04-12
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 2014-12-26
    • 2018-04-01
    • 1970-01-01
    相关资源
    最近更新 更多