How to get Firebase data as a model in swift? - swift

I am trying to get data from firebase and use it as a model that I created.
Here is my model;
class UserData{
var nickname : String = ""
var onesignal_player_id : String = ""
var step_count : Int = 0
var total_point : Int = 0
var competitions : [String:Competition] = [String:Competition]()
}
class Competition{
var end_date : String = ""
var gift : String = ""
var id: String = ""
var name: String = ""
var users : [String:Int] = [:]
}
and this is my function;
func getFirebaseData() {
ref = Database.database().reference()
ref.child("users").child("HXXNCXf6RRS4WVO12shZ3j15BnG3").observe(.value) { (snapshot) in
if let snapshotValue = snapshot.value as? Dictionary<String,Any> {
//change userData with the snapshotValue
self.userData.nickname = snapshotValue["nickname"] as! String
self.userData.step_count = snapshotValue["step_count"] as! Int
self.userData.total_point = snapshotValue["total_point"] as! Int
self.userData.onesignal_player_id = snapshotValue["onesignal_player_id"] as! String
self.userData.competitions = snapshotValue["competitions"] as! [String:Competition]
//reload UI with userData
print(self.userData.competitions)
} else {
print("An error occured while assigning snapshotValue to userData")
}
}
}
This code gave me error like this;
Could not cast value of type '__NSDictionaryM' (0x1f47ada20) to 'StepCounterApp.Competition' (0x1004c06f0).
2021-01-02 23:05:49.985711+0300 StepCounterApp[32511:3685645] Could not cast value of type '__NSDictionaryM' (0x1f47ada20) to 'StepCounterApp.Competition' (0x1004c06f0).
but when i comment out the line included self.userData.competitions from getFirebaseData function, everything works fine.
What should I do? How can I use firebase data as a model?
Finally here is my firebase data;

The problem is in your data model. Declare your model data like this
class UserData {
var nickname : String = ""
var onesignal_player_id : String = ""
var step_count : Int = 0
var total_point : Int = 0
var competitions : Competition = Competition()
}
class Competition{
var end_date : String = ""
var gift : String = ""
var id: String = ""
var name: String = ""
var users : [String:Int] = [:]
init() {
}
init(with dictionary: [String: Any]) {
self.end_date = dictionary["end_date"] as! String
self.gift = dictionary["gift"] as! String
self.id = dictionary["id"] as! String
self.name = dictionary["name"] as! String
self.users = dictionary["users"] as! [String:Int]
}
}
And inside the getFirebaseData funcation
self.userData.competitions = Competition(with: snapshotValue["competitions"] as! [String: Any])

The problem was in my data model and with the help of Raja Kishan's data model sugestion I fixed the problem.
First I changed the model little bit;
class UserData{
var nickname : String = ""
var onesignal_player_id : String = ""
var step_count : Int = 0
var total_point : Int = 0
var competitions : [String:Competition] = [String:Competition]()
}
class Competition{
var end_date : String = ""
var gift : String = ""
var id: Int = 0
var name: String = ""
var users : [String:Int] = [:]
init() {
}
init(with dictionary: [String: Any]) {
self.end_date = dictionary["end_date"] as! String
self.gift = dictionary["gift"] as! String
self.id = dictionary["id"] as! Int
self.name = dictionary["name"] as! String
self.users = dictionary["users"] as! [String:Int]
}
}
Than I add a childSnapshot to my method so I can work directly the "competitions";
func getFirebaseData() {
ref = Database.database().reference()
ref.child("users").child("HXXNCXf6RRS4WVO12shZ3j15BnG3").observe(.value) { [self] (snapshot) in
if let snapshotValue = snapshot.value as? [String:Any] {
//change userData with the snapshotValue
self.userData.nickname = snapshotValue["nickname"] as! String
self.userData.step_count = snapshotValue["step_count"] as! Int
self.userData.total_point = snapshotValue["total_point"] as! Int
self.userData.onesignal_player_id = snapshotValue["onesignal_player_id"] as! String
//******
//This part of the coded added for to solve the problem starting from here
let childSnap = snapshot.childSnapshot(forPath: "competitions")
if let childSnapValue = childSnap.value as? [String:Any] {
childSnapValue.forEach { (element) in
self.userData.competitions.updateValue(Competition(with: element.value as! [String:Any]), forKey: element.key)
}
} else {
print("something wrong with the childSnap")
}
//to here
//******
} else {
print("An error occured while assigning snapshotValue to userData")
}
}
}

Related

Change a value in my UserModel (class) based on a userid

I have a UserModel:
class UserModel {
var uid: String?
var username : String?
var email: String?
var profileImageUrl: String?
var dateOfBirth: String?
var registrationDate: Int?
var isFollowing: Bool?
var accessLevel: Int?
var onlineStatus: Bool?
init(dictionary: [String : Any]) {
uid = dictionary["uid"] as? String
username = dictionary["username"] as? String
email = dictionary["email"] as? String
profileImageUrl = dictionary["profileImageUrl"] as? String
dateOfBirth = dictionary["dateOfBirth"] as? String
registrationDate = dictionary["userRegistrationDate"] as? Int
accessLevel = dictionary["accessLevel"] as? Int
onlineStatus = dictionary["onlineStatus"] as? Bool
}
}
And I also have a value like [12ih12isd89 : True]
I want to change the value "onlineStatus" for the user "12ih12isd89" to True and I thought the right way to do this is updateValue(:forKey:). But my class UserModel does not have updateValue(:forKey:).
How can I use this in my existing model?
Edit:
How I get the data:
func fetchAllUsers (completion: #escaping ([UserModel]) -> Void) {
let dispatchGroup = DispatchGroup()
var model = [UserModel]()
let db = Firestore.firestore()
let docRef = db.collection("users")
dispatchGroup.enter()
docRef.getDocuments { (querySnapshot, err) in
for document in querySnapshot!.documents {
let dic = document.data()
model.append(UserModel(dictionary: dic))
}
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
completion(model)
}
}
To me it looks like you need to find the right object in the array and update the property
let dict = ["12ih12isd89" : true]
var model = [UserModel]()
if let user = model.first(where: {$0.uid == dict.keys.first!}) {
user.onlineStatus = dict.values.first!
}
Depending on what ["12ih12isd89" : true] really is you might want to change the access from dict.keys.first! that I used
If your value dictionary contains more than one user, you can use a for loop like this:
var model = [UserModel]()
//Some initalization ...
let values = ["12ih12isd89" : true]
for (k, v) in values {
model.filter({$0.uid == k}).first?.onlineStatus = v
}

How to Clear Shared Dictionary which is causing saved values not to clear even when I login with other user

How can I clear the shared dictionary on logout in which I am saving login response?
Here is the code I am doing on getting status 1.
if(status == 1)
{
DispatchQueue.main.async {
GAReusableClass.sharedInstance.hideActivityIndicator()
UserDefaults.standard.set(self.DataDict, forKey:MaindataKey)
let Dict = self.mainDict[KData] as! [String: AnyObject]
print("self.DataDict", self.DataDict)
let User_ID = Dict[KUuid]as! String
print(User_ID)
let HMACSECRETKEY = self.deviceToken + "+" + User_ID
kHMACKey = HMACSECRETKEY
let cipher:String = CryptoHelper.encrypt(input:HMACSECRETKEY)!;
print(HMACSECRETKEY)
UserDefaults.standard.setValue(cipher, forKey:HmacKey)
UserDefaults.standard.set(true, forKey: "isLogin")
GAloginUserInfo.shared.saveUserInfo(dict: Dict )
let tabar = self.storyboard?.instantiateViewController(withIdentifier: "GAtHomeTabbarViewController") as! GAtHomeTabbarViewController
self.navigationController?.pushViewController(tabar, animated: true)
}
Here is the shared dictionary which I am using to save the values of login response.
import UIKit
import Firebase
class GAloginUserInfo: NSObject {
var loginUserMobileNo : String?
var loginUserId : String?
var loginUserUuid : String?
var loginUserCountry : String?
var loginUserCountryCode : String?
var loginUserEmail : String?
var loginUserlatitude : String?
var loginUserLongitude : String?
var loginUserName : String?
var loginUserQrcode : String?
var loginUserProfilePic : String?
var isverify : String?
var loginPassword : String?
var dateOfBirth: String?
var earnedPoints:String?
var loginUserGender:String?
var loginUserFollowers:Int = 0
static let shared = GAloginUserInfo()
func saveUserInfo (dict : [String : AnyObject?] ) {
if let loginUserMobileNo = dict["mobile"] as? String {
self.loginUserMobileNo = loginUserMobileNo
}
if let loginUserId = dict["id"] as? String {
self.loginUserId = loginUserId
}
if let loginUserUuid = dict["uuid"] as? String {
self.loginUserUuid = loginUserUuid
print(loginUserUuid)
}
if let loginUserCountry = dict["country"] as? String {
self.loginUserCountry = loginUserCountry
}
if let loginUserCountryCode = dict["country_code"] as? String {
self.loginUserCountryCode = loginUserCountryCode
}
if let loginUserEmail = dict["email"] as? String {
self.loginUserEmail = loginUserEmail
}
if let loginUserProfilePic = dict["profile_pic"] as? String {
self.loginUserProfilePic = loginUserProfilePic
}
if let loginUserLongitude = dict["logitude"] as? String {
self.loginUserLongitude = loginUserLongitude
}
if let loginUserName = dict["name"] as? String {
self.loginUserName = loginUserName
}
if let loginUserQrcode = dict["qr_code"] as? String {
self.loginUserQrcode = loginUserQrcode
}
if let Password = dict["password"] as? String{
self.loginPassword = Password
}
if let dateOfBirth = dict["dob"] as? String{
self.dateOfBirth = dateOfBirth
}
if let earnedPoints = dict["points"] as? String{
let myDouble = Double(earnedPoints)
let doubleStr = String(format: "%.2f", myDouble!)
self.earnedPoints = doubleStr
}
if let loginUserGender = dict["gender"] as? String{
self.loginUserGender = loginUserGender
}
if let loginUserFollowers = dict["followersCount"] as? Int{
self.loginUserFollowers = loginUserFollowers
}
}
}
Actually, the problem is when I log out and log in again with some other user it still shows some values of the previous user. I am clearing the userdefaults on the logout function. but I don't know how to clear this type of shared dictionary.
Use removeObject(forKey:)
to remove the values stored from user defaults in Logout method
UserDefaults.standard.removeObject(forKey: MaindataKey)
UserDefaults.standard.removeObject(forKey: HmacKey)
UserDefaults.standard.set(false, forKey: "isLogin")
Create a method to remove the values from the singleton class like this
extension GAloginUserInfo {
func removeUserInfo() {
self.loginUserMobileNo = nil
self.loginUserId = nil
self.loginUserUuid = nil
self.loginUserCountry = nil
self.loginUserCountryCode = nil
self.loginUserEmail = nil
self.loginUserlatitude = nil
self.loginUserLongitude = nil
self.loginUserName = nil
self.loginUserQrcode = nil
self.loginUserProfilePic = nil
self.isverify = nil
self.loginPassword = nil
self.dateOfBirth = nil
self.earnedPoints = nil
self.loginUserGender = nil
self.loginUserFollowers = 0
}
}
and call this method in logout
GAloginUserInfo.shared.removeUserInfo()

Retrieve firebase data from swift

I'm trying to retrieve data from a Firebase RealTime database, in order to put it on a list which will be used to display data on a TableView.
My problem is that even if I get some data, I haven't enough knowledge to access on arrays and other swift objects. Perhaps, I'm not using the good way to do what I want.
Here is an example of a row on Firebase :
Here is a function written in Swift in which I'm trying to build a list for each row object.
func displayStationsUsingSearch(){
let station = self.stationName
let CP = Int(self.searchedCP!)
// create searchRef or queryRef you name it
let stationsRef = Database.database().reference().child("Stations")
stationsRef.observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
/*if snapshot.value is NSNull {
print("not found")
} else {
// yes we got the user
let id = snapshot.value as! Int
}*/
for child in snapshot.children {
stationsRef.queryOrdered(byChild: "marque")
.queryEqual(toValue: "TOTAL ACCESS")
.observe(.value, with: { snap in
if let dict = snap.value as? [String: AnyObject] {
/*self.stationItem!.nomStation = dict["nomStation"] as! String
self.stationItem!.adresse = dict["adresse"] as! String
self.stationItem!.codePostal = dict["codePostal"] as! String
self.stationItem!.ville = dict["ville"] as! String
self.stationItem!.marque = dict["marque"] as! String
self.stationItem!.pays = dict["pays"] as! String
self.stationItem!.commentaire = dict["commentaire"] as! String
self.stationItem!.coordGPS = dict["coordGPS"] as! String*/
print(dict["nomStation"] as! String)
}
})
}
})
}
The lldb on Xcode workspace displays that :
Printing description of child:
Snap (-LdA6X8CfNY3bsPni31U) {
"DIESEL EXCELLIUM" = 0;
"DIESEL ULTIMATE" = 0;
GAZOLE = 0;
GPL = 0;
SP95 = 0;
"SP95 E10" = 0;
SP98 = 0;
SUPER = 0;
adresse = "RN1 Direction Moisselles";
codePostal = 95570;
commentaire = "";
coordGPS = "";
createdAt = "31/07/2018";
heureDebut = "";
heureFin = "";
id = 0;
marque = ESSO;
modifiedAt = "23/04/2019 18:53";
nomStation = "ESSO Moisselles";
pays = "";
saufJour = "";
services = "";
typeRoute = "";
ville = Moisselles;
}
(lldb)
Could you please help me to retrieve data on a list that I could append to display data on tableview ? Thank you.
Try something like that:
Database.database().reference()
.child("Stations").
observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value as? [String: Any] else {
return
}
var stations = [Station]()
for (key, value) in values {
guard let station = value as? [String: Any],
let adresse = station["adresse"] as? String,
let codePostat = station["codePostat"] as? String else {
continue
}
stations.append(Station(adresse: adresse, codePostat: codePostat))
}
// if you have some completion return retrieved array of stations
completion(stations)
})
struct Station {
private let adresse: String
private let codePostat: String
init(adresse: String, codePostat: String) {
self.adresse = adresse
self.codePostat = codePostat
}
}
You can use a swift Class Instead.
Swift Object:
import Foundation
class FirebaseTransactionData : NSObject{
var customer : FirebaseTransactionDataCustomer!
var driver : FirebaseTransactionDataCustomer!
var status : String!
init(fromDictionary dictionary: [String:Any]){
status = dictionary["status"] as? String
if let customerData = dictionary["customer"] as? [String:Any]{
customer = FirebaseTransactionDataCustomer(fromDictionary: customerData)
}
if let driverData = dictionary["driver"] as? [String:Any]{
driver = FirebaseTransactionDataCustomer(fromDictionary: driverData)
}
}
}
class FirebaseTransactionDataCustomer : NSObject{
var lat : Double!
var longField : Double!
init(fromDictionary dictionary: [String:Any]){
lat = dictionary["lat"] as? Double
longField = dictionary["lng"] as? Double
}
}
Firebase Method
ref.observe(DataEventType.value, with: { (snapshot) in
let value = snapshot.value as? [String:Any]
let datt = FirebaseTransactionData(fromDictionary: value!)
print("snapshot \(datt.status!)")
print("snapshot \(datt.customer.lat!)")
})

UITableView Null Value

I have a list of JSON data downloaded from server:
(DataModal.swift)
class DataModal {
var orderAutoid: Int?
var orderId: String?
var orderName: String?
var orderQty: String?
var orderStatus: String?
init(bOrder_autoid: Int, bOrder_id: String, bOrder_name: String, bOrder_qty: String, bOrder_status: String){
self.orderAutoid = bOrder_autoid
self.orderId = bOrder_id
self.orderName = bOrder_name
self.orderQty = bOrder_qty
self.orderStatus = bOrder_status
}
(OrderStructureDownloadProtocol.swift)
protocol OrderStructureDownloadProtocol: class {
func newItemDownload(items: Array<Any>)
}
....
var jsonElement = Dictionary<String, Any>()
var newOrders = Array<Any>()
for i in 0..<jsonResult.count {
jsonElement = jsonResult[i] as! Dictionary
let newOrder_autoid = jsonElement["orderAutoid"] as? Int ?? 0
let newOrder_id = jsonElement["orderId"] as? String ?? ""
let newOrder_name = jsonElement["orderName"] as? String ?? ""
let newOrder_qty = jsonElement["orderQty"] as? String ?? ""
let newOrder_status = jsonElement["orderStatus"] as? String ?? ""
let newOrder = BMSDataModal(bOrder_autoid: newOrder_autoid, bOrder_id: newOrder_id, bOrder_name: newOrder_name, bOrder_qty: newOrder_qty, bOrder_status: newOrder_status)
newOrders.append(newOrder)
}
DispatchQueue.main.async (
execute: { () -> Void in
self.delegate.newItemDownload(items: newOrders as! Array<Any>)
})
(tableview.swift)
var newOrdersArray = [BMSDataModal]()
func newItemDownload(items: Array<Any>) {
newOrdersArray = items as! [BMSDataModal]
newOrderLookupTableView.reloadData()
}
(tableview.swift another part)
let cell = tableView.dequeueReusableCell(withIdentifier: "orderLookupCell", for: indexPath) as! NewOrderTableViewCell
let item = newOrdersArray[indexPath.row]
cell.newHMNumber?.text = item.orderId ?? "-"
cell.newMP?.text = item.orderName ?? "-"
cell.newQTY?.text = item.orderQty ?? "-"
return cell
}
having all the old NS-style changed. The app is running okay, there are some items that need to reset. As my data-source always contain Double, but I declared it as a String, as I won't deal with calculation so I treated it as 'String'.

Table view stucking a lot

I am using a tableView to show text only. Inside cell, I am using a UITextView with dynamic height and linkDetection with html text converted to attributedString.
I am parsing the html text to attributed text inside my model class below way:
if let nodeValue = dict["blurb_link"]{
blurb_link = nodeValue as? String
let attrString = NSMutableAttributedString(attributedString: (blurb_link?.html2AttributedString)!)
atr_blurb_link = attrString
}
html2AttributedString in an extension of String which returns an attributedString from html text.
I am populating my cell inside cell subclass via below way,
textViewBlurbLink.attributedText = model.atr_blurb_link
But the problem that is happening is, whenever a new cell is loaded, the tableview stucks for a fraction of second which make the tableView scrolling a bit jerky and disturbing to user.
There are no images, no videos no heavy task inside cell which can cause a jerky scroll. Please tell me what could be possible reason of this jerky and hiccup scrolling?
EDIT:
The layout of my cell is:
After getting response I have populated tableView below way:
TSNetworkManager.getDataFor(Request: dataRequest, success: {response in
//print(response.responseObject!)
let model = TSLatestModel.init(WithDictionary: response.responseObject as? [String : Any])
completion(model)
tblLatest.reloadData()
}, failure: {error in
onError(error)
})
and inside cellForRowAtIndexPath
let modelLatestDetails = model?.data![indexPath.section].items![indexPath.row]
cell.setupCellData(model: modelLatestDetails!)
Inside the setupCellData in tableViewCell subclass I am setting the text into textView.
EDIT2:
This the total codebase of my model class
class TSLatestModel: TSModelBase {
var data : [LatestListModel]?
override init(WithDictionary dictionary: [String : Any]?) {
super.init(WithDictionary: dictionary)
if let dict = dictionary{
if let nodeValue = dict["data"] {
data = [LatestListModel]()
for latest in nodeValue as! [Any]{
let model = LatestListModel.init(WithDictionary: latest as? [String:Any])
data?.append(model)
}
}
}
}
}
class LatestListModel: NSObject {
var storyname : String?
var main_title : String?
var color : String?
var issuedate : String?
var formatted_issue_date : String?
var id : String?
var cat_name : String?
var cat_id : String?
var order : Int?
var items : [TSLatestDetailsModel]?
var itemsModified : [TSLatestDetailsModel]?
init(WithDictionary dictionary: [String : Any]?) {
super.init()
if let dict = dictionary {
if let nodeValue = dict["items"] {
items = [TSLatestDetailsModel]()
itemsModified = [TSLatestDetailsModel]()
for item in nodeValue as! [Any] {
let model = TSLatestDetailsModel.init(WithDictionary: item as? [String : Any])
items?.append(model)
if !((item as! [String : Any])["one_liner"] as! String).isEmpty {
let filteredArray = itemsModified?.filter({$0.one_liner == ((item as! [String : Any])["one_liner"] as! String)})
if filteredArray?.count == 0 {
let model = TSLatestDetailsModel.init(WithDictionary: item as? [String : Any])
itemsModified?.append(model)
}
}
}
}
if let nodeValue = dict["item_list"] {
items = [TSLatestDetailsModel]()
itemsModified = [TSLatestDetailsModel]()
for item in nodeValue as! [Any] {
let model = TSLatestDetailsModel.init(WithDictionary: item as? [String : Any])
items?.append(model)
if !((item as! [String : Any])["one_liner"] as! String).isEmpty {
let filteredArray = itemsModified?.filter({$0.one_liner == ((item as! [String : Any])["one_liner"] as! String)})
if filteredArray?.count == 0 {
let model = TSLatestDetailsModel.init(WithDictionary: item as? [String : Any])
itemsModified?.append(model)
}
}
}
}
if let nodeValue = dict["_id"] {
storyname = nodeValue as? String
}
if let nodeValue = dict["order"] {
order = nodeValue as? Int
}
if let nodeValue = dict["category"] {
cat_id = (nodeValue as! [Any])[0] as? String
}
if let dictStoryType = dict["_id"] as? [String : Any] {
if let nodeValue = dictStoryType["issuedate"] {
issuedate = nodeValue as? String
}
if let nodeValue = dictStoryType["formated_issue_date_title"] {
formatted_issue_date = nodeValue as? String
}
if let nodeValue = dictStoryType["id"] {
id = nodeValue as? String
}
if let nodeValue = dictStoryType["category_name"] {
cat_name = nodeValue as? String
}
}
if let nodeValue = dict["name"] {
storyname = nodeValue as? String
}
if let nodeValue = dict["story"] {
storyname = nodeValue as? String
}
if let nodeValue = dict["main_title"] {
main_title = nodeValue as? String
}
if let nodeValue = dict["color"] {
color = nodeValue as? String
}
}
}
}
class TSLatestDetailsModel: NSObject {
var __v : Int?
var _id : String?
var title : String?
var topic_key : String?
var blurb : String?
var blurb_link : String?
var atr_blurb_link : NSMutableAttributedString?
var formated_issue_date : String?
var formated_issue_date_item : String?
var formated_issue_date_title : String?
var issue_link : String?
var issue_title : String?
var issue_date : String?
var one_liner : String?
var main_title : String?
var source : String?
var source_link : String?
var isActive : Bool?
var isDeleted : Bool?
var isfavourite : Bool?
var story_order_number : Int?
var story_type : String?
var categories : [String]?
var story_type_model : TSStoryTypeDetailsModel?
var favourite_category_id : String?
init(WithDictionary dictionary: [String : Any]?) {
super.init()
if let dict = dictionary{
if let nodeValue = dict["__v"]{
__v = nodeValue as? Int
}
if let nodeValue = dict["_id"]{
_id = nodeValue as? String
}
if let nodeValue = dict["title"]{
title = nodeValue as? String
}
if let nodeValue = dict["topic_key"]{
topic_key = nodeValue as? String
}
if let nodeValue = dict["blurb"]{
blurb = nodeValue as? String
}
if let nodeValue = dict["blurb_link"]{
blurb_link = nodeValue as? String
let attrString = NSMutableAttributedString(attributedString: (blurb_link?.html2AttributedString)!)
atr_blurb_link = attrString
}
if let nodeValue = dict["formated_issue_date"]{
formated_issue_date = nodeValue as? String
}
if let nodeValue = dict["issue_date"]{
issue_date = nodeValue as? String
}
if let nodeValue = dict["issue_link"]{
issue_link = nodeValue as? String
}
if let nodeValue = dict["issue_title"]{
issue_title = nodeValue as? String
}
if let nodeValue = dict["one_liner"]{
one_liner = nodeValue as? String
}
if let nodeValue = dict["main_title"]{
main_title = nodeValue as? String
}
if let nodeValue = dict["source"]{
source = nodeValue as? String
}
if let nodeValue = dict["source_link"]{
source_link = nodeValue as? String
}
if let nodeValue = dict["isActive"]{
isActive = nodeValue as? Bool
}
if let nodeValue = dict["isfavourite"]{
isfavourite = nodeValue as? Bool
}
if let nodeValue = dict["story_order_number"]{
story_order_number = nodeValue as? Int
}
if let nodeValue = dict["story_type"]{
story_type = nodeValue as? String
}
if let nodeValue = dict["formated_issue_date_title"]{
formated_issue_date_title = nodeValue as? String
}
if let nodeValue = dict["formated_issue_date_item"]{
formated_issue_date_item = nodeValue as? String
}
if let nodeValue = dict["favourite_category_ids"] {
if (nodeValue as! [String]).count > 0 {
favourite_category_id = (nodeValue as! [String])[0]
}
}
if let nodeValue = dict["story_type"] {
let model = TSStoryTypeDetailsModel.init(WithDictionary: nodeValue as? [String : Any])
story_type_model = model
}
if let nodeValue = dict["category"] {
categories = [String]()
for category in nodeValue as! [String] {
categories?.append(category)
}
}
}
}
}
The cellForRowAtIndexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TSArchiveDetailsCell") as! TSArchiveDetailsCell
cell.delegate = self
if !((favoriteDetilsModel?.data![indexPath.section].items![indexPath.row].source!.isEmpty)!) {
cell.viewFav.isHidden = false
} else {
if favoriteDetilsModel?.data![indexPath.section].storyname?.lowercased() == "brush up" {
cell.viewFav.isHidden = false
} else {
cell.viewFav.isHidden = true
}
}
if isSayItOnRounds {
let modelLatestDetails = favoriteDetilsModel?.data![indexPath.section].items?.filter({$0._id! == selectedItemId})[0]
cell.setupCellData(model: modelLatestDetails!)
} else if isBrushUp {
let thirdBrushUpItemModel = favoriteDetilsModel?.data![indexPath.section].items![2]
if thirdBrushUpItemModel?._id == selectedItemId {
let modelLatestDetails = favoriteDetilsModel?.data![indexPath.section].items?.filter({$0._id == selectedItemId})
cell.setupCellData(model: modelLatestDetails![0])
} else {
let modelLatestDetails = favoriteDetilsModel?.data![indexPath.section].items![indexPath.row]
cell.setupCellData(model: modelLatestDetails!)
}
} else {
let modelLatestDetails = favoriteDetilsModel?.data![indexPath.section].items![indexPath.row]
cell.setupCellData(model: modelLatestDetails!)
}
return cell
}
Possible problems:
Cell layout. I need to see, how do you make layout and reuse cell.
Parsing data and drawing cells at the same time.
You need to create all data before (tableView.datasource = self or tableView.reloadData()). So, your [AttributedString] must be ready before reloading tableView. Do not parse data in cellfoRowAtIndexPath.
Also, check that tableView call cellfoRowAtIndexPath only one time for each cell during cell lifetime.