Parse.com: How to properly check if a field is empty? - ios

I ask this in the context of a iOS / Swift app:
When retrieving with a query an object from Parse, I used to check for empty fields by checking them against nil. if != nil.... then do this etc etc....
Apparently, this is not the proper way to do this, because even if a field is empty on Parse, it is NOT considered nil by swift.
So what to to check for to determine if a field is empty or not, and for the various Parse supported types: strings, Number, Array.....?
Edit: there are answers for objective-c that don't work in swift where unless value is a boolean you MUST compare it against nil (which cause issue here) or something else to see if it exists or not.

You would use whereKeyExists:
Checkout the Parse documentation
If you want to retrieve objects that have a particular key set, you can use whereKeyExists. Conversely, if you want to retrieve objects without a particular
key set, you can use whereKeyDoesNotExist.
// Finds objects that have the score set
[query whereKeyExists:#"score"];

Ok so here is what I found after some investigation:
A String field when it looks empty on parse explorer, in fact contains "". It is only when the field specifically has "undefined" in it that it is nil, which you can compare against with === and not ==. Not sure why, if someone knows....
Other fields than String, cannot contain "". They either contain a value or are undefined.
So if you need to know if a field is nil or contains no value, if it's a string compare it against == "" and === nil, and use === nil if it's not a string.

This is what I used to check whether a field containing a file is null. Since the value can be (undefined) or (null).
func isParseNull(obj : AnyObject!) -> Bool {
if obj == nil {
return true
}
if obj as NSObject == NSNull() {
return true
}
return false
}

I'm pretty sure the Parse documentation says !=nil however you could try
entity == ""

I would extend String class and do the following
extension String {
func isOnlyEmptySpacesAndNewLineCharacters() -> Bool {
return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).length == 0
}
}

Here is my method, as I also struggled to check to see whether a string was empty in parse, and this seems to work fine.
- (void) nameCheck
{
//--------GET CURRENT USER-------//
PFUser *user = [PFUser currentUser];
//----------CHECK IF PARSE IS EMPTY OR TEXTFIELD IS EMPTY-----------//
if ([user[#"fullname"] isEqual: #""] || [fieldName.text isEqual:nil])
{
//-IF EMPTY, GIVE USER ANONYMOUS NAME-//
user[#"fullname"] = #"Anonymous User";
user[#"fullname_lower"] = #"anonymous user";
//------------------SAVE NEW NAME IN BACKGROUND----------------//
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (error == nil)
{
NSLog(#"Saved Username");
}
}];
}
//--ELSE USER'S NAME EXISTS--//
else
{
//--LOAD USER METHOD--//
[self loadUser];
NSLog(#"User has username");
}
}

Related

Core Data predicate crashes when attribute is nil

tl;dr: type something here that won't crash if birthDate is nil:
I have an entity with a birthDate attribute and a fetched property with the following predicate, typed straight into the xcdatamodel file:
$FETCH_SOURCE.birthDate > birthDate
This happily returns a list of managed objects older than FETCH_SOURCE (the managed object where the fetch request is happening). But birthDate is optional, and if the birthDate for FETCH_SOURCE is nil...
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'can't use NULL on left hand side'
Note that it's fine if the attribute is nil for the object being compared. If I swap the arguments of the predicate:
birthDate < $FETCH_SOURCE.birthDate
...I get the same error. Trying to test it for nil:
(birthDate != nil AND birthDate < $FETCH_SOURCE.birthDate)
...gives...
'NSInvalidArgumentException', reason: 'illegal comparison with NULL'
Google hasn't heard of either of those errors so I'm thinking this is a recent state of affairs. The problem remains when it's a String being compared for equivalence, or whatever. Is there a way to fix this in the predicate so it correctly returns an empty list? Thanks.
Edit: To be clear, the question is whether it's possible to fix this crash in the predicate in the xcdatamodel file.
Update: The crash specifically happens when the Relationship fault for the NSFetchedPropertyDescription is triggered by trying to read anything about it, presumably because it doesn't attempt to run the predicate till then. It isn't nil however, and can be checked for nil without crashing.
I can't find any way to amend the predicate of the fetched property to avoid this error, but one workaround is to implement a custom getter for the olderHeroes fetched property. This should return an empty array if the birthDate is nil.
var olderHeroes: NSArray {
var array : NSArray
if self.birthDate == nil {
array = NSArray()
} else {
self.willAccessValueForKey("olderHeroes")
array = self.primitiveValueForKey("olderHeroes") as! NSArray
self.didAccessValueForKey("olderHeroes")
}
return array
}
Or in Objective-C:
-(NSArray *)olderHeroes {
NSArray *array;
if (self.birthDate == nil) {
array = [NSArray array];
} else {
[self willAccessValueForKey:#"olderHeroes"];
array = [self primitiveValueForKey:#"olderHeroes"];
[self didAccessValueForKey:#"olderHeroes"];
}
return array;
}
(These snippets go in the implementation file for the subclass of the FETCH_SOURCE entity).
If you want to have results containing either a nil value or it has to be greater or smaller than a certain date use the following:
((birthDate == nil) OR (birthDate < %#))
This works for me. I hope this is what you're asking. Had a bit of trouble understanding your question.
If you're asking to check a variable you're passing in the predicate, might the following work (untested):
(($FETCH_SOURCE.birthDate == nil && birthDate == nil) OR ($FETCH_SOURCE.birthDate < birthDate))

String Passes Empty Test, Returns null

I am testing to see if a string is stored in NSUserDefaults. In theory, I thought the following was the answer:
if ( ![[[NSUserDefaults standardUserDefaults] authorName] isEqual: #""] )
{
NSLog(#"The default must be set, the string is not equal to empty.");
NSString *authorName = [[NSUserDefaults standardUserDefaults] authorName];
}
In practice, it always tested that something was there, but then returned a value of "(null)", when I try to use it. Can someone tell me why?
Ultimately, I think I've solved the problem with the following, but I'm not clear why the first test case did not work as I expected.
if ( [[[NSUserDefaults standardUserDefaults] authorName] length] != 0 )
Thanks.
The nil string is not equal to the empty string. That is why the first test passes but returns nil - because NSUserDefaults will return nil if no value is stored.
The reason why comparing length to zero works, is because when calling a method on a nil reference in objective-c, nil is returned. This is different from most other language, which would instead throw an exception in this case. Because length is NSInteger, nil becomes zero.
Comparing length to zero should be safe, but what you really is trying to test is whether a string is stored for the given key in the defaults. In that case, you can simply compare to nil:
if ([[NSUserDefaults standardUserDefaults] authorName] != nil)
{
....
}

How can I check for an empty object within an NSArray

I'd like to check for an empty object (i.e. an object of an array which doesn't have a value) within an array which gets its data from a file.
As an example, if my array contains 12 objects (all NSString) and the object at index 11 doesn't return a value when its description is printed into the debug section of Xcode. I want to check if that is the case and respond accordingly. I already tried
if (!([MY_ARRAY objectAtIndex:11] == nil))
{
//Some Stuff
}
else
{
//Some other Stuff
}
which didn't work.
Any help is appreciated.
The description method is for debugging. You should not use it in your program logic. What are these objects, and what do they contain? Can you modify the objects to add an "isEmpty" property?
If you use NSNull, you'd use code like this:
NSArray *array = #{#"String", #(4), [NSNull null], #"Another string");
for (id anObject in array)
{
if (anObject =! [NSNull null]))
{
//Some Stuff
}
else
{
//Some other Stuff
}
}
You can check the length of the string: [string length] > 0
an object is an array cannot be nil, but you can use [NSNull null] which is an "object equivalent" to nil
As Jerome Diaz states, objects in an array can't be nil. The only option you have is to check the count property of the array if it reflects an expected value, or you can inspect the type/class of the object in the array. A safe way to include empty object into array is [NSNull null], but this is the task for the method that fills the array, not the one that reads it.
You can check the class type of an object in array with isKindOfClass or isMemberOfClass.

How to add string object in nsmutable array if some string is empty

arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
I fetched data from a webservice. in my condition if strweb has no value then it simply ignores other values like stradd,sphone and strrate. How can I solve this problem?
you can do like this in a simplest way.
if(strweb==nil)
{
strweb=#"null";
}
Note: pass null in <> bracket;
Try this code,
if(strWeb == nil){
strWeb = [NSString stringWithFormat:#"%#", [NSNull null]];
}
arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
When your any object nil while creation time of array then your array will be end with than object and remaining objects will discards. That why you need to check every object should not be nil according above code stuff then add it into array.
If strWeb is nil then your array structure will be
arrdata=[[NSMutableArray alloc]initWithObjects:strname,nil]; future object will discard.,strAdd,strPhone,strrate,
output of arrdata containg only one object strname
Other way,
Set any default value if your string is nil. for example,
if(strWeb == nil){
strWeb = #"This Value is discarded"; // It could be anything identifier for your purpose.
}
arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
While retrieving time you can match above string with value inside the object.
You use the initializer -initWithObjects:. As you know the object list is terminated with nil. If one of the references has the value nil, -initWithObjects: thinks that this is the terminator.
Check the references (i. e. strweb). If it is nil, assign a default value to it or do not encounter the variable in the list.

ios check if array has object

From an array, I want to make a new mutable array holding all the items that meet a certain criteria. That's not the problem. The problem is checking if the array is empty.
if (!theDates]) {/*do something*/}
it comes back positive regardless, because the mutable array was created. But
if (![theDates objectAtIndex:0])
{
/* nothing got added to the array, so account for that */
}
else
{
/* do something with the array */
}
It crashes.
This crashes because although you have allocated your array, it's still empty. The line [theDates objectAtIndex:0] is trying to access the first object of an array, and due your array has none yet, it will crash.
To check the integrity of your array, just do this:
if (theDates.count > 0)
{
//Do something
id object = theDates[0]; //this for sure won't crash
}
Use [theDates count] > 0. You're accessing a possibly non-existent element, so it will crash when it's empty.
Or you could use the lastObject method which will return nil if the array is empty
if (![theDates lastObject]) { do something }
if( (theDates!=nil) && (theDates.count > 0))
{
//We have and existing array and something in there..
}
if (theDates != nil){
if (theDates.count > 0){
'do something'
}
}
This should check null array then check empty array which prevents nullpointerexception arises
This will work fine..
if (!URarray || !URarray.count){
// write code here
}

Resources