Отложенные функции после асинхронного вызова все еще вызываются перед асинхронными

Таким образом, у меня есть 3 функции, которые должны сделать следующее :

  1. fetchNewMetaData() Извлечение данных с веб-сервера с помощью Alamofire и синхронизация ответа JSON с основным объектом данных с помощью SyncDB.
  2. fetchCurrentMetaObjects() Извлекает объекты из сущности Core Data и добавляет их в массив [NSManagedObject].
  3. applyLabels(label:UILabel, metaKey:String) Примените значение массива of [NSManagedObject]к указанной метке в соответствии с предоставленным metaKey.

Вот код функции :

var items = [NSManagedObject]()

func fetchNewMetaData() {
    let parameters: Parameters = ["email": email!, "password": password!]
    let headers: HTTPHeaders = ["Content-Type": "application/x-www-form-urlencoded"]
    Alamofire.request("https://mywebsite.com/Sync.php", method: .post, parameters: parameters, headers: headers).validate().responseJSON { response in            
        if let jsonResult = response.result.value {
            let json = JSON(jsonResult)
            let jsonData = json["data"]
            print("JSON DATA : (jsonData)")
            let jsonString = jsonData.description
            let stringData = jsonString.data(using: String.Encoding.utf8)
            let serializedJSON = try! JSONSerialization.jsonObject(with: stringData!, options: []) as! [[String : Any]]

            Sync.changes(serializedJSON, inEntityNamed: "Usermeta", dataStack: self.dataStack) { error in
                self.fetchCurrentMetaObjects()
            }
        }
    }
}

func fetchCurrentMetaObjects() {
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Usermeta")
    request.sortDescriptors = [NSSortDescriptor(key: "remoteID", ascending: true)]
    self.items = (try! dataStack.mainContext.fetch(request)) as! [NSManagedObject]
}

func applyLabels(label:UILabel, metaKey:String) {
    for item in items as! [NSManagedObject] {
        if let savedMetaKey = item.value(forKey: metaKey) as? String {
            label.text = savedMetaKey
        }
    }
}

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

override func viewDidLoad() {
    super.viewDidLoad()

    self.fetchNewMetaData()
    self.fetchCurrentMetaObjects()
    DispatchQueue.main.async {
        self.applyLabels(label: self.label, metaKey: "firstName")
    }
}

Я нашел несколько потоков, говорящих о группах отправки и очередях на SO, но все они основаны на Swift 2 или синтаксисе Obj-C, и ничего не применяется к Swift 3. Что-то знает, в чем здесь проблема ? Я знаю, что данные сохраняются в CoreData, но похожеapplyLabels(), что это вызывается раньше fetchcNewMetaData()и fetchCurrentMetaObjects()есть.

Спасибо!

1 ответ

  1. Метод fetchNewMetaData вернется до получения ответа alamofire. Если вы установите точки останова в этом методе, вы заметите, что он попадает в последний } в конце метода, прежде чем он перейдет в ответ Alamofire, затем он вернется и ударит ответ Alamofire мгновением позже.

    Я предполагаю, что вы хотите вызвать методы в следующем порядке?
    fetchNewMetaData — > как только вы получите ответ — > > fetchCurrentMetaObjects ->>> когда это будет сделано — > > > > применить метки

    Если это так, вызовите fetchCurrentMetaObjects в вызове alamofire сразу после синхронизации.изменить, это означает, что fetchCurrentMetaObjects не будет вызываться, пока вы не получите ответ.

    Затем вызовите applyLabels прямо в конце fetchCurrentMetaObjects в DispatchQueue.главный.асинхронный.

    В viewDidLoad, все, что вы должны вызвать fetchNewMetaData, и затем он должен идти в порядке. Дайте мне знать, как это работает для вас.