标题很可能没有措辞正确,但我会发布我的代码,你可以自己判断......
我想从一个有闭包的函数返回一个String
(该闭包从另一个函数获取一个值:
//call the ServerTimeReturn function and print the results------------ current, from
func handleDateAndTimeFetch() -> String {
var thisIsTheDate : String?
serverTimeReturn { (getResDate) -> Void in //Handles the value received from Google and formats it
let dFormatter = DateFormatter()
dFormatter.dateStyle = .short
dFormatter.timeStyle = .medium
dFormatter.timeZone = TimeZone(abbreviation: "UTC")
thisIsTheDate = dFormatter.string(from: getResDate!)
}
if thisIsTheDate != nil {
return thisIsTheDate!
} else {return "AppDelegate > handleDateAndTimeFetch() > 'thisIsTheDate' was not passed a value (was nil)"}
} //End of function
//Call Google's server for the current date & time in UTC (Coordinated Universal Time)----------------------------
func serverTimeReturn(completionHandler:@escaping (_ getResDate: Date?) -> Void){
let url = URL(string: "https://www.google.com")
let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in
let httpsResponse = response as? HTTPURLResponse
if let contentType = httpsResponse?.allHeaderFields["Date"] as? String {
let dFormatter = DateFormatter() //A formatter object
dFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss z"
let serverTime = dFormatter.date(from: contentType)
completionHandler(serverTime)
guard let _ = data, error == nil else {
print(error ?? "Unknown error")
return
}
}
}
print("Retrieved date value")
task.resume()
}
总结以上内容,我在其他地方拨打handleDateAndTimeFetch()
,当它被呼叫时,IT会拨打serverTimeReturn
,从Google服务器检索当前日期和时间。 serverTimeReturn
使用completionHandler
确保在将数据返回到handleDateAndTimeFetch()
中的调用之前检索数据。现在回到handleDateAndTimeFetch()
,我做了一些格式化,然后将它分配给值thisIsTheDate
(我在闭包之外定义,以便handleDateAndTimeFetch()
可以将它返回到我开始的位置这整个过程在其他地方。
问题是,我认为handleDateAndTimeFetch()
在完成从thisIsTheDate
收集之前尝试返回serverTimeReturn
,因为该值始终为'nil'并且它会打印else
声明。
我的问题是,当我在serverTimeReturn
内拨打handleDateAndTimeFetch()
时,如何在其中添加completionHandler
,以便在我返回{{1}之前确定有值字符串?
相信我,我已经非常努力地想出来了,但我的新手心态不允许它哈哈。
非常感谢!
答案 0 :(得分:1)
完成服务器方法并不意味着你可以直接在另一种方法中使用它,对serverTimeReturn
的调用是异步的,所以你不能返回字符串直接来自handleDateAndTimeFetch
,您必须为handleDateAndTimeFetch
func handleDateAndTimeFetch(completionHandler:@escaping (_ getResDate: String?) -> Void) {
serverTimeReturn { (getResDate) -> Void in //Handles the value received from Google and formats it
let dFormatter = DateFormatter()
dFormatter.dateStyle = .short
dFormatter.timeStyle = .medium
dFormatter.timeZone = TimeZone(abbreviation: "UTC")
let thisIsTheDate = dFormatter.string(from: getResDate!)
completion(thisIsTheDate)
}
}
或者在serverTimeReturn
中进行所有格式化并返回字符串(我推荐),因为不需要执行2个函数来等待相同的异步任务