IOS Swift Nested DispatchGroup для массивов обработки вложенных сетевых запросов

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

Я использую IOS Swift и Firebase и в основном захватываю соответствующих общих друзей, сначала захватывая список друзей, а затем захватывая друзей каждого из друзей в моем списке друзей (поскольку это мои общие друзья), если я не захватил их раньше (я использовать список для отслеживания идентификаторов друзей, которых я уже захватил), я отправляю еще один сетевой запрос в fb, чтобы получить количество общих друзей между текущим пользователем и общим другом и проверить, достаточно ли они актуальны для добавления.

Однако у меня есть еще один запрос после того, как он захватит школьных друзей из firebase, и мне нужно убедиться, что нет повторяющихся записей, потому что есть школьные друзья, которые также являются общими друзьями. Я использую группы отправки следующим образом:

// Iterates through friendList to grab mutual friends
        for user in currUser.friendList {
            // Grabs user friend list
            let userFriendListRef = Database.database().reference().child("friend-list").child(user.userID)
            userFriendListRef.observeSingleEvent(of: .value, with: { (snapshot) in
                guard snapshot.exists(),
                    let userFriendList = snapshot.value as? [String: Any] else {
                        logger.info("No mutual friends grabbed from friend")
                        return
                }

                // Mutual friends dispatchGroup
                self.mutualFriendsDispatchGroup.enter()

                // If exists friends, then see if matches user's interest
                self.filterMutualFriendsToMatchUserInterest(using: userFriendList)
            })
        }

        self.mutualFriendsDispatchGroup.notify(queue: .main) {
            logger.info("Done mutual friends")
        }

// Checks if mutual friend matches interest and then adds it into collectionView
fileprivate func filterMutualFriends(using userFriendList: [String: Any]) {
// Maintains a counter
var searchedMutualFriendCounter = 0

// Iterates through userFriendList
for (userID, _) in userFriendList {
    searchedMutualFriendCounter += 1 // Increments counter

    // Ensures not repeating a mutual friend
    guard usersAddedToHomeScroll[userID] == nil,
        searchedUsers[userID] == nil,
        !blockedUsers.contains(userID) else {

            // Handles mutual friend dispatch group leave condition
            if searchedMutualFriendCounter == userFriendList.count {
                self.mutualFriendsDispatchGroup.leave()
                return
            }

            continue
    }

    searchedUsers[userID] = true
    grabFriendsDispatchGroup.enter()

    // Checks if has enough mutual friends, if yes, grab mutual friend data, else skip
    checkIfFriendHasEnoughMutualFriends(userID) { (result) -> Void in
        // Makes sure that has enough mutual friends
        guard result else {
            logger.info("Not enough mutual friends to show in userFriendScroll for \(userID)")
            self.grabFriendsDispatchGroup.leave()

            // Handles mutual friend dispatch group leave condition
            if searchedMutualFriendCounter == userFriendList.count {
                self.mutualFriendsDispatchGroup.leave()
            }

            return
        }
        logger.info("Mutual friend ID grabbed for \(userID)")
        self.grabMutualFriendData(userID, index: searchedMutualFriendCounter, total: userFriendList.count)
    }

}
}

  fileprivate func getAllFriends() {

    // Grabs mutual friends
    getMutualFriends()

    // Gets school friends
    getSchoolFriends()

// Reloads data after grabbing it all
grabFriendsDispatchGroup.notify(queue: .main) {
    self.collectionView.reloadData()
}
}

Я также вызываю функцию MutualFriendsDispatchGroup.leave() в методе grabMutualFriendData(...).

Я прошу прощения за большой объем кода, я пытался понять, как синхронизировать множество сетевых запросов, вложенных в сетевой запрос, чтобы захватить общих друзей и перед моими школьными друзьями, чтобы я не получал дубликаты записей в моем collectionView представление захваченных пользователей.

Примечание. Счетчик в filterMutualFriends(...) — это хак, который я пытался сделать, чтобы выйти из внешней группы диспетчеризации после того, как вы перебрали список друзей друга. Внешняя диспетчерская группа общих друзей дает сбой.


person mding5692    schedule 09.12.2017    source источник


Ответы (1)


Не удалось найти подходящее долгосрочное решение для устранения проблемы, поэтому мне пришлось взломать ее и использовать плохой обходной путь, который просто удаляет повторяющихся пользователей каждый раз, когда захватывается новый пользователь, а затем перезагружает collectionView. Однако обратите внимание, что это может вызвать проблемы в коде.

person mding5692    schedule 11.12.2017