2 Stimmen

Erkennen fehlender JSON-Schlüssel bei verschachtelten Objekten

Derzeit arbeite ich mit einer API, die sich noch in der Entwicklung befindet. Aufgrund dessen ändern sich die Schlüssel in der Antwort noch. Ich konnte erfolgreich die JSON-Daten aus der API abrufen und analysieren, um sie dann in ein NSDictionary umzuwandeln und diese Werte in benutzerdefinierte Objekte zu mapppen. Der Ansatz, den ich verwende, ist folgender:

-(id)initWithDictionary:(NSDictionary*)dictionary
{
    if(self = [super init]){
        _ID = [dictionary valueForKey:kKEY_ID];
        _name = [dictionary valueForKey:kKEY_NAME];
        _nestedObject = [[NestedObject alloc]initWithDictionary:[dictionary valueForKey:kKEY_NESTED_OBJECT]];
        //etc...
    }
    return self
}

Jedes verschachtelte Objekt hat auch die gleiche Analysestruktur.

Dies funktioniert gut, außer wenn sich die API ändert. Wenn etwas geändert wird, fehlen erforderliche Werte und dies führt zu unerwartetem Verhalten oder Abstürzen.

Idealerweise möchte ich, wenn sich einer der Schlüssel ändert, ein NSError erzeugen, mit dem ich den geänderten Wert ausgeben kann, um die Änderung schneller zu finden und zu korrigieren.

Der einzige alternative Ansatz, den ich bisher entwickelt habe, kommt mir unordentlich und schwer wartbar vor.

-(id)initWithDictionary:(NSDictionary*)dictionary andError:(NSError**)error
{
    if(self = [super init]){

        BOOL _parsedSuccessfully = TRUE;

        if (_parsedSuccessfully) {
             _ID = [dictionary valueForKey: kKEY_ID];

             if (!_ID){
                 _parsedSuccessfully = FALSE;
                 *error = [NSError parsingErrorFromKey: kKEY_ID];
             }
        }

        if (_parsedSuccessfully) {
             _name = [dictionary valueForKey: kKEY_NAME];

             if (!_name){
                 _parsedSuccessfully = FALSE;
                 *error = [NSError parsingErrorFromKey: kKEY_NAME];
             }
        }

        if (_parsedSuccessfully) {
             _nestedObject = [[NestedObject alloc]initWithDictionary:[dictionary valueForKey:kKEY_NESTED_OBJECT]];

             if (!_nestedObject){
                 _parsedSuccessfully = FALSE;
                 *error = [NSError parsingErrorFromKey: kKEY_NESTED_OBJECT];
             }
        }

        //etc...

        if (!_parsedSuccessfully) {
            return nil;
        }
    }
    return self
}

Ich frage mich, ob jemand einen besseren Ansatz kennt, der idealerweise weniger Duplikation verwendet.

Über jede Hilfe würde ich mich sehr freuen.

1voto

trojanfoe Punkte 117964

Fügen Sie eine isValid-Methode zu Ihrem Objekt hinzu, die in jeder Situation verwendet werden kann, nicht nur wenn sie aus dem JSON-Wörterbuch initialisiert wird.

- (BOOL)isValid:(NSError **)error {

    #define CHECK_NOT_NULL(x, key) if (!x) { \
        if (error != NULL) \
            *error = [NSError parsingErrorFromKey:key]; \
        return NO; \
    }

    #define CHECK_NOT_EMPTY(x, key) if (!x || ![x length]) { \
        if (error != NULL) \
            *error = [NSError parsingErrorFromKey:key]; \
        return NO; \
    }

    CHECK_NOT_NULL(_ID, kKEY_ID);
    CHECK_NOT_EMPTY(_name, kKEY_NAME);
    // usw.

    return YES;
    #undef CHECK_NOT_NULL
    #undef CHECK_NOT_EMPTY
}

Und verwenden Sie dies dann in Ihrer Init-Methode:

- (id)initWithDictionary:(NSDictionary*)dictionary andError:(NSError**)error
{
    if (self = [super init]) {
         _ID = [dictionary valueForKey: kKEY_ID];
         _name = [dictionary valueForKey: kKEY_NAME];
         // usw.

         if (![self isValid:error]) {
             self = nil;    // Unter der Annahme von ARC
         }
    }
    return self;
}

0voto

Wain Punkte 118580

Wenn Sie ein Array Ihrer Schlüssel erstellen, können Sie Ihre Überprüfung in einer Schleife durchführen, sodass Sie nur eine Kopie der Schleife haben.

Auch hier könnten Sie mithilfe des Arrays alle Schlüssel aus dem Wörterbuch abrufen und sie voneinander entfernen. Auf diese Weise erhalten Sie neue Schlüssel, während Sie auf andere Weise die fehlenden Schlüssel erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X