Using Firebase to populate TableviewCell with Collectionview inside - swift

I can populate my TableviewCell with images and upload them to Firebase successfully but not to my CollectionView inside the cell. However, I can upload them to a CollectionView on another ViewController as long as it's not inside a TableViewCell. I experimented with reloading the data but nothing appears and isn't required by the one on the other ViewController. I'm trying to get the "showcaseImages" to appear in the collectionView.
This is what I have to save the data in my structure:
func save ( userInfo: UserInfo, completion: #escaping (Result < Bool, NSError>) -> Void) {
var showcaseImagesDict = [String : String]()
userInfo.showcaseImages.forEach { showcaseImagesDict[UUID().uuidString] = $0 }
userReference.addDocument(data: ["profileImage": userInfo.profileImage, "profileName": userInfo.profileName, "showcaseImages": showcaseImagesDict
]) { (error) in
if let unwrappedError = error {
completion(.failure(unwrappedError as NSError))
}else {
completion(.success(true))
}
}
}
This is what I have to Listen:
func listen (completion : #escaping ([UserInfo]) -> Void) {
userReference.addSnapshotListener { (snapshot, error) in
guard let unwrappedSnapshot = snapshot else {return}
let documents = unwrappedSnapshot.documents
var usersInfo = [UserInfo]()
for document in documents {
let documentData = document.data()
guard
let profileImage = documentData["profileImage"] as? String,
let profileName = documentData["profileName"] as? String,
let showcaseImagesDict = documentData["showcaseImages"] as? [String : String]
else {continue}
let showcaseImages = showcaseImagesDict.map {$0.value}
let userInfo = UserInfo(profileImage: profileImage, profileName: profileName, showcaseImages: showcaseImages)
usersInfo.append(userInfo)
}
completion(usersInfo)
}
}
Heres what I have to populate the TableviewCell:
func populate(with user: UserInfo){
profileName.text = user.profileName
imageCache2?.getImage(named: user.profileImage,completion: { [weak self](image) in
self?.userImage.image = image
//self?.user = user
})
}
This is to populate CollectionViewCell:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CVCell", for: indexPath)
let collectionViewCell1 = cell as? CollectionViewCell
collectionViewCell1?.imageCache4 = imageCache3
let imagePath = showcaseImages[indexPath.item]
collectionViewCell1?.populate(with: imagePath)
return cell
}

Related

Collection View cell text not showing my data and not showing my number of items in section properly

Hello im doing to do app with firebase. I'm using collection view for show saved user task. When i fetch my tasks i see my fetch data at console properly. Nothing problem with that. I can get my data. But when i try to present my tasks at my collection view i see blank cells or i see random one or two tasks. When i try to add new task, for example i have total 7 task but my collection view have 12 cell. I'm saving one task but my collection view total cell have more than one.
As you can see down below image i have total 2 task saved at firebase but my collection view showing 6 cell. Also not present my tasks at cell text.
So this is my how to save my task function.
#objc func addTaskButtonClicked() {
if NewTaskViewController.textView.text == "" {
makeAlert(titleInput: "Error", messageInput: "Please write your task.")
}else {
guard let currentUid = Auth.auth().currentUser?.uid else {return}
guard let text = NewTaskViewController.textView.text else {return}
let taskId = NSUUID().uuidString
let data = [
"text" : text,
"timestamp" : Timestamp(date: Date()),
"taskId" : taskId,
] as [String : Any]
Firestore.firestore().collection("tasks").document(currentUid).collection("ongoing_tasks").document(taskId).setData(data)
// NewTaskViewController.textView.text = ""
}
}
This is my how to fetch data from firebase function.
func fetchTasks(uid : String,completion : #escaping([Task])-> Void) {
guard let uid = Auth.auth().currentUser?.uid else {return}
var tasks = [Task]()
Firestore.firestore().collection("tasks").document(uid).collection("ongoing_tasks").order(by: "timestamp").addSnapshotListener { snapshot, error in
if let err = error {
print(err)
}else {
if let snapShotDocument = snapshot?.documents {
for doc in snapShotDocument {
let data = doc.data()
tasks.append(Task(data: data))
print(data)
print(tasks)
completion(tasks)
TasksViewController.collectionView.reloadData()
}
}
}
}
}
This is my Task struct.
struct Task {
let tasksID : String
let text : String
let timestamp : Timestamp
init(data : [String : Any]) {
self.tasksID = data["taskId"] as? String ?? ""
self.text = data["text"] as? String ?? ""
self.timestamp = data["timestamp"] as? Timestamp ?? Timestamp(date: Date())
}
}
I'm using two get set for user and task.
var user : User? {
didSet {
configure()
}
}
private func configure() {
guard let user = self.user else {return}
TasksViewController.nameLabel.text = "Hi \(user.name)👋🏻"
fetchTasks()
}
private func fetchTasks() {
guard let uid = self.user?.uid else {return}
print(uid)
fetchTasks(uid: uid) { tasks in
print(uid)
TasksViewController.tasks = tasks
}
}
var task : Task? {
didSet {
configure()
}
}
private func configure() {
guard let task = self.task else {return}
TasksViewCell.textLabel.text = task.text
}
And this is how to present my tasks at my collection view.
static var tasks = [Task]()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return TasksViewController.tasks.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TasksViewController.reuseIdentifier, for: indexPath) as! TasksViewCell
cell.task = TasksViewController.tasks[indexPath.row]
return cell
}
So how can i solve this problem. Thanks for any help. Love y'all.

Updating data in the firebase

I'm trying to do small apps containing firebase codes to learn more about it. so here I made a todo list app, I was able to add the tasks to the firebase and I was able to delete it, the problem I have is updating the status of the task (isComplete: Bool) I've no idea how to write firebase code to update data. almost all the tutorial I read was about the data uploaded to real-time database and I'm using the cloud so I couldn't figure it out. here I wrote this code so when the task is done and I select the cell the circle turn into checkmark.circle It's work but of course the database isn't updated..
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TodoCell
if cell.isComplete == false{
cell.doneButton.image = UIImage(systemName: "checkmark.circle")
cell.isComplete = true
} else {
cell.doneButton.image = UIImage(systemName: "circle")
cell.isComplete = false
}
}
}
Adding tasks to firebase codes
public func postTask(task:String, isComplete: Bool,
completion: #escaping (Result<Bool, Error>) -> ()) {
guard let user = Auth.auth().currentUser else {
return
}
let documentRef = db.collection(DatabaseService.itemsCollection).document()
db.collection(DatabaseService.usersCollection).document(user.uid).
collection(DatabaseService.tasksCollection).
document(documentRef.documentID).setData(["task" : task,
"isComplete": isComplete,
"taskId": documentRef.documentID])
{ (error) in
if let error = error {
completion(.failure(error))
} else {
completion(.success(true))
}
}
}
SnapshotListener
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
guard let user = Auth.auth().currentUser else {
return
}
listener = Firestore.firestore().collection(DatabaseService.usersCollection)
.document(user.uid).collection(DatabaseService.tasksCollection)
.addSnapshotListener({ [weak self] (snapshot, error) in
if let error = error {
DispatchQueue.main.async {
self?.showAlert(title: "Try Again", message:
error.localizedDescription)
}
} else if let snapshot = snapshot {
let task = snapshot.documents.map { TasksList($0.data()) }
self?.todoItems = task
}
})
}
based on #bkbkchoy answer I wrote these codes:
func updateTask(task: TasksList,
isComplete: Bool,
completion: #escaping (Result<Bool, Error>) -> ()) {
guard let user = Auth.auth().currentUser else { return }
db.collection(DatabaseService.usersCollection).document(user.uid)
.collection(DatabaseService.tasksCollection).document(task.taskId)
.updateData(["isComplete": isComplete]) { (error) in
if let error = error {
completion(.failure(error))
} else {
completion(.success(true))
}
}
}
}
and under didSelectRow
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TodoCell
let isComplete = false
if task2.isComplete == false{
cell.doneButton.image = UIImage(systemName: "checkmark.circle")
cell.doneButton.tintColor = .systemBlue
cell.isComplete = true
} else {
cell.doneButton.image = UIImage(systemName: "circle")
cell.doneButton.tintColor = .systemGray
cell.isComplete = false
}
updateStatus(isComplete: isComplete)
}
private func updateStatus(isComplete: Bool) {
databaseService.updateTask(task: task2, isComplete: isComplete)
{ [weak self] (result) in
switch result {
case .failure(let error):
DispatchQueue.main.async {
self?.showAlert(title: "Try again", message: error.localizedDescription)
}
case .success:
break
}
}
}
}
but I got an error :
No document to update: project/todo-list/database/(default)/documents/users/jYZmghQeXodeF2/tasks/1
struct TasksList {
let task: String
let taskId: String
let isComplete: Bool
}
extension TasksList {
init(_ dictionary: [String: Any]) {
self.task = dictionary["task"] as? String ?? ""
self.taskId = dictionary["taskId"] as? String ?? ""
self.isComplete = dictionary["isComplete"] as? Bool ?? false
}
}
There are a couple of ways to update documents in Cloud Firestore:
Rewrite a specific property using setData:
db.collection(DatabaseService.usersCollection)
.document(user.uid)
.collection(DatabaseService.tasksCollection)
.document(task.taskId)
.setData(["isComplete": isComplete], merge: true)
Note: if you use setData, you must include merge: true to overwrite a single property on an existing document or else the whole document will be overwritten.
Use updateData
db.collection(DatabaseService.usersCollection)
.document(user.uid)
.collection(DatabaseService.tasksCollection)
.document(task.taskId)
.updateData(["isComplete": isComplete]) { err in
if let err = err {
print("error updating document: \(err)")
} else {
print("doc successfully updated")
}
}
Firestore has some great documentation online. If you want to learn more about updating/adding data here's a good place to start.
Your approach cannot work.
The cell is just the view, it shows the UI elements and their values, the data source is the model TasksList (why not simply Task).
Cells are reused and you will lose the isCompleted information in the cell when the user scrolls. You have to update the model and reload the view
First of all declare the model as Task and isComplete as variable. According to the naming guidelines task should be name or title and taskId should be just id
struct Task {
let task: String
let taskId: String
var isComplete: Bool
}
In cellForRow set the UI elements in the cell according to the model
let task = todoItems[indexPath.row]
let imageName = task.isComplete ? "checkmark.circle" : "circle"
cell.doneButton.image = UIImage(systemName: imageName)
cell.doneButton.tintColor = task.isComplete ? .systemBlue : .systemGray
In didSelect toggle isComplete in the model, reload the row and save the task
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
todoItems[indexPath.row].isComplete.toggle()
tableView.reloadRows(at: [indexPath], with: .none)
let task = todoItems[indexPath.row]
updateTask(task: task, isComplete: task.isComplete) { result in print(result) }
}
As the whole task is handed over, the second parameter isComplete is not needed in updateTask.

Bind Alamofire request to table view using RxSwift

So I have been researching RxSwift for a couple days, and am trying to create a simple app with it. I have bound the searchController of my table to the results, which feed into the cellForRowAt function. How do I bind the alamofire response to each cell?
Which of these do I need to do?
Use RxAlamofire to create an searchResultsArray
Change searchResultsArray to a Variable and use toObservable?
Bind response or searchResultsArray to create each cell.
The function I need to use is:
.bind(to: self.tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) { row, element, cell in
cell.textLabel?.text = "something"
}
This is my current RxSwift code:
let disposeBag = DisposeBag()
var searchResultsArray = [[String:String]]()
searchController.searchBar.rx.text.orEmpty.filter { text in
text.count >= 3
}.subscribe(onNext: { text in
searchRequest(search: text, searchType: "t:t") { response in
self.searchResultsArray = response
self.tableView.reloadData()
}
}).disposed(by: disposeBag)
This is my current cell creation function. showSearchResults changes when the cancel button is clicked.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else {
return UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
}
return cell
}()
if self.shouldShowSearchResults {
cell.textLabel?.text = searchResultsArray[indexPath.row]["result"]!
cell.detailTextLabel?.text = searchResultsArray[indexPath.row]["location"]!
}
return cell
}
This is my current api request:
func searchRequest(search: String, searchType: String, completionHandler: #escaping ([[String: String]]) -> ()) {
let payload: [String: Any] = [
"q": search,
"fq": searchType,
"start": 0
]
let url = URL(string: "https://www.athletic.net/Search.aspx/runSearch")!
Alamofire.request(url, method: .post, parameters: payload, encoding: JSONEncoding.default).responseJSON { response in
let json = response.data
do {
var searchResults: [[String: String]] = []
let parsedJson = JSON(json!)
if let doc = try? Kanna.HTML(html: parsedJson["d"]["results"].stringValue, encoding: .utf8) {
for row in doc.css("td:nth-child(2)") {
let link = row.at_css("a.result-title-tf")!
let location = row.at_css("a[target=_blank]")!
let schoolID = link["href"]!.components(separatedBy: "=")[1]
searchResults.append(["location": location.text!, "result": link.text!, "id":schoolID])
}
}
completionHandler(searchResults)
} catch let error {
print(error)
}
}
}
I would like to replace the cellForRowAt with a RxSwift solution.
Based on the code you presented, use of Rx will give you something like this:
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchBar.rx.text.orEmpty
.filter { text in text.count >= 3 }
.flatMapLatest { text in searchRequest(search: text, searchType: "t:t") }
.bind(to: self.tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) { row, element, cell in
if self.shouldShowSearchResults {
cell.textLabel?.text = element["result"]!
cell.detailTextLabel?.text = element["location"]!
}
}
.disposed(by: disposeBag)
}
The shouldShowSearchResults feels out of place in that. But otherwise it looks good.
The above assumes you wrap your searchRequest in a function that returns an observable like this:
func searchRequest(search: String, searchType: String) -> Observable<[[String: String]]> {
return Observable.create { observer in
searchRequest(search: search, searchType: searchType, completionHandler: { result in
observer.onNext(result)
observer.onCompleted()
})
return Disposables.create()
}
}
The above is a standard pattern that wraps a function that uses a callback into a function that returns an Observable.

Function does not return array. Download photos from Firebase Storage matching Firebase Database file names [duplicate]

This question already has answers here:
Returning data from async call in Swift function
(13 answers)
Closed 4 years ago.
I have images stored in FireBase Storage, and matching file name data in FireBase Database, and I want to get those photos and display them (note, there is still some code I need to write because I am not getting EVERY photo from storage. Just those that are returned from a query of the database)
Here is the git repo
This code in DBHandler works, as I can see the print of the image file names
func photoListForLocation() -> [String]{
let file_name:String = String()
var photos = [file_name]
ref.observeSingleEvent(of: .value) { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot]{
for snap in snapshot {
if let data = snap.value as? [String:Any]{
let imageName:String = data["image_name"]! as! String
photos.append(imageName)
print("photos.append - \(imageName)")
}//if let data
}//for
}//snapshot
}//ref.observeSingleEvent
return photos
}//photoListForLocation
BUT the "return photos" never happens.. So the following in my ViewController does nothing..
let dbHandler:DBHandler = DBHandler()
var fileList = [String]()
fileList = dbHandler.photoListForLocation()
fileList.forEach {fileName in
print("\(fileName)")
}
Of course, if there is a better or simpler way of accomplishing my goal, I'm all ears.
for Mr. Tomato... (see comments)
import Foundation
import FirebaseDatabase
import GoogleMaps
class DBHandler {
var ref:DatabaseReference! = Database.database().reference().child("locations")
var imageCount:Int = 0
func addLocation(coordinate:CLLocationCoordinate2D, rating: Double, imageName: String?){
let location = ["latitude": coordinate.latitude,
"longitude": coordinate.longitude,
"rating": rating,
"image_name": imageName!,
"postDate": ServerValue.timestamp()
] as [String : Any]
self.ref.childByAutoId().setValue(location)
}//end setLocation
func getImageListForLocation(lattitude:Double, longitude:Double) -> [String]{
var images = [String]()
self.ref.observeSingleEvent(of: .value) { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot]{
for snap in snapshot {
if let data = snap.value as? [String:Any]{
let thisLattitude = data["latitude"]
let thisLongitude = data["longitude"]
guard let imageName = data["image_name"] else {return}
if lattitude == thisLattitude as! Double && longitude == thisLongitude as! Double {
images.append(imageName as! String)
}//if
}//if
}//for
}//if
}//ref
self.imageCount = images.count
return images //DOES NOT RETURN IMAGES!! (FILE NAMES)
}//getImageListForLocation
}//DBHandler
In order to get the photos and display them, you need to store the Storage URL of the photo location in your database for later use. Here are a couple of functions I created for a project that does this.
This application has a list of Angels that it saves and retrieves. Angels have names, numbers, emails, and images. I store a local array of these angels in a datasource I've defined in PageDataSource.sharedInstance(). The boolean crudIsAvailable is to make sure there is a connection. On verifying that CRUD operations are available I being scrubbing the list of angelsToSave:
func saveAngels(_ completion: #escaping(_ error: Error?) -> Void) {
if PageDataSource.sharedInstance.crudIsAvailable == true {
let angelsRef = ref.child("angels")
let myAngelsRef = angelsRef.child(id)
for item in PageDataSource.sharedInstance.angelsToSave {
let angel = PageDataSource.sharedInstance.angels[item]
let angelNameRef = myAngelsRef.child(angel.name!)
var angelToSave = getAngel(angel)
var jpegRepresentation : UIImage? = nil
if let photo = angel.photo {
jpegRepresentation = photo
} else {
jpegRepresentation = UIImage(named: "Anonymous-Seal")
}
if let photoData = UIImageJPEGRepresentation(jpegRepresentation!, 1.0) {
storePhoto(photoData, angel.name!, completion: { (url, err) in
if err != nil {
print(err?.localizedDescription)
angelToSave["photo"] = nil
myAngelsRef.updateChildValues(angelToSave, withCompletionBlock: { (error, ref) in
if error != nil {
completion(error!)
} else {
completion(nil)
}
})
} else {
angelToSave["photo"] = url?.absoluteString
angelNameRef.updateChildValues(angelToSave)
completion(nil)
}
})
}
}
} else {
completion(NSError(domain: "Unavailable", code: 0, userInfo: nil))
}
}
The important part of saveAngels() is if let photoData..... storePhoto() and here is the storePhoto() function.
func storePhoto(_ photo: Data, _ name: String, completion: #escaping (_ result: URL?, _ error: NSError?) -> Void) {
let storageRef = Storage.storage().reference().child(name)
storageRef.putData(photo, metadata: nil) { (storageMetaData, err) in
if err != nil {
completion(nil, NSError(domain: (err?.localizedDescription)!, code: 0, userInfo: nil))
} else {
completion(storageMetaData?.downloadURL(), nil)
}
}
}
The function storePhoto() returns the value of the URL through a completion handler and the saveAngels() function takes that information and uses it to store the data to the realtime database for future use.
For a better understanding here is my Angel object:
class Angel: NSObject {
var name: String?
var email: [String]?
var phone: [String]?
var photo: UIImage?
var filepath: String?
}
And here is how I download the photo:
First, I retrieve the list of photo URLs to an array of "angels" in a datasource singleton on VC load then I load the images as they appear in a collectionView like this.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as! AngelCollectionViewCell
cell.imageView?.contentMode = .scaleAspectFill
cell.activityIndicator.hidesWhenStopped = true
cell.activityIndicator.startAnimating()
if let pic = PageDataSource.sharedInstance.angels[indexPath.row].photo {
cell.imageView?.image = pic
cell.activityIndicator.stopAnimating()
cell.setNeedsLayout()
} else if let imgURL = PageDataSource.sharedInstance.angels[indexPath.row].filepath {
Storage.storage().reference(forURL: imgURL).getData(maxSize: INT64_MAX, completion: { (data, error) in
guard error == nil else {
print("error downloading: \(error!)")
return
}
// render
let img = UIImage.init(data: data!)
// store to datasource
PageDataSource.sharedInstance.angels[indexPath.row].photo = img
// display img
if cell == collectionView.cellForItem(at: indexPath) {
DispatchQueue.main.async {
cell.imageView?.image = img
cell.activityIndicator.stopAnimating()
cell.setNeedsLayout()
}
}
})
} else {
// TODO: TODO: Change Image to a proper placeholder
cell.imageView.image = UIImage(contentsOfFile: "Angels#2x.png")
cell.Label.text = PageDataSource.sharedInstance.angels[indexPath.row].name!
cell.activityIndicator.stopAnimating()
}
return cell
}
The important code really starts with Storage.storage I hope this helps!!

Swift Tableview Refresh Error

I get this error:
This is my code:
I am using refresh in the tableView section of the project. What could be causing this error during the refresh?
But in which phase it falls to the fault I could not solve that part
var kategoriId = ""
var refresher = UIRefreshControl()
var arrayKonularData = [konularData]()
let singleton = konularClass.sharedGlobal
override func viewDidLoad() {
super.viewDidLoad()
refresher.attributedTitle = NSAttributedString(string: "Yükleniyor")
refresher.addTarget(self, action: #selector(KonuDetayViewController.refresh), for: UIControlEvents.valueChanged)
self.tableview.addSubview(refresher)
KonulariGetir(sirala: "order by tarih desc")
navigationController?.delegate = self
tableview.layer.cornerRadius = 10
}
func refresh()
{
DispatchQueue.main.async {
if self.segmentControl.selectedSegmentIndex == 0
{
self.arrayKonularData.removeAll()
self.KonulariGetir(sirala: "order by tarih desc")
}
if self.segmentControl.selectedSegmentIndex == 1
{
self.arrayKonularData.removeAll()
self.KonulariGetir(sirala: "order by indirimpuani desc")
}
}
DispatchQueue.main.async {
self.refresher.endRefreshing()
}
}
I am taking data from web service in this section
func KonulariGetir(sirala:String)
{
var request = URLRequest(url: URL(string:"http://212.xxx.xxx.xxx:7001/IndirimiKovala/KonuGetir")!)
request.httpMethod = "POST"
let postString = "filtre="+sirala
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil
{
print("error")
}
if let urlContent = data
{
do
{
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let gelenDizi = jsonResult as? NSArray
{
for i in 0..<gelenDizi.count
{
if let baslik = (gelenDizi[i] as? NSDictionary)?["baslik"] as? String
{
self.singleton.baslik = baslik
}
if let indirimPuani = (gelenDizi[i] as? NSDictionary)?["indirimpuani"] as? Int
{
self.singleton.indirimPuani = String(indirimPuani)
}
if let konuId = (gelenDizi[i] as? NSDictionary)?["id"] as? Int
{
self.singleton.konuId = String(konuId)
}
if let haberVeren = (gelenDizi[i] as? NSDictionary)?["uye"] as? String
{
self.singleton.haberVerenUye = haberVeren
}
if let gelenTarih = (gelenDizi[i] as? NSDictionary)?["tarih"] as? String
{
self.singleton.tarih = gelenTarih
}
if let gelenAktif = (gelenDizi[i] as? NSDictionary)?["aktif"] as? Int
{
self.singleton.aktif = gelenAktif
}
self.arrayKonularData.append(konularData.init(baslik: self.singleton.baslik, indirimPuani: self.singleton.indirimPuani, konuId: self.singleton.konuId,haberVeren:self.singleton.haberVerenUye , tarih:self.singleton.tarih,aktif:self.singleton.aktif))
}
}
DispatchQueue.main.async {
self.tableview.reloadData()
}
}
catch
{
print("server hatası")
}
}
}
task.resume()
}
I guess the problem comes from the part of code where you try to populate tableview. So the possible solution can be in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) delegate methode check if arrayKonularData array is not empty like this
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: orderCell, for: indexPath)
if !arrayKonularData.isEmpty {
.....// Your code
}
return cell
}
Another solution (which I thing will be the right solution in your case) add completion function of
func KonulariGetir(sirala:String)
and reload tableview in the completion method