chirag shah chirag shah - 1 year ago 76
iOS Question

Predicate on optional value in swift not working

I am try to predicate on the optional value and it always crash the application with following error.

* Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key q_id.'
First throw call stack:

Although there is variable define in the model but it is define like this

var q_id : Int!

If i convert this variable in unwrap it workings fine

var q_id = Int()

So is there any other way for predicate on optional value?

let Qid = dictData.objectForKey("q_id") as? String
let fQuesID : Int = Int(Qid!)!;

let predicate = NSPredicate(format: "SELF.q_id == %i",fQuesID)
let arrObj : NSArray = arrData.filteredArrayUsingPredicate(predicate) ;
//arrData.filter { predicate.evaluateWithObject($0) }
if(arrObj.count > 0)
let objPostModel : ViewPostModel = arrObj.firstObject as! ViewPostModel;
objPostModel.isPollExpired = 1; // 1 Means Poll Expired!

It is only happened in primitive types variable (int,float,etc ... )

Answer Source

I assume dictData is an NSDictionary containing String value for key "q_id", arrData is an NSArray which contains only ViewPostModel. And in the class ViewPostModel, q_id is a property of type Int?.

With all those given, you can write your code in some more Swifty way:

    if let
        qId = dictData["q_id"] as? String,
        fQuesID = Int(qId)
        let arrObj = (arrData as! [ViewPostModel]).filter{$0.q_id == fQuesID}
        if let objPostModel = arrObj.first {
            objPostModel.isPollExpired = 1  // 1 Means Poll Expired!
    } else {
        print("invalid q_id in dictData")

(With declaring your arrData as [ViewPostModel], you will have no need to use dangerous as! operator. You can make some other parts more Swifty.)

Generally, if you are using NSPredicate only to filter an array, better use Swift filter method and closure.