Couchbase Mobile iOS and nulls in json - Proper way to check for null on a CBLModel?

262 views
Skip to first unread message

Jeremy Kelley

unread,
Aug 15, 2014, 4:33:27 PM8/15/14
to mobile-c...@googlegroups.com
I am seeing something very odd and I'm wondering if anyone else has seen it.

I have a CBLModel, "Co" and an instance of that in "co".

I can NSLog the document with NSLog(@"doc: %@", co.document.properties) and see the following.
 

 

doc: {
   
"_id" = f0550298e5914ca18c377bdeaed4795c;
   
"_rev" = "1-94ea5906d0daee5f79ddc9de4eb37935";
    addr1
= "<null>";
    addr2
= "<null>";
    city
= "<null>";
   
"created_at" = "2014-08-15T05:22:01Z";
    email
= "<null>";
   
"est_terms" = "<null>";
   
"inv_terms" = "<null>";
    name
= JJCo;
    phone
= "<null>";
    pic
= "";
    plan
= STARTER;
    postal
= "<null>";
    slug
= "jjco.leveler.com";
    state
= "<null>";
    taxRate
= "0.0825";
    taxType
= "<null>";
    type
= co;
}


I can NSLog(@"co.addr1  %@", co.addr1)  and see "co.addr1 <null>"


While trying to assign the value to a UITextField, (an IBOutlet at "self.addr1") I have successful used 

    self.addr.text = co.addr1 ? co.addr1 : @""; 

 for quite some time.


But now I see the following error:


 -[NSNull rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x7e8068

2014-08-15 15:13:57.448 lvlrios[43935:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x7e8068'


I have tried all sorts of wonkery... from (id)[NSNull null] == co.addr1 to the example above and many other caffeine fueled attempts.

I have never encountered this problem because cb lite  seems to insert an empty string for NSString members on a Model whereas couchbase-python seems to put nulls.  I think from a JSON standpoint, the null is more correct but I'm falling down trying to handle records created by python that have been replicated into my cbmob db within ios.

Any help is GREATLY appreciated.

Thanks,
Jeremy




jeremy

unread,
Aug 15, 2014, 4:51:34 PM8/15/14
to mobile-c...@googlegroups.com
Looks like this works.

self.addr1.text = ([co.addr1 isEqual:[NSNull null]]) ? @"" : co.addr1;

#macro time...

-j
> --
> You received this message because you are subscribed to the Google Groups
> "Couchbase Mobile" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mobile-couchba...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/mobile-couchbase/1343d943-89b8-49d2-b4d2-f7d3fbe0ee45%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
As far as the laws of mathematics refer to reality, they are not certain;
and as far as they are certain, they do not refer to reality. A. Einstein

Jens Alfke

unread,
Aug 15, 2014, 4:52:02 PM8/15/14
to mobile-c...@googlegroups.com

> On Aug 15, 2014, at 1:33 PM, Jeremy Kelley <nods...@gmail.com> wrote:
>
> I can NSLog the document with NSLog(@"doc: %@", co.document.properties) and see the following.
>
> doc: {
> "_id" = f0550298e5914ca18c377bdeaed4795c;
> "_rev" = "1-94ea5906d0daee5f79ddc9de4eb37935";
> addr1 = "<null>";
> addr2 = "<null>";
> city = "<null>";

Most of the properties are set to JSON null values, which seems wasteful to me; why not just omit the property instead? But it's possible that you have an application schema where a value of null means something different than no property?

> While trying to assign the value to a UITextField, (an IBOutlet at "self.addr1") I have successful used
> self.addr.text = co.addr1 ? co.addr1 : @"";
> for quite some time.
> But now I see the following error:
> -[NSNull rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x7e8068

That's what I'd expect. You understand the difference between a nil pointer and an NSNull object, right? Your code on the second line is checking whether co.addr1 is nil. In this case it isn't; it's an NSNull object. Storing an NSNull object into what's supposed to be an NSString valued property is illegal, and causes exceptions when the UITextField tries to call NSString methods on it.

> I have tried all sorts of wonkery... from (id)[NSNull null] == co.addr1 to the example above and many other caffeine fueled attempts.

That test will work only if there is a single instance of NSNull in the process (since == is a pointer comparison.) I would have guessed that NSNull is a singleton, but if this isn't working for you, maybe it isn't. In that case the most reliable test is
[co.addr1 isKindOfClass: [NSNull class]]

> I have never encountered this problem because cb lite seems to insert an empty string for NSString members on a Model

No, it doesn't. If you set the Objective-C property to a non-nil NSString, then that will be stored in the document as a JSON string. If you set it to nil, the property will not appear in the document at all.

—Jens

Jens Alfke

unread,
Aug 15, 2014, 5:00:02 PM8/15/14
to mobile-c...@googlegroups.com

On Aug 15, 2014, at 1:51 PM, jeremy <nods...@gmail.com> wrote:

self.addr1.text = ([co.addr1 isEqual:[NSNull null]]) ? @"" : co.addr1;

Yup, that's another safe test.

I just realized that CBLModel shouldn't be storing an NSNull object into a NSString-valued property at all; that's a type violation. Instead it should probably convert it to nil. That would save you from having to make tests like this. I just filed this as a new issue.

—Jens

Jeremy Kelley

unread,
Aug 15, 2014, 5:01:29 PM8/15/14
to mobile-c...@googlegroups.com
Jens - sorry, I was mistaken about the nulls.

I was assigning the values from UITextFields indiscrimately on a model
and then had looked in the db at a record to confirm my bias. Me
being sloppy.

My nil/NSNull comparison-fu was weak. Switching back and forth
between objc, python, js is giving me tired head. I knew better...

-j
> --
> You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/mobile-couchbase/FEC533EA-BF0C-4528-9D5D-12559486203E%40couchbase.com.
> For more options, visit https://groups.google.com/d/optout.



--
The Christian ideal has not been tried and found wanting;
it has been found difficult and left untried – G. K. Chesterton
Reply all
Reply to author
Forward
0 new messages