Как запустить функцию после завершения вызова API в Swift - PullRequest
0 голосов
/ 18 февраля 2020

Я хочу, чтобы моя функция openDoor возвращала true, если вызов API дал нам doorStatus «OPENED». Однако я сталкиваюсь с проблемой, когда эта функция возвращается до вызова API, заставляя каждый раз возвращать false. потому что это было инициализировано так. Мой вопрос заключается в том, как сначала сделать запрос API, чтобы я мог присвоить doorStatusL значение true или false на основе этого вызова API, чтобы вернуть его в конце?

                func openDoor(requesto: URLRequest) ->Bool {
                 var doorstatusL = false;


                func sendRequest() -> Bool {
                NSURLConnection.sendAsynchronousRequest(requesto, queue: OperationQueue.main) {(response, data, error) in

                    guard let data = data else {
                        return
                    }
                    print(String(data: data, encoding: .utf8)!)
                    do {

                        let json = try JSONDecoder().decode([WelcomeElement].self, from: data )
                        //try JSONSerialization.jsonObject(with: data!, options: [])
                        print(json[0].doorstatus)
                        if(json[0].doorstatus == "OPENED"){
                            doorstatusL = true;
                            print(doorstatusL)
                            print("assigned TRUE")
                        }
                    } catch {
                        print("Status Error during JSON serialization: \(error.localizedDescription)")
                    }
                    }
                    return true
                }
                if(sendRequest()==true){
                    print(doorstatusL)
                    print("=======+++++++")
                    return doorstatusL
                } else {
                    print("returned false at the end")
                    return false
                }  
               return true;
            }

Выход с терминала

false
=======+++++++
[{"message":"OPEN, ENTER ","doorstatus":"OPENED"}] 
OPENED
true
assigned TRUE

Спасибо

решено

                        func sendRequest(requesto: URLRequest, success:Bool, completionHandler: @escaping (Bool)->Void) {
                        var doorStatusL = false

                        NSURLConnection.sendAsynchronousRequest(requesto, queue: OperationQueue.main) { (response, data, error) in
                            guard let data = data else { return }

                            do {
                                let json = try JSONDecoder().decode([WelcomeElement].self, from: data )

                                if(json[0].doorstatus == "OPENED") {
                                    doorStatusL = true
                                    completionHandler(doorStatusL)
                                }
                            } catch {
                                print("Status Error during JSON serialization: \(error.localizedDescription)")
                            }
                        }
                    }

                    let completionhandler:(Bool)->Void = { (success) in
                        if success {
                                sendNotifications()
                        }
                    }

                    sendRequest(requesto: request2, success: true, completionHandler: completionhandler)

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020
func openDoor(requesto: URLRequest,completionHandler:@escaping (Bool) -> ()) {
    func sendRequest() -> Bool {
            NSURLConnection.sendAsynchronousRequest(requesto, queue: OperationQueue.main) {(response, data, error) in

                guard let data = data else {
                    return
                }
                print(String(data: data, encoding: .utf8)!)
                do {

                    let json = try JSONDecoder().decode([WelcomeElement].self, from: data )
                    //try JSONSerialization.jsonObject(with: data!, options: [])
                    print(json[0].doorstatus)
                    if(json[0].doorstatus == "OPENED"){
                        doorstatusL = true;
                        print(doorstatusL)
                        print("assigned TRUE")
                    }
                } catch {
                    print("Status Error during JSON serialization: \(error.localizedDescription)")
                }
                }
                completionHandler(true)
            }
            if(sendRequest()==true){
                print(doorstatusL)
                print("=======+++++++")
                completionHandler(doorstatusL) 
            } else {
                print("returned false at the end")
                completionHandler(false)
            }  
    })
}

Использование:

openDoor() { requesto: urlHere,success in
   print(success)
}

Экранирующее закрытие : Экранирующее закрытие - это закрытие, которое вызывается после возврата функции, которую оно было передано. Другими словами, он переживает функцию, которой он был передан.

Не экранирующее закрытие : Закрытие, которое вызывается внутри функции, в которую оно было передано, то есть до его возврата.

Подробнее об этом можно прочитать в этом вопросе: Swift @escaping and Completion Handler

1 голос
/ 18 февраля 2020

Добавить обработчик завершения в метод вызова API

func sendRequest(completion:@escaping (_ response:Bool) -> Void){
   completion(true)
}

, после чего вы можете вызвать функцию после его завершения

sendRequest(completion: {_ in
    yourFunction()
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...