iOS -Использование Pull-To-Refresh Как узнать, когда новые данные добавляются в узел Firebase в зависимости от местоположения пользователя - PullRequest
0 голосов
/ 15 декабря 2018

Мое приложение позволяет пользователям продавать такие вещи, как кроссовки и т. Д. Кроссовки, которые отображаются в ленте пользователя, основаны на продавцах, которые разместили товары, которые находятся рядом с пользователем.Я использую GeoFire, чтобы узнать местоположение продавца, и все работает отлично.Когда пользователь использует pullToRefresh, если рядом нет новых данных / кроссовок, тогда нет необходимости обновлять список.

Место, где я в тупике, - это когда пользователь вытягивает PullToRefresh.Как определить, что новые товары были добавлены либо совершенно новым продавцом, который находится рядом, либо тем же продавцом, который добавил дополнительные пары кроссовок?

Например,Пользователь А живет в почтовом индексе 10463, и в радиусе 20 миль находятся 2 продавца.Любые кроссовки, которые эти продавцы выставят на продажу, появятся в ленте пользователя.Но третий продавец может прийти и выложить пару кроссовок, или любой из первых 2 продавцов может добавить дополнительную пару.Если пользователь pullsToRefesh, то эти элементы появятся, но если ничего не будет добавлено, то pullToRefresh не должен ничего делать.

Я не хочу излишне перезапускать код firebase, если мне это не нужно.Единственный способ сделать это - сначала проверить postsRef, чтобы проверить, были ли добавлены новые кроссовки двумя продавцами или совершенно новым продавцом, который также находится поблизости.

код:

let refreshControl: UIRefreshControl = {
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: #selector(pullToRefresh), for: .valueChanged)
    return refreshControl
}()

@objc func pullToRefresh() {

      // if there aren't any new nearby sellers or current sellers with new items then the two lines below shouldn't run

      arrOfPosts.removeAll() // this is the array that has the collectionView's data. It gets populated in thirdFetchPosts()
      firstGetSellersInRadius(miles: 20.0)
}

override func viewDidLoad() {
    super.viewDidLoad()

    firstGetSellersInRadius(miles: 20.0) // the user can change the mileage but it's hardcoded for this example
}

// 1. I get the user's location and then get all the nearby sellers
func firstGetSellersInRadius(miles: Double) {

    // user's location
    guard let currentLocation = locationManager.location else { return }
    let lat = currentLocation.coordinate.latitude
    let lon = currentLocation.coordinate.longitude
    let location = CLLocation(latitude: lat, longitude: lon)

    let radiusInMeters = (miles * 2) * 1609.344 // 1 mile == 1609.344 meters
    let region = MKCoordinateRegion(center: location.coordinate, latitudinalMeters: radiusInMeters, longitudinalMeters: radiusInMeters)

    let geoFireRef = Database.database().reference().child("geoFire")

    regionQuery = geoFireRef?.query(with: region)
    queryHandle = regionQuery?.observe(.keyEntered, with: { (key: String!, location: CLLocation!) in

        let geoModel = GeoModel()
        geoModel.userId = key
        geoModel.location = location

        self.arrOfNearbySellers.append(geoModel)
    })

    regionQuery?.observeReady({
        self.secondLoopNearbySellersAndGetTheirAddress(self.arrOfNearbySellers)
    })
}

// 2. I have to grab the seller's username and profilePic before I show their posts because they're shown along with the post
func secondLoopNearbySellersAndGetTheirAddress(_ geoModels: [GeoModel]) {

    let dispatchGroup = DispatchGroup()

    for geoModel in geoModels {

        dispatchGroup.enter()

        if let userId = geoModel.userId {

            let uidRef = Database.database().reference().child("users")?.child(userId)

            uidRef.observeSingleEvent(of: .value, with: { [weak self](snapshot) in

                guard let dict = snapshot.value as? [String: Any] else { dispatchGroup.leave(); return }

                let profilePicUrl = dict["profilePicUrl"] as? String
                let username = dict["username"] as? String

                let userModel = UserModel()
                userModel.profilePicUrl = profilePicUrl
                userModel.username = username

                self?.arrOfSellers.append(userModel)
                dispatchGroup.leave()
            })
        }
    }

    dispatchGroup.notify(queue: .global(qos: .background)) { [weak self] in

        self?.thirdFetchPosts(self!.arrOfSellers)
    }
}

// 3. now that I have their address I fetch their posts
func thirdFetchPosts(_ userModels: [UserModel]) {

    let dispatchGroup = DispatchGroup()

    var postCount = 0
    var loopCount = 0

    for userModel in userModels {

        dispatchGroup.enter()

        if let userId = userModel.userId {

            let postsRef = Database.database().reference().child("posts")?.child(userId)

            postsRef?.observe( .value, with: { [weak self](snapshot) in

                postCount = Int(snapshot.childrenCount)

                guard let dictionaries = snapshot.value as? [String: Any] else { dispatchGroup.leave(); return }

                dictionaries.forEach({ [weak self] (key, value) in
                    print(key, value)

                    loopCount += 1

                    guard let dict = value as? [String: Any] else { return }

                    let postModel = PostModel(userModel: userModel, dict: dict)
                    self?.arrOfPosts.append(postModel)

                    if postCount == loopCount {
                        dispatchGroup.leave()
                        postCount = 0
                        loopCount = 0
                    }
                })
            })
        }
    }

    dispatchGroup.notify(queue: .global(qos: .background)) { [weak self] in
        self?.fourthRemoveQueryObserverReloadCollectionView()
    }
}

// 4. now that I have all the posts inside the arrOfPosts I can show them in the collectionView
func foutrhRemoveQueryObserverReloadCollectionView() {

    DispatchQueue.main.async { [weak self] in

        self?.arrOfPosts.sort { $0.postDate ?? 0 > $1.postDate ?? 0}
        self?.refreshControl.endRefreshing()

        if let queryHandle = self?.queryHandle {
            self.regionQuery?.removeObserver(withFirebaseHandle: queryHandle)
        }

        self?.collectionView.reloadData()

        self?.arrOfNearbySellers.removeAll()
        self?.arrOfSellers.removeAll()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...