问题陈述:我们需要从Xamarin.IOS应用程序将日志数据上传到Azure存储。日志不是由应用程序的用户创建的,并且在用户生成日志后的任何时间内保持打开应用程序的权限都没有任何限制。我们需要牢记以下几点来可靠地上传日志:
[寻找此问题的潜在解决方案时,Xamarin文档指出在iOS7 +中:
NSURLSession允许我们创建任务以:
- 通过网络和设备中断传输内容。
- 上传和下载大文件(后台传输服务)。
因此,看来NSURLSession是此类工作的不错选择,但我想知道我是否正在重新发明轮子。 WindowsAzure.Storage客户端库是否使用基于NSURLSession的上载实现来尊重应用程序背景,或者是否要在后台上载数据,是否有必要将其上载到我用POST方法控制的中间服务器,然后中继数据到Azure存储?公共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为我指出正确的方向。