GoogleDrive + Alamofire: Uploading a file with properties

此生再无相见时 提交于 2020-01-02 09:29:10

问题


I am trying to upload a file + parameters to Google Drive via Swift 2/Alamofire. In the code below, i I change the line that says:

"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"

to the following:

"https://www.googleapis.com/upload/drive/v3/files"

the file uploads to google without a name. Otherwise, the file upload fails with the same generic code:

Error Domain=com.alamofire.error Code=-6003 "Response status code was unacceptable: 400" UserInfo={NSLocalizedFailureReason=Response status code was unacceptable: 400}

I'd like to be able to upload the file with name and potentially other parameters as well. I know I'm mangling the multipart upload somehow, but I don't know what I'm doing wrong.

  func postBinaryToGdriveSimple (token: String, callback: Bool -> Void){
var returnedId : String!
let path = NSBundle.mainBundle().pathForResource("drawing", ofType: "bin")

let bindata: NSData = NSData(contentsOfURL: NSURL(fileURLWithPath: path!))!
let parameters : [String: String] = ["title":"SomeFileName"]
let headers = ["Authorization": "Bearer \(token)"]
upload(
  .POST,
  "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
  headers: headers,

  multipartFormData: { multipartFormData in
    // append file parameters to request
    for (key, value) in parameters {
      multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
    }
    // append binary file to request
    multipartFormData.appendBodyPart(data: bindata, name: "upload", fileName: "drawing.bin", mimeType: "application/octet-stream")

  },
  encodingCompletion: { encodingResult in
    switch encodingResult {
    case .Success(let upload, _, _):
      upload.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
        dispatch_async(dispatch_get_main_queue()) {
          let percent = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))
          //progress(percent: percent)
          print ("................\(percent)")
        }
      }
      upload.validate()
      upload.responseJSON { response in
        switch response.result {
        case .Success(let data):
          print(response)
          print("Validation Successful")

          let json = JSON(data)
          returnedId = json[("id")].stringValue
          print("......id for uploaded file is \(returnedId)")

          callback(true)
        case .Failure(let error):
          print(error)
          print("Validation Bad")
          callback(false)
        }


      }
    case .Failure(_):
      callback(false)
    }
})
} // end of postBinaryToGdriveSimple

I wonder if there is something about the way Alamofire creates the multipart request that Google Drive is not liking. From the google api site, it seems like a request needs to have certain parameters that Alamofire may not be creating, such as Content-length and boundary settings...

POST /upload/drive/v3/files?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
 "name": "My File"
}

--foo_bar_baz
Content-Type: image/jpeg

JPEG data
--foo_bar_baz--

If so, what is the work-around?


回答1:


Double check the API documentation for Google Drive.

It appears that the key field for the parameter is "name" (not "title").

If you want additional, custom file properties, restricted to the single app, add an "appProperties" to the json:

"appProperties": { "title": "whatever" }



来源:https://stackoverflow.com/questions/38450245/googledrive-alamofire-uploading-a-file-with-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!