Überprüfen eines Nullwerts in Objective-C, der von einer JSON-Zeichenfolge zurückgegeben wurde

78

Ich habe ein JSON- Objekt, das von einem Webserver stammt.

Das Protokoll sieht ungefähr so ​​aus:

{          
   "status":"success",
   "UserID":15,
   "Name":"John",
   "DisplayName":"John",
   "Surname":"Smith",
   "Email":"email",
   "Telephone":null,
   "FullAccount":"true"
}

Beachten Sie, dass das Telefon als null eingeht, wenn der Benutzer keine eingibt.

Wenn Sie diesen Wert a zuweisen NSString, wird NSLoger als ausgegeben<null>

Ich weise die Zeichenfolge folgendermaßen zu:

NSString *tel = [jsonDictionary valueForKey:@"Telephone"];

Wie kann dieser <null>Wert richtig überprüft werden? Es hindert mich daran, a zu retten NSDictionary.

Ich habe versucht, die Bedingungen [myString length]und myString == nilund zu verwendenmyString == NULL

Wo ist außerdem der beste Ort in der iOS-Dokumentation, um dies zu lesen?

Chris
quelle

Antworten:

189

<null>So protokolliert der NSNull-Singleton. Damit:

if (tel == (id)[NSNull null]) {
    // tel is null
}

(Der Singleton ist vorhanden, da Sie keine nilAuflistungsklassen hinzufügen können .)

Wevah
quelle
41
Wenn Sie es ohne die Besetzung tun möchten, können Sie auch versuchen:if ([tel isKindOfClass:[NSNull class]])
Aaron Hayman
wir können verwenden: if (Objekt ist gleich: [NSNull null]) {--logic here--}
Gajendra K Chauhan
24

Hier ist das Beispiel mit der Besetzung:

if (tel == (NSString *)[NSNull null])
{
   // do logic here
}
Floh
quelle
oder wenn (tel == (NSString *) NSNull.null) {// hier Logik machen}
Raphael Oliveira
10

Sie können diesen eingehenden String auch folgendermaßen überprüfen: -

if(tel==(id) [NSNull null] || [tel length]==0 || [tel isEqualToString:@""])
{
    NSlog(@"Print check log");
}
else
{  

    NSlog(@Printcheck log %@",tel);  

}
Nitin Gohel
quelle
Ihre erste NSLogLinie ist falsch ... es sollte sagen , dass die Zeichenfolge ist leer. Und warum sollten Sie es in diesem Fall drucken?
Bdesham
Vielen Dank für Ratschläge und ich drucke NSLogfür das Wissen, welche Bedingung wahr wird
Nitin Gohel
9

Wenn Sie mit einer "instabilen" API arbeiten, möchten Sie möglicherweise alle Schlüssel durchlaufen, um nach Null zu suchen. Ich habe eine Kategorie erstellt, um damit umzugehen:

@interface NSDictionary (Safe)
-(NSDictionary *)removeNullValues;
@end

@implementation NSDictionary (Safe)

-(NSDictionary *)removeNullValues
{
    NSMutableDictionary *mutDictionary = [self mutableCopy];
    NSMutableArray *keysToDelete = [NSMutableArray array];
    [mutDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (obj == [NSNull null]) 
        {
            [keysToDelete addObject:key];
        }
    }];
    [mutDictinary removeObjectsForKeys:keysToDelete];
    return [mutDictinary copy];
}
@end
Kyle C.
quelle
4

Die beste Antwort ist, was Aaron Hayman unter der akzeptierten Antwort kommentiert hat:

if ([tel isKindOfClass:[NSNull class]])

Es wird keine Warnung ausgegeben :)

kjoelbro
quelle
3

Wenn Sie viele Attribute in json haben, ifist es problematisch , Anweisungen zu verwenden, um sie einzeln zu überprüfen. Was noch schlimmer ist, ist, dass der Code hässlich und schwer zu pflegen wäre.

Ich denke, der bessere Ansatz besteht darin, eine Kategorie zu erstellen NSDictionary:

// NSDictionary+AwesomeDictionary.h

#import <Foundation/Foundation.h>

@interface NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key;
@end

// NSDictionary+AwesomeDictionary.m

#import "NSDictionary+AwesomeDictionary.h"

@implementation NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key {
    id value = [self valueForKey:key];
    if (value == [NSNull null]) {
        value = nil;
    }
    return value;
}
@end

Nach dem Import dieser Kategorie können Sie:

[json validatedValueForKey:key];
Brian
quelle
2

Normalerweise mache ich das so:

Assuma Ich habe ein Datenmodell für den Benutzer und es hat eine NSString-Eigenschaft namens E-Mail, die aus einem JSON-Diktat abgerufen wurde. Wenn das E-Mail-Feld in der Anwendung verwendet wird, verhindert das Konvertieren in eine leere Zeichenfolge mögliche Abstürze:

- (id)initWithJSONDictionary:(NSDictionary *)dictionary{

    //Initializer, other properties etc...

    id usersmail = [[dictionary objectForKey:@"email"] copy];
    _email = ( usersmail && usersmail != (id)[NSNull null] )? [usersmail copy] : [[NSString      alloc]initWithString:@""];
}
Yunus Nedim Mehel
quelle
2

In Swift können Sie Folgendes tun:

let value: AnyObject? = xyz.objectForKey("xyz")    
if value as NSObject == NSNull() {
    // value is null
    }
Segev
quelle
Die Frage bezieht sich auf Objective-C, nicht auf Swift.
JasonMArcher
4
@JasonMArcher Die Antwort bietet immer noch einen gewissen Wert für diejenigen, die über eine Google-Suche auf die Frage kommen. Immerhin ist es eine 4 Jahre alte Frage.
Beau Nouvelle
0

Am besten halten Sie sich an Best Practices, dh verwenden Sie ein echtes Datenmodell, um JSON-Daten zu lesen.

Schauen Sie sich JSONModel an - es ist einfach zu bedienen und konvertiert automatisch [NSNUll null] in * nil * -Werte, sodass Sie Ihre Überprüfungen wie in Obj-c wie folgt durchführen können:

if (mymodel.Telephone==nil) {
  //telephone number was not provided, do something here 
}

Schauen Sie sich die Seite von JSONModel an: http://www.jsonmodel.com

Hier ist auch eine einfache Anleitung zum Erstellen einer JSON-basierten App: http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/

Marin Todorov
quelle
Existiert diese JSONModel-Site noch? Es ist nicht auf Englisch, daher kann ich nicht sicher sein, aber es sieht nicht so aus, als hätte es viel mit JSON zu tun.
Stewart Macdonald
0

Ich habe viel versucht, aber nichts hat funktioniert. Endlich hat das bei mir geklappt.

NSString *usernameValue = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] valueForKey:@"usernameKey"]];

if ([usernameValue isEqual:@"(null)"])
{
     // str is null
}

quelle
0
if([tel isEqual:[NSNull null]])
{
   //do something when value is null
}
Gajendra K Chauhan
quelle
Erzeugt eine Warnung: Inkompatible Zeigertypen, die 'NSNull * _Nonnull' an den Parameter 'Class' senden
Adnan Asghar
0

Versuche dies:

if (tel == (NSString *)[NSNull null] || tel.length==0)
{
    // do logic here
}
Mritunjay
quelle
0

Ich benutze das:

#define NULL_TO_NIL(obj) ({ __typeof__ (obj) __obj = (obj); __obj == [NSNull null] ? nil : obj; }) 
Carles Estevadeordal
quelle
0

Wenn wir einen Nullwert wie erhalten, können wir ihn mit dem folgenden Codeausschnitt überprüfen.

 if(![[dictTripData objectForKey:@"mob_no"] isKindOfClass:[NSNull class]])
      strPsngrMobileNo = [dictTripData objectForKey:@"mobile_number"];
  else
           strPsngrMobileNo = @"";
Chandni - Systematix
quelle
-6

Hier können Sie dies auch tun, indem Sie die Länge der Zeichenfolge überprüfen, dh

if(tel.length==0)
{
    //do some logic here
}
Rahul Narang
quelle
3
Nein, wenn teles sich um eine Instanz von handelt NSNull, wird eine Ausnahme ausgelöst.
Kurt Revis
Ja, ich denke, wir müssen überprüfen, ob es null ist oder nicht. Wir müssen auch die oben genannten Bedingungen berücksichtigen
Rahul Narang