2017-09-24 187 views
0

我有一個fetchJson函數,它使用session.datatask從OpenWeatherMap服務器獲取簡單的JSON對象(字符串)。問題是當我使用尾部閉包調用此函數時我可以在尾部閉包中打印JSON對象,但是當我嘗試在尾部閉包外部打印jsonobject時,它會打印出nil。是否有任何方法可以將此jsonobject打印在closure.?Basically我需要訪問後closure.Here外的JSON對象是我fetchjson代碼:如何從使用session.datatask(with:request)的結尾閉包中獲取數據?

func fetchJson(completion: @escaping (Any)->Void){ 
let Url = composeURL(cityname: "Boston") 
let request = URLRequest(url:Url) 

let task = session.dataTask(with: request) { 
    (data, response, error) ->Void in 
    if let jsonData = data { 
     do{ 
      let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) 

      OperationQueue.main.addOperation 

       {completion(jsonObject) 
      } 
     } catch let error { 
      print ("error creating JSON Object: \(error)") 
     } 

    }else if let requestError = error{ 
     print("error fetching weather json string: \(requestError)") 
    }else { 
     print("Unexpected error with reuqest") 
    } 

}//end of task 
task.resume() 

}//end of fecth json 

這是我在我的視圖控制器調用fetchJson:

var Jacks : Any! 

fetchJson(){ 
    json in 


    Jacks = json 
    print(Jacks)///This prints the jsonobject correctly 


    } 

    print(Jacks) //This prints the jsonobject as nil 

我不不明白爲什麼Jacks會在我將其分配給jsonobject之後爲零。任何想法?如何檢索j後面的c後面的jsonobject losure?

回答

0

答案是因爲你的fetchJson()函數是異步的。只有當您的數據已成功讀取時,纔會調用閉包中的代碼,但在調用fetchJson()之後,最後一行的打印語句會立即運行。此時,您的Jacks對象仍然爲零。

如果您的應用需要在獲取JSON數據後更新其UI或執行額外的任何其他邏輯,我建議將該邏輯移入您在封閉內調用的單獨函數。舉個例子:

func updateView(with jacks: Jacks) { 
    // additional logic here 
} 
+0

因此,基本上你所說的是我沒有辦法在閉包之外打印插孔或者甚至引用它? – Minty

+0

@Minty您可以,但只有在您從API調用中獲得結果後才能執行此操作。你介意分享你想要執行的邏輯嗎? –

+0

基本上我只需要Jacks變量,在閉包之外可以訪問json數據,以便在視圖控制器的不同部分使用。插孔實際上是我的視圖控制器中的全局變量。我如何獲得分配給插孔的JSON數據並在追蹤閉包之外使用? – Minty

相關問題