在 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 个函数来等待相同的异步任务