使用NSURLSession从iOS(Swift)将文件上载到Django表单

使用NSURLSession从iOS(Swift)将文件上载到Django表单,ios,django,forms,swift,nsurlsession,Ios,Django,Forms,Swift,Nsurlsession,我正在尝试将iOS应用程序的tmp目录中保存的文本文件(.csv)上传到web服务器的url中,该url使用Django表单(通过浏览器从计算机上传文件,可以正常工作)。我无法使Swift代码正常工作,无法使request.FILES不为空。我尝试与NSRLSession代码一起使用,但无法使request.FILES正常工作 我的主要问题是:我应该怎么做才能为请求提供Django表单将使用的正确存储的密钥和信息(在本例中,请确保密钥“docfile”),并将其与我要发送的文本文件相关联? 以下

我正在尝试将iOS应用程序的tmp目录中保存的文本文件(.csv)上传到web服务器的url中,该url使用Django表单(通过浏览器从计算机上传文件,可以正常工作)。我无法使Swift代码正常工作,无法使request.FILES不为空。我尝试与NSRLSession代码一起使用,但无法使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表单的视图:

视图.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>

选择一个文件: