Использует ли библиотека WindowsAzure .Storage для Xamarin NSUrlSession для загрузки файлов? - PullRequest
0 голосов
/ 03 марта 2020

Постановка проблемы: У нас есть требование загрузить данные журнала в Azure Хранилище из приложения Xamarin. IOS. Журналы не создаются пользователем приложения, и у пользователя нет никаких ограничений на то, чтобы приложение оставалось открытым в течение любого периода времени после создания журналов. Мы хотим надежно загрузить наши журналы, имея в виду несколько моментов:

  • Пользователь может отправить приложение в фоновый режим
  • Размер файла может быть до 15 МБ
  • Нам все равно, когда мы их получим. Мы открыты для планирования задачи для этого.

Анализируя возможные решения этой проблемы, документация Xamarin утверждает, что в iOS7 +:

NSURLSession позволяет нам создавать задачи для:

  1. Передача контента через сеть и устройства.
  2. Загрузка и загрузка больших файлов (Служба фоновой передачи).

Таким образом, кажется, что NSURLSession - хороший кандидат для такого рода работы, но мне интересно, изобретаю ли я велосипед заново. Удовлетворяет ли клиентская библиотека WindowsAzure .Storage фонов приложений с помощью загрузки, основанной на NSURLSession, или, если я хочу загрузить данные в фоновом режиме, необходимо ли загружать их на промежуточный сервер, который я управляю, методом POST? , а затем передать данные в Azure Storage? В опубликованной c Azure документации, похоже, нет никаких указаний на то, что загрузка может быть выполнена с помощью запланированного задания.

1 Ответ

1 голос
/ 04 марта 2020

Я получил это работает. Я упростил классы и методы в один метод. Здесь есть только необходимое.

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 за указание в правильном направлении.

...