Как я могу получить доступ к измененной переменной за пределами оператора switch? - PullRequest
0 голосов
/ 20 июня 2020

У меня есть оператор switch, который получает, сколько сообщений у пользователя, и я называю var numberOfPosts to = posts.count. Но я хотел бы вернуть значение Int из numberOfPosts в UICollectionView func numberOfItemsInSection, но оно всегда возвращает ноль. Как мне go исправить это?

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        userSubID = AWSMobileClient.default().userSub!
        let post = uploads.keys
        let predicate = post.userSub == userSubID
        _ = Amplify.API.query(request: .list(uploads.self, where: predicate)) { event in
            switch event {
            case .success(let result):
                switch result {
                case .success(let posts):
                    self.numberOfPosts = posts.count 
                  print(numberOfPosts) // It prints the num of posts
                case .failure(let error):
                    print("Got failed result with \(error.errorDescription)")
                }
            case .failure(let error):
                print("Got failed event with error \(error)")
            }
        }
        print(numberOfPosts)
        return numberOfPosts //The variable returns 0 
    }

1 Ответ

1 голос
/ 20 июня 2020

Когда вызывается функция collectionView(_:,numberOfItemsInSection:), переменная numberOfPosts будет равна 0 и останется прежней в точке, откуда эта функция вернется. Это потому, что вы фактически не изменяете переменную numberOfPosts в этой функции, а скорее запускаете другую функцию, которая позже изменит эту переменную. При этом вы не сможете запустить функцию запроса из collectionView(_:,numberOfItemsInSection:) и использовать ее результаты (т.е. изменение переменной numberOfPosts) в той же функции.

Более того, collectionView(_:,numberOfItemsInSection:) обычно (что означает всегда) плохое место для начала выполнения вызовов API. Они должны выполняться в таких функциях, как viewDidLoad или viewDidAppear.

То, что вы действительно хотите достичь, - это сначала отобразить пустое представление коллекции, выполнить вызов API, и когда у вас есть результат, вам нужно чтобы обновить представление коллекции и заполнить его полученными данными.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        userSubID = AWSMobileClient.default().userSub!
        let post = uploads.keys
        let predicate = post.userSub == userSubID
        _ = Amplify.API.query(request: .list(uploads.self, where: predicate)) { event in
            switch event {
            case .success(let result):
                switch result {
                case .success(let posts):
                    self.numberOfPosts = posts.count 
                    print(numberOfPosts) // It prints the num of posts

                    self.collectionView.reloadData() // Reload the collection view here

                case .failure(let error):
                    print("Got failed result with \(error.errorDescription)")
                }
            case .failure(let error):
                print("Got failed event with error \(error)")
            }
        }
    }
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.numberOfPosts
    } 
}

Кроме того, вам, скорее всего, потребуется использовать фактический массив для заполнения представления коллекции данными, поэтому, возможно, сохраните только posts.count вам не очень поможет. Вместо этого вам нужно будет сохранить весь массив posts. Но общая идея вызова API где-то вне функции представления коллекции и вызова collectionView.reloadData() останется точно такой же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...