문제

나는 XML을 구문 분석하려고 노력하고 있습니다. NSXMLParserDelegate. 그만큼 NSObject 데이터를 넣고 싶어요 (그냥 부를거야 MyObject) 가지다 @property그렇지 않은 s NSStringS (일부가 있습니다 NSDateS, 일부 NSNumberS, 아마도 어느 시점에서 일부 프리미티브).

XML은 모두 큰 문자열이므로 XML의 값을 내 속성에 직접 넣으려고 할 때 오류와 충돌이 발생합니다 (사용 중입니다. [myObject setValue:currentElementValue forKey:elementName];parser:didEndElement:..., 일반적으로 잘 작동합니다 - 언제 key a NSString). 나는 이것이 실제로 작동하기를 기대하지는 않았지만, 그것이 가치가 있다고 생각했다.

가장 쉬운 일은 모든 것을 하드 코드이므로 '@property (비 원자, 강한) nsnumber *Age;'가 있다면; 내 대상에, 내가 찾을 때 <age>25</age> 내 XML의 일부입니다 MyObject.age = [NSNumber numberWithInt:[currentElementValue intValue]];. 이것의 문제는 매우 단단하다는 것입니다.이 코드가 그보다 더 역동적이기를 바랍니다. 나는 내 객체의 모든 속성이 미리 무엇인지 알고 싶지 않습니다.

나는 또한 무엇을 확인하려고 노력했다 class 속성의 경우 값을 입력하기 전에 약간의 변환을 수행합니다 (따라서 [myObject setValue:[NSNumber numberWithInt:[currentElementValue intValue] forKey:elementName]; 재산 인 경우 isKindOfClass:[NSNumber class]]. 이것의 문제점은 이번이 부동산을 사용한 것은 이번이 처음이므로 nil, 따라서 수업이 없습니다. 따라서이 접근법은 실제로 작동하지 않습니다.

내가 이것을 완전히 잘못하고 있습니까? XML에서 데이터를 가져 와서 비에 넣는 것은 상당히 일반적인 것 같습니다.NSString 변수이지만 작동하지 않는 것 같습니다.

내가 설정 한 방법이나 이미 시도한 내용을 더 잘 이해하기 위해 더 많은 코드를 볼 필요가 있다면 알려주십시오.


편집 : 나는 내가하려는 일의 빠른 예를 생각해 냈습니다. 다음 XML이 있다고 가정합니다.

<Object>
    <ITEM_NUMBER>4</ITEM_NUMBER>
    <IS_AWESOME>YES</IS_AWESOME>
    <AWESOMENESS>9000.1</AWESOMENESS>
</Object>

나는 인스턴스로 구문 분석하고 싶다 MyObject (an NSObject 아강)

@interface MyObject: NSObject

@property (nonatomic, assign) int ITEM_NUMBER;
@property (nonatomic, assign) BOOL IS_AWESOME;
@property (nonatomic, assign) float AWESOMENESS;

@end

그리고 두 번째 XML

<OtherObject>
    <PRICE>4.99</PRICE>
    <QUANTITY>5</QUANTITY>
    <FOR_RESALE>NO</FOR_RESALE>
</OtherObject>

그것은 사례로 들어갈 것입니다 OtherObject (또한 NSObject 아강)

@interface OtherObject: NSObject

@property (nonatomic, assign) int QUANTITY;
@property (nonatomic, assign) BOOL FOR_RESALE;
@property (nonatomic, assign) float PRICE;

@end

"템플릿"파서를 만들고 싶습니다 ( @property (nonatomic, strong) NSObject *instance; 그리고 NSMutableString *currentElementValue 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 ...
}
...

그런 다음 각각의 다른 XML에 대한 "템플릿"파서를 서브 클래스하고 init 방법

self.instance = [[MyObject alloc] init];

또는

self.instance = [[OtherObject alloc] init];

적절한. 나는 내가 부르는 많은 웹 서비스를 가지고 있으며, 비슷하게 구조화 된 XML을 얻을 것이라고 부르기 때문에 각각의 구문 분석에서 1 줄만 변경하면 매우 바람직한 것입니다. 단일 "템플릿"클래스에 나머지 구문 분석 코드를 보유하면 코드를 유지 관리, 읽기 및 디버깅하는 것이 훨씬 쉽습니다.

분명히, 내가 가진 문제는입니다 isKindOfClass 수락하지 않습니다 int, float, 또는 BOOL 입력으로. 대신 사용할 수있는 것과 비슷한 점이 있습니까?

도움이 되었습니까?

해결책

이것의 문제점은 이번이 부동산을 사용한 것은 이번이 처음이므로 NIL이므로 클래스가 없다는 것입니다.

대상 C는 허용합니다 런타임시 쿼리 클래스 속성, 따라서 속성 유형을 내성하고 적절한 trnsformation을 사용하는 것이 한 가지 방법입니다.

런타임에 대한 자세한 내용을 읽을 수 있습니다 Mike Ash의 블로그에서 또는 참조 객관적인 C 내성/반사.

하지만, 이 구체적인 문제는 다른 많은 사람들이 발생했습니다., 그래서 몇 가지 해결책이 있습니다. iOS 가장 성숙한 REST 서비스 라이브러리 Restkit은 그러한 도서관의 좋은 예입니다. MagicRecord는 또 다른 것입니다.

자신의 솔루션을 구현하기 전에 확인할 몇 개의 라이브러리를 쉽게 찾을 수 있습니다.

다른 팁

물론 나는 단지 그것을 무시할 수있었습니다 init 의 방법 MyObject 내 모든 속성을 빈 값에 할당하기 위해 nil 문제 문제는 내 OP에서 언급했지만 정말 해킹 된 느낌입니다. 그래도 유일한 옵션 일 수 있습니다.


편집 :이 접근법은 OP의 편집의 예제와 완전히 분리됩니다. KVC가 회전합니다 int에스, float모래 BOOL모두 NSNumberS, 원래 어디에 있는지 알 수없는 방법없이. 즉, 전화 할 수 없다는 뜻입니다 [currentElementValue intValue], [currentElementValue floatValue], 또는 [currentElementValue boolValue] 적절한.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top