StuartM
StuartM

Reputation: 6823

Mapping Dictionary to custom object for TableView

We have a custom Plist which contains data for a bunch of fields we are adding to a tableView. The layout is like this:

Root Array
-- Section (Array)
--- Field (Dictionary)
---- FieldName
---- HasError
---- FieldType
--- Field (Dictionary)
---- FieldName
---- HasError
---- FieldType

There are multiple sections, with multiple fields in each. Each field is a dictionary, which we will later map to a custom object type. For example 'FieldObject'.

I understand we can create a custom initWithDictionary method on the 'FieldObject' to create a model object from each dictionary.

At the moment we get the relevant data like this:

 let tvDataPath = NSBundle.mainBundle().pathForResource("CandRegisterFields", ofType: "plist")
self.tableViewData = NSArray.init(contentsOfFile: tvDataPath!)

What we want to do is map all the dictionaries for the fields into the custom model object, then add them back into original NSArray data as the new object type in the same index etc. Is there a quick/easy way to do this?

Upvotes: 0

Views: 913

Answers (1)

beyowulf
beyowulf

Reputation: 15331

Why do you want to want to place your objects back into an NSArray wouldn't it be better to convert from cocoa objects into native swift collection types so you can use a struct rather than a class for your Field object?

For example:

struct Field
{
    let fieldName: String
    let hasError: Bool
    let fieldType: String //Should actually most likely be an enum
}

extension Field
{
    init?(dictionary: NSDictionary?)
    {
        guard let dictionary = dictionary, let fieldName = dictionary["FieldName"] as? String else { return nil }
        let hasError = dictionary["HasError"] as? Bool ?? false
        let fieldType = dictionary["FieldType"] as? String ?? ""
        self.init(fieldName: fieldName, hasError: hasError, fieldType: fieldType)
    }
}

Create a struct for your Field object. Have some init method that converts an NSDictionary into a Field.

var sectionsArray = [[Field]]()
for array in plistArray
{
    guard let array = array as? NSArray else { continue }
    let section = array.flatMap { Field(dictionary: $0 as? NSDictionary) }
    sectionsArray.append(section)
}

Iterate over the sections in your plist. Each of those sections is an array of dictionaries. You can map each of those dictionaries to a Field so your [NSDictionary] is mapped to a [Field]. You can then add that array to another array to retain the initial structure of the data.

Upvotes: 3

Related Questions