Sameeh Ahmed
Sameeh Ahmed

Reputation: 95

Classes or Structs for Models in Swift


I want to implement IgListKit for my UICollectionView. This Library requires me to use “Class Model : ListDiffable”

Accoding to my current architecture I have “Struct Model : Decodable” As I use JSON Decoder in my NetworkService to retrieve Data I have 2 struct, 1 for the Root and the 2 for my Array.

struct Talents : Decodable {
    let status : String?
    let error : String?
    let response : String?
}

struct Talent: Decodable {
  let id: String
  let name : String
  let smallDesc: String
  let largeDesc : String
}
\\I also have enum CodingKeys to match the keys for both structs

Following is the Struct output ,Works well to be used in my UICollectionView

when I change these structs to class

class Talents : Decodable {
    var status : String?
    var error : String?
    var response : String?
init( status : String,error : String, response : String){
    self.status = status
    self.error = error
    self.response = response
}
}

This is the Class Output I get, Which I am not sure how to use.

What are the changes I should make in order to resolve this, and apply : ListDiffable Protocol stubs to my Model class?

Service File with the instance of which in viewDidLoad of my CollectionVC I take the Data in an array.

    static func getCategoryTalents(category:String,completion: @escaping (Bool, [Talent]?, Error?) -> Void) {

        let parameters: Parameters = [
            "filter": category,
            "shuffle": 1
        ]

        AF.request(Constants.baseUrl,
                   parameters : parameters ).response { response in
                    guard let data = response.data else {
                        DispatchQueue.main.async {
                            print("\(Error.self)")
                            completion(false, nil, Error.self as? Error)
                        }

                        return}
                    do {

                        let talentsResponse = try JSONDecoder().decode(Talents.self, from: data)
                        print(talentsResponse)

                        let firstJSONString = talentsResponse.response?.replacingOccurrences(of: "\\", with: "")
                        let secondJSONString = firstJSONString?.replacingOccurrences(of: "\"{", with: "{").replacingOccurrences(of: "}\"", with: "}")

                        guard let talentArray = try! JSONDecoder().decode([Talent]?.self, from: (secondJSONString?.data(using: .utf8)!)!) else {
                            return }
                        print(talentArray)
                        var talents = [Talent]()
                        for talent in talentArray {
                            guard let individualTalent = talent as Talent? else { continue }
                            talents.append(individualTalent)
                        }

                        DispatchQueue.main.async {
                            completion(true, talents, nil)
                        }

                    } catch {
                        DispatchQueue.main.async {
                            completion(false, nil, error)
                        }
                    }

        }
    }

Upvotes: 0

Views: 1303

Answers (2)

Sameeh Ahmed
Sameeh Ahmed

Reputation: 95

Since it is a whole lot of work to make serve Models with srtucts as seen here

I changed my class to make it work with IGListKit.

import Foundation
import IGListKit


class Talents: NSObject,Decodable {
    let status : String
    let error : String
    let response : String

    init(status:String,error:String,response:String) {
        self.status   = status
        self.error    = error
        self.response = response
    }

}
extension NSObject: ListDiffable {
  public func diffIdentifier() -> NSObjectProtocol {
    return self
  }

  public func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
    return isEqual(object)
  }
}

Upvotes: 0

Frankenstein
Frankenstein

Reputation: 16341

You don't need to change the existing struct to class create a new class and make an initializer which accepts struct as the parameter:

struct TalentDataModel: Decodable {
    let status : String?
    let error : String?
    let response : String?
}
class Talents: Decodable {
    var status : String?
    var error : String?
    var response : String?

    init(dataModel: TalentDataModel) {
        status   = dataModel.status
        error    = dataModel.error
        response = dataModel.response
    }
}

Upvotes: 0

Related Questions