2017-09-04 34 views
-1

我想從外部的JSON文件,這是一個Web服務器,它取得了一個字符串,它取得了成功,但它是在一個封閉的地方,它得到的價值,和我需要把它弄到外面,所以我可以用變量returnip來返回它。我該怎麼做?返回變量指定內部封閉 - 斯威夫特

func getJsonFromUrl() -> String { 

    let URL2 = "https://url.com/asd.php"; 
    let url = URL(string: URL2) 
    URLSession.shared.dataTask(with:url!) { (data, response, error) in 
     if error != nil { 
      print(error as Any) 
     } else { 
      do { 

       let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any] 
       let ips = parsedData["ip"] as! String 
       print("The IP is: " + ips) //Prints the value correctly 
       var returnip = ips //The value that I want to return, that does not go outside this closure 
      } catch let error as NSError { 
       print(error) 
      } 
     } 

     }.resume() 
    return returnip //Does not return anything 
} 

感謝

+0

你不能做這種方式。 Web調用是異步的。返回將在URL調用完成之前發生。 – ryantxr

回答

1

不能從異步函數和一個return語句返回內部封閉只能從封閉本身返回。

您需要改爲使用完成處理程序。另外,在解析網絡響應時不要使用強制展開optionals /強制轉換選項。

func getJsonFromUrl(name: String, completion: @escaping (String?)->()) { 
    //use name variable just as you would in a normal function 
    let URL2 = "https://url.com/asd.php" 
    let url = URL(string: URL2) 
    URLSession.shared.dataTask(with:url!) { (data, response, error) in 
     if error != nil { 
      print(error as Any) 
      completion(nil) 
     } else { 
      do { 
       guard let parsedData = try JSONSerialization.jsonObject(with: data!) as? [String:Any] else { completion(nil); return } 
       guard let ips = parsedData["ip"] as? String else {completion(nil); return } 
       print("The IP is: " + ips) //Prints the value correctly 
       completion(ips) 
      } catch let error as NSError { 
       print(error) 
       completion(nil) 
      } 
     } 
    }.resume() 
} 

然後,你可以這樣調用:

getJsonFromUrl(name: "Input", completion: { ips in 
    print(ips) 
    //you can only use the value inside the closure of completion 
}) 
+0

如果函數有參數,我該怎麼辦?例如,'func getJsonFromUrl(name:String,completion:@escaping(String?) - >()){}'。那是製作這個功能的方式嗎?你怎麼稱呼它? – FrankFabregat

+0

順便說一句,'dataTask(with:URL)'將在後臺隊列中運行。因此,如果您需要完成與UI相關的工作,請在主隊列中進行。 – antonio081014

+0

順便說一下,我需要將它稱爲變量,所以'let variable = getJsonFromUrl(name:name,completion:{在 print(ips) })''。那是對的嗎? – FrankFabregat