Можем ли мы вызывать api асинхронно в didSelectRow по indexpath в ios swift - PullRequest
0 голосов
/ 05 сентября 2018

Я хочу вызвать api из didSelectRowat indexpath, используя некоторый идентификатор, и в соответствии с ответом api мне нужно перейти на другой экран.

func tableView (_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

let contactDB : FMDatabase!
contactDB = FMDatabase(path: databasePath!)
if contactDB != nil{

            if contactDB.open(){

                let read:Int = 1

               let campaignID = self.notification_details[indexPath.row].userId

                let querySQL = "UPDATE new_notifications SET read = \(read) WHERE from_id = \"\(campaignID)\""

                let results:FMResultSet? = contactDB.executeQuery(querySQL,withArgumentsIn: nil)
          }

        contactDB.close()

       }
    let cell = tableView.cellForRow(at: indexPath)
   cell?.layer.backgroundColor = UIColor.clear.cgColor
    if  self.notification_details[indexPath.row].notification_type == "LIVE"{
        DispatchQueue.main.async {
            NotificationCenter.default.post(name: Notification.Name("live_notification_notificationtab"), object:  self.notification_details[indexPath.row].campaign_id)

    }

}

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Да, вы определенно можете это сделать, но давайте проанализируем, как лучше всего это сделать. Предположим, у вас есть некоторая информация, отображаемая в табличном представлении. Один пользователь выбирает строку, которую вы хотите использовать для API, но ответ API требует времени для перехода с сервера на ваше устройство, так что же будет делать пользователь в это время? Если вы позволяете пользователю взаимодействовать с пользовательским интерфейсом, он / она может прокручивать экран и выбирать некоторые другие строки, поэтому не следует разрешать пользователю взаимодействовать с API, вместо этого пользователь должен быть заблокирован от использования приложения до вы получите ответ, поэтому правильнее всего заблокировать пользователя с помощью какого-либо загрузчика или индикатора, а затем сделать асинхронный вызов.

0 голосов
/ 05 сентября 2018

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

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

func userSelectedItem(_ item: MyObject) {
    progressBackground?.isHidden = false
    progressActivityIndicator?.startAnimating()
    MyObject.fetchDetails(id: item.id) { detailedObject in
        self.navigationController?.pushViewController(DetailedObjectViewController(detailedObject), animated: true)
        self.progressBackground?.isHidden = true
        self.progressActivityIndicator?.stopAnimating()
    }
}

Это можно назвать похожим на:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    userSelectedItem(items[indexPath.row])    
}

но все зависит от того, как вы реализовали свое табличное представление.

В любом случае вам может потребоваться прервать операцию с некоторыми событиями. Например, если пользователь переходит на другой экран во время выполнения асинхронной операции, вы можете запретить вызов после завершения выборки. Самая простая процедура состоит в том, чтобы использовать некоторую переменную, такую ​​как var isVisible: Bool = false, которая затем устанавливается на true, когда вид действительно появляется, а значение false на виде исчезает. Затем вы можете использовать это свойство внутри блока, в который вы помещаете новый контроллер представления и решаете перемещаться или нет.

...