2016-02-24 20 views
11

Sto imparando rapidamente e invio una richiesta al server con il seguente codice. Funziona per richiesta semplice e ottengo risposta dal server. Il mio problema è che non posso inviare un file al server.swift, invia file al server

codice:

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() 

risultato: posso inviare il file al server da questo codice:

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

Che cos'è esattamente l'errore? – JAL

+1

non ho alcun errore in questo codice e questo codice funziona per me quando invio una richiesta al server e ottengo una vera risposta dal server ora non so come inviare un FILE audio al server –

+0

Devi essere più specifico sul tuo problema Hai già provato qualche approccio? Se l'hai fatto e non ha funzionato, dovresti dirci cosa hai provato in modo che sia possibile identificare il problema. Se, tuttavia, non hai fatto nessun tentativo, dovresti prima Google "NSURLRequest attach file" –

risposta

4

Come potete leggere qui, è necessario utilizzare NSURLSession per il lavoro HTTP, è molto più flessibile e potente; e penso che è destinato a sostituire NSURLConnection ...

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

Ecco un esempio per voi ...

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

Grande risposta di cui sopra .. Qui è aggiornato per Swift3:

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() 

}