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

时间:2015-11-03 05:43:20

标签: ios django forms swift nsurlsession

我正在尝试将保存在我的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>

0 个答案:

没有答案