I am encountering an EXC_BREAKPOINT error in my iOS app, particularly on the line group.depart() within the makeAPICallForCategories operate. The unusual factor is that the worth of the error’s subcode varies between numbers 7, 3, and a pair of. I’ve included the related code snippet beneath.
//
// ViewController.swift
// follow
//
// Created by aycan duskun on 12.03.2023.
//
import UIKit
import Firebase
import FirebaseAuth
import FirebaseFirestore
class HomeVC: UIViewController {
var consumer: Consumer?
let titleLabel = SPTitleLabel(textAlignment: .left, fontSize: 20)
let userImage = SPImageView(cornerRadius: 40)
let querySearchBar = SPSearchBar()
var queryRecipesVC: QueryRecipesVC!
let cancelButton = SPButton(backgroundColor: .clear, title: "Cancel")
var recipes: [(tag: String, recipe: [Recipe])] = []
var similarRecipesArray: [GetSimilarRecipes] = []
let categoryHeaderView = CategoriesHeaderView()
let recommendationHeaderTitle = SPTitleLabel(textual content: "Advice", textAlignment: .left, fontSize: 20)
let recommendationSeeAllButton = SPButton(backgroundColor: .clear, title: "See All")
let tags = [Tags.breakfast, Tags.lunch, Tags.dinner, Tags.soup, Tags.dessert]
let group = DispatchGroup()
non-public var searchDebounceTimer: Timer?
lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(body: .zero, collectionViewLayout: UICollectionViewFlowLayout.init())
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.showsVerticalScrollIndicator = false
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID)
collectionView.register(RecommendationCollectionViewCell.self, forCellWithReuseIdentifier: RecommendationCollectionViewCell.reuseID)
collectionView.register(CategoriesHeaderView.self, forSupplementaryViewOfKind: "CategoriesHeader", withReuseIdentifier: CategoriesHeaderView.headerIdentifier)
collectionView.register(RecommendationHeaderView.self, forSupplementaryViewOfKind: "RecommendationHeader", withReuseIdentifier: RecommendationHeaderView.headerIdentifier)
collectionView.backgroundColor = .systemBackground
return collectionView
}()
override func viewDidLoad() {
tremendous.viewDidLoad()
view.backgroundColor = .systemBackground
configureCompositionalLayout()
getCategoriesFromCache()
setupQueryRecipesVC()
layoutUI()
fetchRecipeData()
configure()
createDismissKeyboardTapGesture()
retrieveUserInfo()
cancelButton.addTarget(self, motion: #selector(cancelButtonTapped), for: .touchUpInside)
override func viewWillAppear(_ animated: Bool) {
tremendous.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(false, animated: true)
}
non-public func setupQueryRecipesVC() {
queryRecipesVC = QueryRecipesVC()
addChild(queryRecipesVC)
view.addSubview(queryRecipesVC.view)
queryRecipesVC.didMove(toParent: self)
queryRecipesVC.view.isHidden = true
queryRecipesVC.view.translatesAutoresizingMaskIntoConstraints = false
querySearchBar.delegate = self
}
@objc func cancelButtonTapped() {
queryRecipesVC.view.isHidden = true
collectionView.isHidden = false
cancelButton.isHidden = true
querySearchBar.textual content = ""
}
func makeAPICallForCategories(tag: String, atIndex index: Int, group: DispatchGroup) {
NetworkManager.shared.getRecipesInfo(for: .searchCategory(tag)) { [weak self] class in
guard let self = self else { return }
change class {
case .success(let classes):
for class in classes {
PersistenceManager.updateWith(class: class, actionType: .add) { error in
if let error = error {
print("Error saving class: (error)")
}
}
}
self.updateUI(with: classes, atIndex: index)
case .failure(let error):
break
}
group.depart()
}
}
func fetchRecipeData() {
recipes = tags.map { (tag: $0, recipe: []) }
for (index, tag) in tags.enumerated() {
group.enter()
makeAPICallForCategories(tag: tag, atIndex: index, group: self.group)
}
group.notify(queue: .predominant) {
self.collectionView.reloadData()
}
}
func getCategoriesFromCache() {
// First, attempt to retrieve classes from cache
for (index, tag) in tags.enumerated() {
PersistenceManager.retrievedCategories { [weak self] lead to
guard let self = self else { return }
change outcome {
case .success(let cachedCategories):
if !cachedCategories.isEmpty {
// If cached classes can be found, replace UI
print("Information is coming from cache: (cachedCategories)")
self.updateUI(with: cachedCategories, atIndex: index)
} else {
// If not obtainable in cache, make API name
print("Information just isn't obtainable in cache, making API name...")
self.makeAPICallForCategories(tag: tag, atIndex: index, group: self.group)
}
// If there's an error retrieving from cache, make API name
case .failure(let error):
print("Error retrieving classes from cache: (error)")
}
}
}
}
func configure() {
collectionView.setUp(to: view, and: querySearchBar)
cancelButton.isHidden = true
}
func updateUI(with classes: [Recipe], atIndex index: Int) {
DispatchQueue.predominant.async {
self.recipes[index].recipe = classes
}
}
func fetchSimilarRecipes(recipeID: String, completion: @escaping (Outcome<[GetSimilarRecipes], SPError>) -> Void) {
print("Fetching related recipes for recipeID: (recipeID)")
NetworkManager.shared.getSimilarRecipes(recipeID: recipeID) { lead to
//guard let self = self else {return}
change outcome {
case .success(let similarRecipes):
print("Fetched related recipes: (similarRecipes)")
DispatchQueue.predominant.async {
completion(.success(similarRecipes))
self.similarRecipesArray.append(contentsOf: similarRecipes)
print("SIMILAR RECIPES ARE: (self.similarRecipesArray)")
self.collectionView.reloadData()
}
case .failure(let error):
print("Error fetching related recipes: (error.localizedDescription)")
DispatchQueue.predominant.async {
completion(.failure(error))
}
//self.view.bringSubviewToFront(self.tableView)
}
}
}
This situation began taking place after I added a brand new part underneath the makeAPICallForCategories operate that includes the PersistenceManager. Earlier than including this part, the code used to work fantastic with none crashes.
Moreover, I am utilizing a DispatchGroup named group to make sure that all API calls are accomplished earlier than reloading the collectionView knowledge.
Any insights into why this error is going on and find out how to resolve it will be vastly appreciated. Thanks!