'Unable to parse the format string "claimID != '' & userID = %#"' - ios

I am trying to write a NSPredicate to fetch userID and claimID and I am getting the below error.
Terminating app due to uncaught exception NSInvalidArgumentException', reason: 'Unable to parse the format string "claimID != '' & userID = %#"'
My Code is-
+(NSArray*)fetchNotificationsWithPredicate {
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"claimID != '' & userID = %#",[[NSUserDefaults standardUserDefaults] objectForKey:#"usernmae"]];
NSLog(#"%#",[self fetchNotifications]);
NSArray *loginUsers = [DBUtils createAndExecuteFetchRequestWithPredicate:#"Notification" predicate:predicate];
return loginUsers;
}

Looking at the predicate string format, it looks like & isn't a valid operator. You either want AND or &&. So:
#"claimID != '' && userID = %#"
or
#"claimID != '' AND userID = %#"
(This may well not be the only issue. I've never used this API, and I'm not an iOS developer. This is just from inspection of the documentation...)

Rewrite your predicate:
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"claimID != '' AND userID MATCHES %#",[[NSUserDefaults standardUserDefaults] objectForKey:#"usernmae"]];
Note: for number matching use '=' and for string matching use 'MATCHES'

Related

How to query for String AND NSDate property?

I am facing an odd error with my code:
if let date = self.messages.last?.date {
let newMessages = self.realm.objects(Message).filter("chatId == '\(self.chatId!)' AND date > \(date)")
}
This outputs the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "chatId = 'oSgUGWH9fWURmBh5NQZK2POpxdI3yEdl7PrPzAU33l7cVFIpzR38otF3' AND date > 2016-07-17 10:56:07 +0000"'
What am I doing wrong?
EDIT:
Using NSPredicate it works:
let predicate = NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date)
newMessages = self.realm.objects(Message).filter(predicate)
But why doesn't the first solution work?
If you want to filter an array using a predicate, you need to pass a predicate and not just a string literal as the argument, and also use the method filteredArrayUsingPredicate(_:).
Why "chatId == '\(self.chatId!)' AND date > \(date)" doesn't work is that the compiler interprets this as a string literal - and not a predicate as you've created in your other example:
NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date)
The fix is to either instantiate an NSPredicate as you've done in your edit, and pass that value to filteredArrayUsingPredicate(:_) or just move the instantiation to inside the method:
newMessages = self.realm.objects(Message).filteredArrayUsingPredicate(NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date))
If you want to use this method, the array needs to be an NSArray, and the objects in the array need to be KVC compliant, so you're better off in Swift with using the filter(_:) method as such:
let newMessages = self.realm.objects(Message).filter({ $0.chatId == self.chatId! && $0.date.compare(date) == NSComparisonResult.OrderedDescending })

How to concatenate two column values and compare in ios

In my entity Contact, I have two columns named firstName & lastName. I want to search for a name entered by user in my DB.
For Eg: If user enters only 'William' I can search either its present in first name or last name and show the result.
If the user enters 'William Smith', then I want to get both first name and last name from DB and compares it with search text.
For this i want to use NSPredicate that compares 3 condition:
firstName contains the search text OR
lastName contains the search text OR
firstName+lastName contains the search text.
I used the following predicate for that:
NSString *strSearchType = #"(%# CONTAINS[cd] '%#' OR %# CONTAINS[cd] '%#' OR (%# || %# CONTAINS[cd] '%#')";
I know "||" is the concatenate operator.
But it gives me the following exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "(firstName CONTAINS[cd] 'rus' OR lastName CONTAINS[cd] 'rus' OR ((firstName || lastName) CONTAINS[cd] 'rus'))"'
Am i doing anything wrong ?
You can try following :
firstName contains the search text OR
lastName contains the search text OR
(search text contains the firstName AND search text contains the lastName).
NSString* stringA=nil; NSString* stringB=nil;
// this would give array of string separated by space
NSArray *searchStrArray = [searchString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" "]];
if (searchStrArray.count>0) {
stringA=[searchStrArray objectAtIndex:0];
}
if (searchStrArray.count>1) {
stringB=[searchStrArray objectAtIndex:1];
}
NSPredicate* predicateA= [NSPredicate predicateWithFormat:#“firstName CONTAINS[c] %# OR lastName CONTAINS[c] %#",stringA , stringA];
NSPredicate* resultPredicate=predicateA;
if(stringB){
NSPredicate* predicateB= [NSPredicate predicateWithFormat:#“firstName CONTAINS[c] %# OR lastName CONTAINS[c] %#",stringB , stringB];
resultPredicate=[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:resultPredicate,predicateB, nil]];
}

swift NSPredicate compare string

In the twitter api, the id_str is like this: "572581876033982465".
Right now I want to use NSPredicate to filter the tweets, and the current format is like this:
NSPredicate(format: "idStr > %#", self.maxId!)
Both idStr and self.maxId are type of String. And it crashes with error message: "Operator type 2 not supported for string type".
I think it means that I should cast both of them to number value.
I tried this:
let predicate = NSPredicate(format: "[idStr intValue] > %#", self.maxId!.toInt()!)
But it crashes with error:
Unable to parse the format string "[idStr intValue] > %#
How to cast the id_str in the format?
Have you tried this:
let id_str = "572581876033982465"
let id_num = id_str.toInt()!
var predicate = NSPredicate(format: "id_num > %#", self.maxId!.toInt()!)

how to solve NSPredicate error 'Can't use in/contains operator with collection 8 (not a collection)

I tried to predicate my coredate based on the mood on the initial queries all the moods are set to 8.
I will be calling from 0 - 7 every sec to update the tableview.
but I got
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't use in/contains operator with collection 8 (not a collection)'
Should I use CONTAINS or other operator to predicate?
NSString* filter = #"%K CONTAINS[cd] %#";
NSPredicate *getMoodPred = [NSPredicate predicateWithFormat:filter, #"mood", mood];
NSLog(#"getmood %#",getMoodPred); //getmood mood CONTAINS[cd] "7"
NSArray *getMoodArray = [[VPPCoreData sharedInstance]allObjectsForEntity:#"Song" orderBy:Nil filteredBy:getMoodPred];
The probably means that the mood attribute is stored as Number, not as String. "CONTAINS" works only with strings. The following predicate should work:
NSNumber *mood = #(7);
NSString *filter = #"%K == %#";
NSPredicate *getMoodPred = [NSPredicate predicateWithFormat:filter, #"mood", mood];
using NSNumber on the rhs and == as comparator.

'Unable to parse the format string "function == %#"' when using NSPredicate's predicateWithFormat:

I am trying to search an NSArray via the 'function' attribute. The output when I print the array on the console is as follows:
<__NSArrayI 0xa523b40>(
{
category = "010-T";
description = "<h3>Opleidingen</h3>";
function = "T-r";
name = "Michal Jordan";
photo = "http://dws.com/34.jpg";
},
{
category = "010-T";
description = "abcd";
function = "AB";
name = "Pvt MSK";
photo = "http://test.com/3.jpg";
},
{
category = "010-T";
description = "def";
function = "T-r";
name = "Sanu M";
photo = "http://abc.com/1.jpg";
}
)
This code, which searches by 'category', works:
NSString *categoryStr = #"010-T";
NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"category == %#",categoryStr]]];
But when I tried with the following code (searching by function), an exception was thrown:
NSString *functionStr = #"T-r";
NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"function == %#",functionStr]]];
The exception was:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "function == %#"'
So it seems here, that function is a reserved keyword.
I tried the following code, wrapping function with single quotes, but the result was that arr had 0 objects.
NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"'function' == %#",functionStr]]];
What am I doing wrong here?
Apple's Predicate Programming Guide states that "Predicate expressions in Cocoa are represented by instances of NSExpression." Note that NSExpression provides a syntax whereby one can invoke method calls via the FUNCTION keyword. The docs define the syntax as FUNCTION(receiver, selectorName, arguments, ...). While I find no reference to this in any documentation, it appears this feature excludes the use of the literal word function in other contexts.
Fortunately, you can build your predicate format string in an alternative way using the %K format specifier, which is used for key names. For example, [NSPredicate predicateWithFormat:#"%K == %#", #"function", #1] will not throw an exception and will work correctly. See it in action in the following code:
NSDictionary *dict1 = #{#"otherKey": #1, #"function" : #2};
NSDictionary *dict2 = #{#"otherKey": #2, #"function" : #1};
NSArray *array = #[dict1, dict2];
NSPredicate *otherKeyPredicate = [NSPredicate predicateWithFormat:#"%K == %#",#"otherKey", #1];
NSArray *filteredByOtherKey = [array filteredArrayUsingPredicate:otherKeyPredicate];
NSPredicate *functionPredicate = [NSPredicate predicateWithFormat:#"%K == %#", #"function", #1];
NSArray *filteredByFunction = [array filteredArrayUsingPredicate:functionPredicate];
NSLog(#"filteredByOtherKey = %#", filteredByOtherKey);
NSLog(#"filteredByFunction = %#", filteredByFunction);
We get the following output on the console:
filteredByOtherKey = (
{
function = 2;
otherKey = 1;
}
)
filteredByFunction = (
{
function = 1;
otherKey = 2;
}
)
Constructing your predicates this way may be slightly more work but will prevent these types of conflicts in the future. A good practice moving forward is to restrict the format string to containing only format specifiers and predicate syntax, finalizing the prediate's expression string at run time.
NSString *functionStr = #"T-r";
NSArray *arr = [myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(function == %#)",functionStr]];
Here myarr is NSMutableArray.
Try with this code.

Resources