Swift выполняет функции последовательно - PullRequest
0 голосов
/ 02 июля 2018

У меня есть следующий код, который получает токен доступа из логина на Facebook и возвращает его как «accessToken». Получив токен доступа, я хочу передать его на мой сервер в запросе и вернуть ответ в виде массива.

У меня проблема в том, что запрос к серверу выполняется до получения accessToken. Я изучил операторы замыкания, но не могу найти способ упорядочить выполнение функций, не заканчивая вложением. Я не против вложения в этом случае, но в будущем, если я скажу 5 функций, это начнет выглядеть грязно.

Подхожу ли я к этому наилучшим образом, используя классы и функции? Обычно, когда я пишу код в swift, весь код, относящийся к viewController, будет содержаться в 1 файле, но по мере роста проекта я стремлюсь реализовать более ООП подход, чтобы сделать проект более управляемым. Как мне лучше всего этого добиться?

import Foundation
import UIKit

class registrationPage: UIViewController {

    @IBAction func facebookButton(_ sender: Any) {

        // Get the access token from facebook
        let accessToken = facebookLogin().login()

        // Get the users currency, langage and locale.
        let currency = Locale.current.currencyCode ?? "GBP"
        let language = Locale.current.languageCode ?? "GB"
        let region = Locale.current.regionCode ?? "GB"

        let params = "accessToken=\(accessToken)&currency=\(currency)&language=\(language)&region=\(region)"

        let resultArray = database().connect(endPoint: "loginfb.php?", params: "\(params)")

        print(resultArray)

    }
}

class facebookLogin {

    var response = ""

    func login(completion: (_ result: String) -> Void) {

     let loginManager = LoginManager()

     loginManager.logIn(readPermissions:[ReadPermission.publicProfile, ReadPermission.email], viewController: registrationPage() as UIViewController) {

    loginResult in switch loginResult {

    case .failed:
    self.response = "ERROR"

    case .cancelled:
    self.response = "ERROR"

    case .success:

        self.response = "\(String(describing: FBSDKAccessToken.current().tokenString!))"
        print(self.response)

    }
        }

        completion(self.response)
    }
}

1 Ответ

0 голосов
/ 02 июля 2018

loginManager.logIn асинхронный, поэтому он требует закрытия. Вы можете синхронизировать вызов или, как вы сказали, использовать вложенные замыкания, когда один вызывает следующий.

Чтобы сделать let accessToken = facebookLogin().login() синхронным с DispatchGroup:

class facebookLogin {
    func login() -> String {
        let loginManager = LoginManager()

        var response = ""

        let group = DispatchGroup()
        group.enter() // loginManager.logIn

        loginManager.logIn(readPermissions:[ReadPermission.publicProfile, ReadPermission.email], viewController: registrationPage() as UIViewController) {

            loginResult in switch loginResult {                
            case .failed:
                self.response = "ERROR"

            case .cancelled:
                self.response = "ERROR"

            case .success:            
                self.response = "\(String(describing: FBSDKAccessToken.current().tokenString!))"
                print(self.response)

            }

            group.leave() // loginManager.logIn
        }

        group.wait()
        return response
    }
}

Если вам не нравится синтаксис facebookLogin().login() { accessToken in ... }, вы можете поместить часть { accessToken in ... } в ее собственную функцию

func callServer(accessToken: String) {
    // Get the users currency, langage and locale.
    let currency = Locale.current.currencyCode ?? "GBP"
    let language = Locale.current.languageCode ?? "GB"
    let region = Locale.current.regionCode ?? "GB"

    let params = "accessToken=\(accessToken)&currency=\(currency)&language=\(language)&region=\(region)"

    let resultArray = database().connect(endPoint: "loginfb.php?", params: "\(params)")

    print(resultArray)
}

и позвоните по номеру

@IBAction func facebookButton(_ sender: Any) {

    // Get the access token from facebook
    facebookLogin().login(completion: callServer(accessToken:))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...