2015-02-01 23 views
5

Uso Alamofire per eseguire una richiesta POST. Poiché questa richiesta POST può richiedere un po 'di tempo e voglio tenere traccia dell'avanzamento e visualizzarlo come ProgressView.Richiesta POST Alamofire con avanzamento

Alamofire.request(.POST, ApiLink.create_post, parameters: parameters, encoding: .JSON) 
     .progress { (bytesRead, totalBytesRead, totalBytesExpectedToRead) -> Void in 
      println("ENTER .PROGRESSS") 
      println("\(totalBytesRead) of \(totalBytesExpectedToRead)")     
      self.progressView.setProgress(Float(totalBytesRead)/Float(totalBytesExpectedToRead), animated: true) 
     } 
     .responseJSON { (_, _, mydata, _) in 
      println(mydata) 
     } 

Tuttavia, ho notato che il .progress bloccare solo ottenere chiamato dopo che la richiesta post è finito invece di ottenere chiamato più volte per tenere in realtà traccia dei progressi. println ("ENTER .PROGRESSS") viene chiamato solo una volta (alla fine)

Come posso fare .progress lavora con Alamofire.request POST?

Inoltre: I miei parametri includono una stringa di immagine codificata in base64. Sto usando un back-end Ruby on Rails per elaborare l'immagine. È quel processo che richiede parecchio tempo.

+0

Se è solo JSON che stai tornando, potrebbe benissimo essere che tutto il carico utile sta tornando tutto in una volta ... Che cosa viene stampato esattamente? – mattt

+0

Oh sì, in effetti sto ricevendo una semplice richiesta JSON dopo che è tornata. Il fatto è che i miei parametri includono un'immagine codificata in base64. Sto utilizzando un binario di back-end per elaborare l'immagine caricata e questo processo richiede del tempo. – fabdarice

+0

A meno che tu non stia facendo 'upload', lo stato di avanzamento riportato è il download. – mattt

risposta

6

È invece possibile utilizzare prima l'enum ParameterEncoding per generare i dati di HTTPBody. Quindi puoi estrarre quei dati e passarli al metodo Alamofire upload. Ecco una versione modificata della tua stessa funzione che compila in un parco giochi e utilizza invece la funzione upload.

struct ApiLink { 
    static let create_post = "/my/path/for/create/post" 
} 

let parameters: [String: AnyObject] = ["key": "value"] // Make sure this has your image as well 

let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: ApiLink.create_post)!) 
mutableURLRequest.HTTPMethod = Method.POST.rawValue 

let encodedURLRequest = ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0 
let data = encodedURLRequest.HTTPBody! 

let progressView = UIProgressView() 

Alamofire.upload(mutableURLRequest, data) 
     .progress { _, totalBytesRead, totalBytesExpectedToRead in 
      println("ENTER .PROGRESSS") 
      println("\(totalBytesRead) of \(totalBytesExpectedToRead)") 
      progressView.setProgress(Float(totalBytesRead)/Float(totalBytesExpectedToRead), animated: true) 
     } 
     .responseJSON { _, _, mydata, _ in 
      println(mydata) 
     } 

Questo avrà certamente aggiornamenti di avanzamento come @mattt menzionato originariamente nel suo commento sopra.

+0

Come posso recuperare i parametri nel back-end con .upload? Sto usando un binario come mio back-end e tutti i parametri che ho recuperato con .request ora sono nulli con .upload. – fabdarice

+0

Probabilmente è necessario comprimere i dati come oggetto MultipartFormData prima di caricarli. Fino a quando Alamofire supporta i caricamenti di MultipartFormData, sarà necessario utilizzare [AFNetworking] (https://github.com/AFNetworking/AFNetworking). È anche possibile passare i parametri nell'URL e passare i dati in 'HTTPBody'. Dipende da cosa si aspetta il tuo server. – cnoon

+0

Finisco per utilizzare effettivamente AFNetworking. – fabdarice

0

C'è un metodo separato in Alamofire da caricare. Si prega di verificare la loro documentazione here.

Hanno sottosezioni

  1. Caricamento con Progress
  2. Caricamento MultipartFormData

che descrive il caricamento.

1

As @cnoon ha detto che è possibile utilizzare il metodo di caricamento per tenere traccia dei progressi con alcune modifiche. Ecco cosa esattamente ha lavorato con me:

let jsonData = NSJSONSerialization.dataWithJSONObject(jsonObject, options: .PrettyPrinted) 
Alamofire.upload(.POST, "API URL String", headers: ["Content-Type": "application/json"], data: jsonData) 
     .validate() 
     .responseJSON(completionHandler: { (response: Response<AnyObject, NSError>) in 
      //Completion handler code 
     }) 
     .progress({ (bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) in 
      //Progress handler code 
     }) 

Nota che è necessario impostare la http campo di intestazione valore "Content-Type" a "application/json" se i dati sono formattato come JSON da decodificare correttamente nel back-end.

Problemi correlati