Xamarin 的 WindowsAzure.Storage 库是否使用 NSUrlSession 进行文件上传?
Does the WindowsAzure.Storage library for Xamarin use NSUrlSession for file uploads?
问题陈述: 我们需要从 Xamarin.IOS 应用程序将日志数据上传到 Azure 存储。日志不是由应用程序的用户创建的,并且在日志生成后用户保持应用程序打开的时间不受限制。我们希望可靠地上传我们的日志,并牢记以下几点:
- 用户可能会将应用程序发送到后台
- 文件最大可达 15MB
- 我们不在乎什么时候得到它们。我们愿意为此安排任务。
在寻找此问题的潜在解决方案时,Xamarin 文档指出 iOS7+:
NSURLSession allows us to create tasks to:
- Transfer content through network and device interruptions.
- 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();
}
}
}
}
有用的文档:
- https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
- https://developer.apple.com/documentation/foundation/nsmutableurlrequest/1408793-setvalue
- https://docs.microsoft.com/en-us/dotnet/api/foundation.insurlsessiontaskdelegate?view=xamarin-ios-sdk-12
希望有人觉得这很有用并且花在这上面的时间比我少。感谢@SushiHangover 为我指明了正确的方向。
问题陈述: 我们需要从 Xamarin.IOS 应用程序将日志数据上传到 Azure 存储。日志不是由应用程序的用户创建的,并且在日志生成后用户保持应用程序打开的时间不受限制。我们希望可靠地上传我们的日志,并牢记以下几点:
- 用户可能会将应用程序发送到后台
- 文件最大可达 15MB
- 我们不在乎什么时候得到它们。我们愿意为此安排任务。
在寻找此问题的潜在解决方案时,Xamarin 文档指出 iOS7+:
NSURLSession allows us to create tasks to:
- Transfer content through network and device interruptions.
- 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();
}
}
}
}
有用的文档:
- https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
- https://developer.apple.com/documentation/foundation/nsmutableurlrequest/1408793-setvalue
- https://docs.microsoft.com/en-us/dotnet/api/foundation.insurlsessiontaskdelegate?view=xamarin-ios-sdk-12
希望有人觉得这很有用并且花在这上面的时间比我少。感谢@SushiHangover 为我指明了正确的方向。