Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «попытка вставить раздел 50, но после обновления осталось только 1 раздел».
Привет всем, я застрял на этой ошибке весь день. Вылетает приложение после установленного Предела загрузки партии в 50 ячеек. Я считаю, что я заполняю tableView неправильно. Вот фрагмент кода, непосредственно работающего с разделами в таблице.
import UIKit import Firebase import Foundation
class NotificationViewController: GradientViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var GVX3: UIView!
var isVisible = false
var notifications: [GActionNotification] = []
//Pull to Refresh
lazy var refresher: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.tintColor = primaryColor
refreshControl.addTarget(self, action: #selector(requestData), for: .valueChanged)
return refreshControl
}()
//Pull to Refresh
@objc func requestData() {
print("requesting data")
let deadline = DispatchTime.now() + .milliseconds(856)
DispatchQueue.main.asyncAfter(deadline: deadline) {
self.refresher.endRefreshing()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
isVisible = true
NotificationService.shared.setSeen(notifications: notifications)
setNotificationsBadge()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
isVisible = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
tableView.clipsToBounds = true
tableView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
if #available(iOS 13.0, *) {
tableView.backgroundColor = UIColor.systemBackground
} else {
// Fallback on earlier versions
tableView.backgroundColor = UIColor.white
}
tableView.allowsSelection = false
if #available(iOS 10.0, *) {
tableView.refreshControl = refresher
}else{
tableView.addSubview(refresher)
}
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
observeNotifications()
}
var loader: BatchCollectionLoader?
func requestMoreNotifications() {
loader?.getNextSnapshot(completion: { [weak self] (snapshot) in
NotificationService.shared.process(snapshot: snapshot, completion: { (notifications) in
guard notifications.count > 0 else { return }
guard let strongSelf = self else { return }
var indexSet = IndexSet.init(integer: strongSelf.notifications.count)
if notifications.count > 1 {
let range = (strongSelf.notifications.count...(strongSelf.notifications.count + notifications.count - 1))
indexSet = IndexSet.init(integersIn: range)
}
let shouldUpdate = strongSelf.notifications.count == 0
strongSelf.notifications.append(contentsOf: notifications)
if shouldUpdate {
strongSelf.tableView.reloadData()
} else {
strongSelf.tableView.beginUpdates()
strongSelf.tableView.insertSections(indexSet, with: .bottom)
strongSelf.tableView.endUpdates()
}
})
})
}
func observeNotifications() {
guard let current = GUser.current else { return }
loader = BatchCollectionLoader.init(collection: NotificationService.shared.notificationReference.document(current.uid).collection("notifications"))
loader?.getNextSnapshot(completion: { [weak self] (snapshot) in
NotificationService.shared.process(snapshot: snapshot, completion: { (notifications) in
guard let strongSelf = self else { return }
strongSelf.notifications = notifications.sorted(by: {$0.time > $1.time})
DispatchQueue.main.async {
strongSelf.tableView.reloadData()
}
if strongSelf.isVisible && isInForeground {
NotificationService.shared.setSeen(notifications: notifications)
}
strongSelf.setNotificationsBadge()
})
})
}
func setNotificationsBadge() {
UIApplication.shared.applicationIconBadgeNumber = notifications.filter({!$0.isSeen}).count
if notifications.filter({!$0.isSeen}).count > 0 {
self.tabBarController?.tabBar.items?[2].badgeValue = "\(notifications.filter({!$0.isSeen}).count)"
} else {
self.tabBarController?.tabBar.items?[2].badgeValue = nil
}
}
func configureTableView() {
tableView.register(UINib.init(nibName: LaunchNotificationCell.identifier, bundle: nil), forCellReuseIdentifier: LaunchNotificationCell.identifier)
tableView.register(UINib.init(nibName: GNotificationCell.identifier, bundle: nil), forCellReuseIdentifier: GNotificationCell.identifier)
tableView.rowHeight = 70
tableView.delegate = self
tableView.dataSource = self
}
}
расширение NotificationViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return notifications.count > 0 ? notifications.count : 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if notifications.count == 0 {
if let cell = tableView.dequeueReusableCell(withIdentifier: LaunchNotificationCell.identifier, for: indexPath) as? LaunchNotificationCell {
return cell
}
}
if let cell = tableView.dequeueReusableCell(withIdentifier: GNotificationCell.identifier, for: indexPath) as? GNotificationCell {
cell.configure(notification: notifications[indexPath.row])
cell.authorProfileTapped = { [weak self] uid in
guard let strongSelf = self else { return }
strongSelf.openProfile(id: uid)
}
cell.postTapped = { [weak self] postUid in
guard let strongSelf = self else { return }
let notification = strongSelf.notifications[indexPath.row]
if notification.action == .friendRequest {
strongSelf.openProfile(id: notification.user)
} else {
let alert = UIAlertController(title: nil, message: "Loading post...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = UIActivityIndicatorView.Style.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
strongSelf.present(alert, animated: true, completion: nil)
PostService.shared.getPost(id: postUid, location: nil, completion: {post, err in
alert.dismiss(animated: true, completion: nil)
if let post = post {
guard let commentsVC = strongSelf.storyboard?.instantiateViewController(withIdentifier: "CommentsViewController") as? CommentsViewController else {return}
commentsVC.post = post
strongSelf.navigationController?.pushViewController(commentsVC, animated: true)
}
})
}
}
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if notifications.count == 0 {
return view.frame.height
}
return 70
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.section == tableView.numberOfSections - 1 &&
indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
requestMoreNotifications()
}
}
}
расширение NotificationViewController: GPostHelperProtocol {} расширение NotificationViewController: ProfileHelperProtocol {}