2016-07-19 2 views
1

Я пытаюсь загрузить файл + параметры на Google Диск через Swift 2/Alamofire. В приведенном ниже коде, я могу изменить строку, которая говорит:GoogleDrive + Alamofire: Загрузка файла со свойствами

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

на следующее:

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

закачки файлов в Google без имени. В противном случае, загрузка файла не завершится с тем же родовым кодом:

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 Диску. С апи сайта Google, похоже, запрос должен иметь определенные параметры, которые Alamofire не могут создавать, например, как Content-Length и граничных настроек ...

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

Дважды проверьте документацию API для Google Диска.

Похоже, что поле ключа для параметра - это «имя» (а не «название»).

Если вы хотите дополнительные свойства пользовательских файлов, ограничивается одним приложением, добавьте "appProperties" в формате JSON:

"appProperties": { "название": "то, что" }

+0

Большое спасибо за то, что посмотрели мою проблему. Вы правы в моем контроле над параметром «имя» ... Однако это не решило проблему. Я обновил свой вопрос, чтобы включить рекламный ролик о многостраничных запросах из документов API GoogleDrive ... Возможно ли, что Alamofire не отправляет всю информацию, необходимую для запроса? Если да, то как исправить? – Plutovman

+0

oh ok, попробуйте прокомментировать цикл for in внутри multipartFormData и посмотрите, что произойдет, если вы добавите: multipartFormData.appendBodyPart (data: "{'name': 'FILE_NAME'}". DataUsingEncoding (NSUTF8StringEncoding, allowLossyConversion: false)! , name: "name", mimeType: "application/json") – mrkbxt

+0

Кстати, границы устанавливаются alamofire, когда вы добавляете часть тела. Метод AF должен самостоятельно извлекать Content-Length для POST, а параметр mimeType задает Content-Type для этой части запроса. https://github.com/Alamofire/Alamofire/blob/master/Source/MultipartFormData.swift – mrkbxt