我正在尝试将保存在我的iOS应用程序的tmp目录中的文本文件(.csv)上传到使用Django表单的网址上的Web服务器(并且可以通过浏览器从计算机上传文件来正常工作)。我无法让Swift代码工作并将request.FILES变为空。我尝试将the answer to this question与NSRLSession代码from this page一起使用,但我无法使request.FILES表现出来。
我的主要问题是:我该怎么做才能为请求提供正确的存储密钥和Django表单将使用的信息(在这种情况下,请确保密钥'docfile'),并将其与我想发送的文本文件?
以下是我到目前为止的代码(对于任何奇怪的格式化道歉):
ViewController.swift代码
class ViewController: UIViewController, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate {
let defaults = NSUserDefaults.standardUserDefaults()
var fileManager = NSFileManager()
var tmpDir = NSURL(fileURLWithPath: NSTemporaryDirectory())
var responseData = NSMutableData()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func sendFileToServer(){
//get file name
if let fileName = defaults.stringForKey("fileNameKey")
{
let getPath = tmpDir.URLByAppendingPathComponent(fileName)
let data: NSData = NSData(contentsOfFile: getPath.path!)!
//setup major parts of HTTP request here
let request = NSMutableURLRequest(URL: NSURL(string: "http://mywebserverurl.goeshere/upload/")!)
let HTTPMethod: String = "POST"
request.HTTPMethod = HTTPMethod
//set up more important HTTP request info here
let boundary = "----SomeSortOfRandomStringGoesHere"
let contentType = "multipart/form-data; boundary=\(boundary)"
request.setValue(contentType, forHTTPHeaderField:"Content-Type")
let body = NSMutableData()
let tempData = NSMutableData()
let parameterName = "docfile"
let mimeType = "file"
tempData.appendData("--\(boundary)\r\n--".dataUsingEncoding(NSUTF8StringEncoding)!)
let fileNameContentDisposition = "filename=\"\(fileName)\""
let contentDisposition = "Content-Disposition: form-data; name=\"\(parameterName)\"; \(fileNameContentDisposition)\r\n"
tempData.appendData(contentDisposition.dataUsingEncoding(NSUTF8StringEncoding)!)
tempData.appendData("Content-Type: \(mimeType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
tempData.appendData(data)
tempData.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(tempData)
body.appendData("\r\n--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
request.setValue("\(body.length)", forHTTPHeaderField: "Content-Length")
request.HTTPBody = body
uploadFiles(request, data: data)
}
}
func uploadFiles(request: NSURLRequest, data: NSData) {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
let task = session.uploadTaskWithRequest(request, fromData: data)
task.resume()
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error != nil {
print("session \(session) occurred error \(error?.localizedDescription)")
} else {
print("session \(session), response: \(NSString(data: responseData, encoding: NSUTF8StringEncoding))")
}
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
let uploadProgress: Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print("session \(session) uploaded \(uploadProgress * 100)%.")
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
print("session \(session), received response \(response)")
completionHandler(NSURLSessionResponseDisposition.Allow)
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
responseData.appendData(data)
}
以下是Django表单的视图:
views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views.decorators.csrf import csrf_exempt
from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
@csrf_exempt
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponse("Upload worked")
else:
form = DocumentForm() # A empty, unbound form
# Render list page with the documents and the form
return render_to_response(
'upload.html',
{'form': form},
context_instance=RequestContext(request)
)
当我要求Django打印时,我试图保存的表格看起来像这样:
<tr>
<th>
<label for=“id_docfile”>Select a file:</label>
</th>
<td>
<input id=“id_docfile” name=“docfile” type=“file” />
</td>
</tr>