2016-02-24 17 views
11

Ich lerne schnell und ich sende eine Anfrage an den Server mit dem Code unten. Es funktioniert für einfache Anfrage und ich bekomme Antwort vom Server. Mein Problem ist, dass ich keine Datei an den Server senden kann.swift, Datei an Server senden

Code:

let parameters = parameter 

    let request = NSMutableURLRequest(URL: NSURL(string: requestUrl)!) 
    let boundaryConstant = "-----Boundary+\(arc4random())\(arc4random())" 


    let contentType = "multipart/form-data; boundary=" + boundaryConstant 
    let boundaryStart = "--\(boundaryConstant)\r\n" 
    let boundaryEnd = "--\(boundaryConstant)--\r\n" 

    let body:NSMutableString = NSMutableString(); 

    for (key, value) in parameters { 
     body.appendFormat(boundaryStart) 
     body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") 
     body.appendFormat("\(value)\r\n") 
    } 
    body.appendFormat(boundaryEnd) 


    request.HTTPMethod = "POST" 
    request.setValue(contentType, forHTTPHeaderField: "Content-Type") 

    request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding) 

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in 

     guard error == nil && data != nil else { 
      // check for fundamental networking error 
      print("error=\(error)") 
      return 

     } 


     if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {   // check for http errors 

      print("statusCode should be 200, but is \(httpStatus.statusCode)") 
      print("response = \(response)") 
     } 


     self.responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)! 
     print("MMMMMMMM \(self.responseString)") 
     self.result = self.responseString.dataUsingEncoding(NSUTF8StringEncoding)! as NSData 
     callback(self.responseString) 

    } 

    print("code start") 
    task.resume() 

Ergebnis: i kann durch diesen Code-Datei-Server bereitstellen:

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    let request = createRequest() 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in 
     if error != nil { 
      // handle error here 
      print(error) 
      return 
     } 
     do { 
      if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary { 
       print("success == \(responseDictionary)") 

      } 
     } catch { 
      print(error) 

      let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
      print("responseString = \(responseString)") 
     } 
    } 
    task.resume() 


} 

func createRequest() -> NSURLRequest { 
    let param = [] 


    let boundary = generateBoundaryString() 

    let url = NSURL(string: "URl")! 
    let request = NSMutableURLRequest(URL: url) 
    request.HTTPMethod = "POST" 
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") 
    request.setValue("userValue", forHTTPHeaderField: "X-Client-user") 
    request.setValue("passValue", forHTTPHeaderField: "X-Access-pass") 


    //let path1 = NSBundle.mainBundle().pathForResource("voice", ofType: "png") as String! 
    request.HTTPBody = createBodyWithParameters(param, filePathKey: "voice", paths: ["pathURl"], boundary: boundary) 

    return request 
} 

func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, paths: [String]?, boundary: String) -> NSData { 
    let body = NSMutableData() 

    if parameters != nil { 
     for (key, value) in parameters! { 
      body.appendString("--\(boundary)\r\n") 
      body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") 
      body.appendString("\(value)\r\n") 
     } 
    } 

    if paths != nil { 
     for path in paths! { 
      let url = NSURL(fileURLWithPath: path) 
      let filename = url.lastPathComponent 
      let data = NSData(contentsOfURL: url)! 
      let mimetype = mimeTypeForPath(path) 

      body.appendString("--\(boundary)\r\n") 
      body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename!)\"\r\n") 
      body.appendString("Content-Type: \(mimetype)\r\n\r\n") 
      body.appendData(data) 
      body.appendString("\r\n") 
     } 
    } 

    body.appendString("--\(boundary)--\r\n") 
    return body 
} 

func generateBoundaryString() -> String { 
    return "Boundary-\(NSUUID().UUIDString)" 
} 


func mimeTypeForPath(path: String) -> String { 
    let url = NSURL(fileURLWithPath: path) 
    let pathExtension = url.pathExtension 

    if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() { 
     if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() { 
      return mimetype as String 
     } 
    } 
    return "application/octet-stream"; 
} 
+0

Was genau ist der Fehler? – JAL

+1

Ich habe keinen Fehler in diesem Code und dieser Code funktioniert für mich, wenn ich eine Anfrage an den Server senden, und ich bekomme echte Antwort vom Server jetzt weiß ich nicht, wie man eine Audio-Datei an den Server senden –

+0

Sie müssen genauer sein über dein Problem. Haben Sie schon einmal versucht? Wenn Sie es getan haben und es nicht funktioniert hat, sollten Sie uns mitteilen, was Sie versucht haben, damit das Problem erkannt werden kann. Wenn Sie jedoch selbst keinen Versuch unternommen haben, sollten Sie zunächst Google "NSURLRequest Datei anhängen" –

Antwort

4

Wie Sie hier lesen, Sie NSURLSession für HTTP-Arbeit, es weitaus flexibler nutzen sollten und mächtig; und ich denke, ist dazu bestimmt, NSURLConnection zu ersetzen ...

https://www.objc.io/issues/5-ios7/from-nsurlconnection-to-nsurlsession/

Hier ist ein Beispiel für Sie ...

func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) { 
// **** get_metadata **** 
    let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!) 
    let session = NSURLSession.sharedSession() 
    request.HTTPMethod = "POST" 

    request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization") 
    request.addValue("application/json",forHTTPHeaderField: "Content-Type") 
    request.addValue("path", forHTTPHeaderField: lePath) 
    let cursor:NSDictionary? = ["path":lePath] 
    do { 
     let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: []) 
     request.HTTPBody = jsonData 
     print("json ",jsonData) 
    } catch { 
     print("snafoo alert") 
    } 

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in 
     if let error = error { 
      completion(string: nil, error: error) 
      return 
     } 
     let strData = NSString(data: data!, encoding: NSUTF8StringEncoding) 
     print("Body: \(strData)\n\n") 
     do { 
      let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers); 
      self.jsonParser(jsonResult,field2file: "ignore") 
      for (key, value) in self.parsedJson { 
       print("key2 \(key) value2 \(value)") 
      } 

      completion(string: "", error: nil) 
     } catch { 
      completion(string: nil, error: error) 
     } 
    }) 
    task.resume() 

} 
2

Große Antwort oben .. Hier ist es für swift3 aktualisiert wird:

func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) { 
// **** get_metadata **** 
    let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!) 
    let session = NSURLSession.sharedSession() 
    request.HTTPMethod = "POST" 

    request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization") 
    request.addValue("application/json",forHTTPHeaderField: "Content-Type") 
    request.addValue("path", forHTTPHeaderField: lePath) 
    let cursor:NSDictionary? = ["path":lePath] 
    do { 
     let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: []) 
     request.HTTPBody = jsonData 
     print("json ",jsonData) 
    } catch { 
     print("snafoo alert") 
    } 

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in 
     if let error = error { 
      completion(string: nil, error: error) 
      return 
     } 
     let strData = NSString(data: data!, encoding: NSUTF8StringEncoding) 
     print("Body: \(strData)\n\n") 
     do { 
      let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers); 
      self.jsonParser(jsonResult,field2file: "ignore") 
      for (key, value) in self.parsedJson { 
       print("key2 \(key) value2 \(value)") 
      } 

      completion(string: "", error: nil) 
     } catch { 
      completion(string: nil, error: error) 
     } 
    }) 
    task.resume() 

}