Ich versuche durch ein XML zu analysieren, den ich von einem Webservice mit einem bekomme NSXMLParserDelegate
. Das NSObject
Ich möchte die Daten einsetzen (ich werde sie einfach nennen MyObject
) hat @property
s, das nicht sind NSString
s (es gibt einige NSDate
S, einige NSNumber
S und vielleicht irgendwann in Zukunft einige Primitive).
Da der XML alles eine große Zeichenfolge ist, bekomme ich Fehler und stürze, wenn ich versuche, die Werte einfach direkt aus dem XML in meine Eigenschaften einzulegen (ich verwende [myObject setValue:currentElementValue forKey:elementName];
in meinem parser:didEndElement:...
, was normalerweise gut funktioniert - wann key
ist ein NSString
). Ich hatte nicht wirklich erwartet, dass dies funktioniert, aber ich dachte, es war einen Schuss wert.
Das einfachste, was zu tun ist, ist nur Hardcode zu tun. auf meinem Objekt, wenn ich das finde <age>25</age>
Teil meines XML, das tue ich MyObject.age = [NSNumber numberWithInt:[currentElementValue intValue]];
. Das Problem dabei ist, dass es sehr starr ist - ich möchte, dass dieser Code dynamischer ist. Ich möchte nicht wissen, was alle Eigenschaften meines Objekts im Voraus sind.
Ich habe auch versucht zu überprüfen, was die class
der Eigenschaft ist und dann eine gewisse Konvertierung vor dem Eingeben eines Wertes (so etwas wie [myObject setValue:[NSNumber numberWithInt:[currentElementValue intValue] forKey:elementName];
Wenn die Eigenschaft isKindOfClass:[NSNumber class]]
. Das Problem dabei ist, dass dies das erste Mal ist, dass Eigenschaft verwendet wird, so dass es so ist nil
, und hat daher keine Klasse. Dieser Ansatz funktioniert also auch nicht wirklich.
Mache ich das völlig falsch? Es scheint, als sollte es ziemlich typisch sein, Daten von einem XML zu erhalten und sie in Nichts zu setzenNSString
Variablen, aber ich kann es nicht zum Laufen bringen.
Wenn jemand mehr Code sehen muss, um ein besseres Verständnis dafür zu erhalten, wie ich dies eingerichtet habe oder was ich bereits ausprobiert habe, lassen Sie es mich wissen.
EDIT: Ich habe ein kurzes Beispiel dafür gefunden, was ich versuche zu tun. Angenommen, ich habe das folgende XML:
<Object>
<ITEM_NUMBER>4</ITEM_NUMBER>
<IS_AWESOME>YES</IS_AWESOME>
<AWESOMENESS>9000.1</AWESOMENESS>
</Object>
dass ich in eine Instanz von analysieren möchte MyObject
(ein NSObject
Unterklasse)
@interface MyObject: NSObject
@property (nonatomic, assign) int ITEM_NUMBER;
@property (nonatomic, assign) BOOL IS_AWESOME;
@property (nonatomic, assign) float AWESOMENESS;
@end
Und eine zweite XML
<OtherObject>
<PRICE>4.99</PRICE>
<QUANTITY>5</QUANTITY>
<FOR_RESALE>NO</FOR_RESALE>
</OtherObject>
das wird in eine Instanz von gehen OtherObject
(Auch NSObject
Unterklasse)
@interface OtherObject: NSObject
@property (nonatomic, assign) int QUANTITY;
@property (nonatomic, assign) BOOL FOR_RESALE;
@property (nonatomic, assign) float PRICE;
@end
Ich möchte einen "Vorlage" -Parser erstellen (der hat @property (nonatomic, strong) NSObject *instance;
und dann NSMutableString *currentElementValue
als Ivar)
...
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentElementValue setString:string];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([[self.instance valueForKey:elementName] isKindOfClass:int])
{
[self.instance setValue:[currentElementValue intValue] forKey:elementName];
}
else if ([[self.instance valueForKey:elementName] isKindOfClass:float])
{
[self.instance setValue:[currentElementValue floatValue] forKey:elementName];
}
else if ([[self.instance valueForKey:elementName] isKindOfClass:BOOL])
{
[self.instance setValue:[currentElementValue boolValue] forKey:elementName];
}
else if ...
}
...
Dann unterklasse ich diesen "Vorlage" -Parser für jeden meiner verschiedenen XMLs und überschreibe das init
Methode so
self.instance = [[MyObject alloc] init];
oder
self.instance = [[OtherObject alloc] init];
wie angemessen. Ich habe viele Webservices, die ich nenne, die ich ähnlich strukturiert habe. Wenn Sie den Rest des Parser -Codes in einer einzigen "Vorlage" -Klasse haben, wird das Wartung, Lesen und Debuggen des Codes so viel einfacher.
Offensichtlich ist das Problem, das ich habe isKindOfClass
akzeptiert nicht int
, float
, oder BOOL
als Eingänge. Gibt es etwas Ähnliches, das ich stattdessen verwenden kann?