简体   繁体   中英

IOS Swift Nested DispatchGroup for Nested Network requests handling arrays

I'm experiencing crashes and I'm not too sure how to handle the situation with nested dispatchgroup inside a dispatchgroup. I know I'm doing something wrong and getting crashes and would like some help with how to handle below situation:

I am using IOS Swift and Firebase and basically grabbing relevant mutual friends by first grabbing a friendList, and then grabbing the friends of each of the friends on my friendList (as those are my mutual friends), if I have not grabbed them earlier (I use a list to track ids of friends Ive already grabbed), I send another network request to fb to grab the number of mutual friends between current user and mutual friend and check if they are relevant enough to be added.

However I have another request after that grabs school friends from firebase and I need to make sure there arent duplicate entries because there are school friends that are also mutual friends. I'm using Dispatch groups like so:

// 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()
}
}

I also call mutualFriendsDispatchGroup.leave() in grabMutualFriendData(...) method.

I apologize for the large amount of code, I was trying to figure out basically how to put in sync lots of network requests nest in a network request to grab mutual friends and before my grab school friends so that I dont get duplicate entries on my collectionView presenting the grabbed users.

Note: The counter thing in filterMutualFriends(...) is a hack I was attempting that would exit out of the outer dispatchgroup once you've iterated through the friendlist of a friend. The outer mutual friends dispatchGroup is the one crashing.

Could not figure out a proper long-term solution to fix the issue, so I had to hack around it and use a bad workaround which just removes duplicate users everytime a new user is grabbed and then reloads the collectionView. However, note that this will and can cause problems in the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM