Как в Swift использовать обработчик завершения в функции, которая уже использует One? - PullRequest
0 голосов
/ 28 апреля 2018

Заголовок, скорее всего, не сформулирован верно, но я выложу свой код, и вы сами сможете судить ...

Я хочу вернуть 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() в другое место, а когда он вызывается, ИТ-специалист звонит serverTimeReturn, где он получает текущую дату и время с серверов Google. serverTimeReturn использует completionHandler, который обеспечивает получение данных перед возвратом к их вызову в handleDateAndTimeFetch(). Теперь, вернувшись к handleDateAndTimeFetch(), я немного форматирую, прежде чем присвоить его значению thisIsTheDate (которое я определяю за пределами замыкания, чтобы handleDateAndTimeFetch() мог вернуть его в то место, где я начал весь этот процесс в другом месте.

Проблема, я думаю, handleDateAndTimeFetch() пытается вернуть thisIsTheDate до того, как он завершит сбор из serverTimeReturn, потому что значение всегда 'nil', и оно печатает мой оператор else.

Мой вопрос: когда я вызываю serverTimeReturn внутри handleDateAndTimeFetch(), как я могу добавить туда completionHandler, чтобы у меня наверняка было значение, прежде чем я верну строку thisIsTheDate?

Поверьте, я очень старался понять это, но мой ум новичка не позволяет ему это, ха-ха.

Большое спасибо!

1 Ответ

0 голосов
/ 28 апреля 2018

Завершение серверного метода не означает, что вы можете использовать его возвращение напрямую в другом методе, вызов 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 функции для ожидания одной и той же асинхронной задачи

...