AFNetworking и Swift-Save JSON response


Я хочу сделать запрос GET в swift, чтобы получить некоторые данные Json. Я пытался использовать AFNetworking, и это работает, но я не знаю, как вернуть Json, который я получаю.

Я пробовал с return, но это сделано до GET, поэтому я ничего не получаю...

func makeGet(place:String) -> String
{
    var str:String = ""
    let manager = AFHTTPRequestOperationManager()
    manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
    manager.GET("http://something.com/api/(place)",
        parameters: nil,
        success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
            str = "JSON:  (responseObject.description)"
            println(str) //print the good thing
        },
        failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
            str = "Error: (error.localizedDescription)"
        })
    return str //return ""
}

Вы можете мне помочь ?

3 4

3 ответа:

Вы не получаете ответа от этой функции, потому что операция GET происходит асинхронно. То есть порядок исполнения выглядит так:

  1. Ты звонишь makeGet

  2. makeGet создает manager, который запускает запрос GET

  3. makeGet завершает выполнение и возвращает пустую строку

  4. (некоторое время спустя) manager получает значение обратно от сервера и выполняет либо success, либо failure блок.

Таким образом, единственный раз, когда у вас есть доступ к JSON, который возвращается с сервера, - это Шаг 4, и вам нужно найти способ хранения этого значения, чтобы вы могли его проанализировать или использовать. Здесь есть множество опций - одна из них заключается в определении замыканий, которые вызывают обработчики событий на экземпляре класса, например:
class MyClass {

    func jsonLoaded(json: String) {
        println("JSON: \(json)")
    }

    func jsonFailed(error: NSError) {
        println("Error: \(error.localizedDescription)")
    }

    func makeGet(place:String) {        
        let manager = AFHTTPRequestOperationManager()
        manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
        manager.GET("http://something.com/api/\(place)",
            parameters: nil,
            success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
                self.jsonLoaded(responseObject.description)
            },
            failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
                self.jsonFailed(error)
            }
        )
    }

}

Поскольку вы хотите вернуть значение после завершения запроса webservice, вы должны передать данные через делегат или блок (в swift это называется замыканием)

Я вижу здесь полезные блоки

//Above your class file create a handler alias 
typealias SomeHandler = (String! , Bool!) -> Void

func makeGet(place:String , completionHandler: SomeHandler!)
{
    var str:String = ""
    let manager = AFHTTPRequestOperationManager()
    manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
    manager.GET("http://something.com/api/\(place)",
        parameters: nil,
        success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
            str = "JSON:  \(responseObject.description)"
            println(str) //print the good thing
            completionHandler(str,false)   //str as response json, false as error value

        },
        failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
            str = "Error: \(error.localizedDescription)"
            completionHandler("Error",true)   
        })
    //return str //return ""    You don't want to return anything here
}

Когда вы хотите вызвать метод, получите значения, подобные этому

makeGet(){
   yourJSONString , errorValue in   //Here the value will be passed after you get the response

     if !errorValue { 
         println("The End."
     }
}

Подробнее о быстрых замыканиях

К вашему сведению: владелец AFNetworking создал новый сетевой слой для swift и он называется Alamofire (AF от AFNetworking - Alamofire :])

let manager = AFHTTPSessionManager()
    manager.GET("http://api.androidhive.info/json/movies.json", parameters: nil, success: { (operation, responseObject) -> Void in
        print(responseObject)
        }, failure: nil)

AFHTTPRequestOperationManager недоступен в последней библиотеке AFnetworking, он заменен на AFHTTPSessionManager. Это простой пример получения объекта ответа.