Search code examples
iosarraysswiftxcodeplist

Retrieving multiple rows from plist


I have some code data which is in my plist. I am trying to read that in using Xcode. Basically I want to retrieve multiple rows which satisfy a given condition

I am able to retrieve only 1 row using the following code: but I am not able retrieve more than 1 row. For example I have the following rows

Lodging col1 col2 col3 1. a. b. c 1. d. e. f

print(getDateForDate(date: "1"))

func getSwiftArrayFromPlist(name: String) -> (Array<Dictionary<String,String>>)
        {
        let path = Bundle.main.path(forResource: name, ofType: "plist")
        var arr : NSArray?
        arr = NSArray(contentsOfFile: path!)
        return(arr as? Array<Dictionary<String,String>>)!
    }
    func getDateForDate(date: String) -> (Array<[String:String]>)
    {
        let array = getSwiftArrayFromPlist(name: "file")
        let namePredicate = NSPredicate(format: "Lodging = %@", date)
        return [array.filter{namePredicate.evaluate(with: $0)}[0]]
    }

The above code is able to retrieve row 1 but not row 2. I want to extract all rows which match the condition. Not just one


Solution

  • First of all you are discouraged from reading plists with the NSArray or NSDictionary API. Use PropertyListSerialization or better deserialize the property list into structs with the Codable protocol.

    func getSwiftArrayFromPlist(name: String) -> [[String:String]]
    {
        let url = Bundle.main.url(forResource: name, withExtension: "plist")!
        let data = try! Data(contentsOf: url)
        return try! PropertyListSerialization.propertyList(from: data, format: nil) as! [[String:String]]
    }
    

    Your predicate filters the array and returns the first object [0], change the line to

    return array.filter{namePredicate.evaluate(with: $0)}
    

    The NSPredicate in redundant, in Swift you can filter directly. And the parentheses around the return type are redundant, too

    func getDateForDate(date: String) -> [[String:String]]
    {
        let array = getSwiftArrayFromPlist(name: "file")
        return array.filter{ $0["Lodging"]! == date }
    }