GoogleDrive + Alamofire:使用属性上传文件

3
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在尝试通过Swift 2 / Alamofire将文件+参数上传到Google Drive。 在下面的代码中,如果我更改以下行:

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

对于以下内容:

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

文件上传至谷歌时没有名称。否则,文件上传将失败,出现相同的通用错误代码:
Error Domain=com.alamofire.error Code=-6003 "Response status code was unacceptable: 400" UserInfo={NSLocalizedFailureReason=Response status code was unacceptable: 400}

我希望能够上传文件并指定名称和其他可能的参数。我知道我在某种程度上破坏了多部分上传,但我不知道我做错了什么。

  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

我想知道 Alamofire 创建多部分请求的方式是否有问题,可能与 Google Drive 不兼容。根据 Google API 网站上的信息,请求需要具备一些参数,Alamofire 可能没有创建,例如内容长度和边界设置...
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--

如果是这样,有什么解决方法?
1个回答

3

请仔细查阅Google Drive的API文档。

参数中关键字段似乎是"name"(而非"title")。

如果您想要额外的、自定义的文件属性,限于单个应用程序,请在json中添加"appProperties":

"appProperties": { "title": "任意内容" }


非常感谢您查看我的问题。您关于“名称”参数的疏忽是正确的...然而,这并没有解决问题。我更新了我的问题,包括了来自GoogleDrive API文档的有关多部分请求的简介...Alamofire是否可能没有发送所有必要的信息来进行请求?如果是这样,应该如何修复? - Plutovman
哦,好的,请尝试在multipartFormData闭包内注释掉for循环,并添加以下内容,看看会发生什么:multipartFormData.appendBodyPart(data:"{'name':'FILE_NAME'}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"name", mimeType: "application/json") - mrkbxt
顺便提一下,边界是由alamofire设置的,当你“添加一个body部分”时。AF方法应该自动提取POST的Content-Length,并且mimeType参数设置请求的那个部分的Content-Type。https://github.com/Alamofire/Alamofire/blob/master/Source/MultipartFormData.swift - mrkbxt
1
太棒了!你又一次做到了。我喜欢这个答案的简洁性。multipartFormData.appendBodyPart(data:"{'name':'FILE_NAME'}".dataUsingEncoding(N‌​SUTF8StringEncoding, allowLossyConversion: false)!, name :"name", mimeType: "application/json")解决了我的问题。非常感谢! - Plutovman
很酷。所以只是为了增加一些细节...无论在multipartFormData.appendBodyPart(data:"DATA_TO_ENCODE"参数的主引号内添加什么都会被编码。请注意,这些主引号定义了一个Swift中的字符串,并不包括在编码中,就像您的parameters字典变量一样。JSON需要{}、:和""字符。我在回答时使用单引号是为了方便,但是JSON标准是双引号,因此在我使用'单引号字符处,技术上应该使用"(转义双引号)。然后,通过mimeType将Content-Type设置为application/json。 - mrkbxt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接