0

i am new to swift, currently practicing

here i have a plist file, which has an Array Of Dictionaries, each dictionary has one string, the plist has 3 records, it looks like this

item 0:
kurdi: Googlee

item 1:
kurdi: Yahooe

item 2:
kurdi: Binge

here's a image for the plist; Screenshot 11:52AM

okay so the point is, when a user searches for oo for example two of the records contain oo, such as google and yahoo, i want to return an array of results,

for that case i used:

let path = Bundle.main.path(forResource:"hello", ofType: "plist")
let plistData = NSArray(contentsOfFile: path!)
let objCArray = NSMutableArray(array: plistData!)

 if let swiftArray = objCArray as NSArray as? [String] {

     let matchingTerms = swiftArray.filter({
      $0.range(of: "oo", options: .caseInsensitive) != nil // here
        })
        print(matchingTerms)

    }

but unfortunately, when i print matchingTerms it returns nil .. thanks

0

2 Answers 2

2

If you are new to Swift please learn first not to use NSMutable... Foundation collection types in Swift at all. (The type dance NSArray -> NSMutableArray -> NSArray -> Array is awful). Use Swift native types. And instead of NSArray(contentsOfFile use PropertyListSerialization and the URL related API of Bundle.

All exclamation marks are intended as the file is required to exist in the bundle and the structure is well-known.

let url = Bundle.main.url(forResource:"hello", withExtension: "plist")!
let plistData = try! Data(contentsOf: url)
let swiftArray = try! PropertyListSerialization.propertyList(from: plistData, format: nil) as! [[String:String]]
let matchingTerms = swiftArray.filter({ $0["kurdi"]!.range(of: "oo", options: .caseInsensitive) != nil })
print(matchingTerms)
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks vadian. so helpful
how to solve this in swift 4.0 It's crashing. let predicate = NSPredicate(format: "status = %@", DeviceUserStatus.New.rawValue) let sortedResults1 = (deviceUsers as NSArray).filtered(using: predicate) as NSArray, It's works fine in swift 3.3. swift 4.0 Crash says : valueForUndefinedKey:]: this class is not key value coding-compliant for the key status.
@JamshedAlam Don't use NSArray in Swift. The native filter method is more convenient. In Swift 4 you have to mark all properties as @objc when using NSObject - KVC.
My array is deviceUsers , declared like : var deviceUsers = [EDeviceUser](). Should i declare it with : @objc var deviceUsers = [EDeviceUser]() ? And then use the filtered(using: predicate) ?
@JamshedAlam No, please read the error message ... for the key status. The property status must be marked as @objc. Please read also SE-0160 Limiting @objc inference
|
0

Cast swift array to [[String:Any]] not [String]. And in filter you need to check the value of the key kurdi. Try this.

if let swiftArray = objCArray as? [[String:Any]] {
    let matchingTerms = swiftArray.filter { (($0["kurdi"] as? String) ?? "").range(of: "oo", options: .caseInsensitive) != nil }
    print(matchingTerms)
}

2 Comments

If all dictionary values are String cast to [[String:String]], not [[String:Any]].
@vadian Yes If all dictionary values are String.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.