在 Swift 中,如何在已经使用一个的函数中使用完成处理程序?
In Swift, How do I use a Completion Handler in a function that's already Using One?
标题很可能措辞不正确,但我会post我的代码,你可以自己判断...
我想return一个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
来确保在 return 将其调用到 handleDateAndTimeFetch()
之前检索数据。现在回到 handleDateAndTimeFetch()
,我在将它分配给值 thisIsTheDate
之前做了一些格式化(我在闭包外部定义它,以便 handleDateAndTimeFetch()
可以 return 它到我在其他地方开始整个过程的地方。
问题是,我认为 handleDateAndTimeFetch()
正在尝试 return thisIsTheDate
在完成从 serverTimeReturn
收集之前,因为该值始终是 'nil'并打印我的 else
语句。
我的问题是,当我在 handleDateAndTimeFetch()
中调用 serverTimeReturn
时,我怎样才能在那里添加一个 completionHandler
以便我在 [=46] 之前肯定有一个值=] thisIsTheDate
字符串?
相信我,我已经很努力地想弄明白了,但我的新手头脑不允许这样做哈哈。
非常感谢!
完成服务器方法并不意味着您可以在另一个方法中直接使用它 return,对 serverTimeReturn
的调用是异步的,因此您不能 return直接来自 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
和 return 中的所有格式设置为字符串(我推荐),因为无需执行 2 个函数来等待相同的异步任务
标题很可能措辞不正确,但我会post我的代码,你可以自己判断...
我想return一个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
来确保在 return 将其调用到 handleDateAndTimeFetch()
之前检索数据。现在回到 handleDateAndTimeFetch()
,我在将它分配给值 thisIsTheDate
之前做了一些格式化(我在闭包外部定义它,以便 handleDateAndTimeFetch()
可以 return 它到我在其他地方开始整个过程的地方。
问题是,我认为 handleDateAndTimeFetch()
正在尝试 return thisIsTheDate
在完成从 serverTimeReturn
收集之前,因为该值始终是 'nil'并打印我的 else
语句。
我的问题是,当我在 handleDateAndTimeFetch()
中调用 serverTimeReturn
时,我怎样才能在那里添加一个 completionHandler
以便我在 [=46] 之前肯定有一个值=] thisIsTheDate
字符串?
相信我,我已经很努力地想弄明白了,但我的新手头脑不允许这样做哈哈。
非常感谢!
完成服务器方法并不意味着您可以在另一个方法中直接使用它 return,对 serverTimeReturn
的调用是异步的,因此您不能 return直接来自 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
和 return 中的所有格式设置为字符串(我推荐),因为无需执行 2 个函数来等待相同的异步任务