IOS Swift 嵌套网络请求处理数组的嵌套 DispatchGroup
IOS Swift Nested DispatchGroup for Nested Network requests handling arrays
我遇到了崩溃,我不太确定如何处理调度组内嵌套调度组的情况。我知道我做错了什么并发生崩溃,希望获得有关如何处理以下情况的帮助:
我正在使用 IOS Swift 和 Firebase,基本上是通过首先抓取一个朋友列表来抓取相关的共同朋友,然后抓取我的朋友列表中每个朋友的朋友(因为那些是我的共同的朋友),如果我之前没有抓取他们(我使用列表来跟踪我已经抓取的朋友的 id),我向 fb 发送另一个网络请求以获取当前用户和共同朋友之间的共同朋友的数量并检查他们是否足够相关,可以添加。
但是我有另一个请求从 firebase 抓取学校朋友,我需要确保没有重复的条目,因为有些学校朋友也是共同的朋友。我正在像这样使用 Dispatch 组:
// 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()
}
}
我还在 grabMutualFriendData(...) 方法中调用了 mutualFriendsDispatchGroup.leave()。
对于大量的代码,我深表歉意,我试图弄清楚如何将大量网络请求同步嵌套在网络请求中以获取共同的朋友以及在我获取学校朋友之前,这样我就不会得到我的 collectionView 上的重复条目显示了被抓取的用户。
注意:filterMutualFriends(...) 中的计数器是我尝试的一个 hack,一旦您遍历朋友的好友列表,它就会退出外部调度组。外层的共同好友dispatchGroup崩溃了
无法找到解决此问题的合适的长期解决方案,因此我不得不绕过它并使用一个糟糕的解决方法,它只会在每次抓取新用户时删除重复用户,然后重新加载 collectionView。但是,请注意,这会并且可能会导致代码出现问题。
我遇到了崩溃,我不太确定如何处理调度组内嵌套调度组的情况。我知道我做错了什么并发生崩溃,希望获得有关如何处理以下情况的帮助:
我正在使用 IOS Swift 和 Firebase,基本上是通过首先抓取一个朋友列表来抓取相关的共同朋友,然后抓取我的朋友列表中每个朋友的朋友(因为那些是我的共同的朋友),如果我之前没有抓取他们(我使用列表来跟踪我已经抓取的朋友的 id),我向 fb 发送另一个网络请求以获取当前用户和共同朋友之间的共同朋友的数量并检查他们是否足够相关,可以添加。
但是我有另一个请求从 firebase 抓取学校朋友,我需要确保没有重复的条目,因为有些学校朋友也是共同的朋友。我正在像这样使用 Dispatch 组:
// 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()
}
}
我还在 grabMutualFriendData(...) 方法中调用了 mutualFriendsDispatchGroup.leave()。
对于大量的代码,我深表歉意,我试图弄清楚如何将大量网络请求同步嵌套在网络请求中以获取共同的朋友以及在我获取学校朋友之前,这样我就不会得到我的 collectionView 上的重复条目显示了被抓取的用户。
注意:filterMutualFriends(...) 中的计数器是我尝试的一个 hack,一旦您遍历朋友的好友列表,它就会退出外部调度组。外层的共同好友dispatchGroup崩溃了
无法找到解决此问题的合适的长期解决方案,因此我不得不绕过它并使用一个糟糕的解决方法,它只会在每次抓取新用户时删除重复用户,然后重新加载 collectionView。但是,请注意,这会并且可能会导致代码出现问题。