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
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 }
}