有没有办法从这个晦涩的对象中获取属性并将其转换为 JSON?

Is there a way to acquire the properties from this obscure object and convert it to JSON?

我正在使用正在交付 this object to me.

的远程图书馆

如果我设置调试器,我会得到以下信息:

KandyChatMessage: UUID - 70886A79-2FF60F5E1A3961EF , timestamp - 2017-02-13 17:46:12 +0000 , sender - uri - 3@domain.domain.com, userName - 3, domain - domain.domain.com, type - 0, associationType - 1 , recipient - uri - afdab3bfb5774@domain.domain.com, userName - afdab3bfb57a12b5, domain - domain.domain.com, type - 1, associationType - 1 , type: - 1 , mediaItem - KandyTextMessageData - text:3 , info:(null) , isIncoming - 1 , additionalData - (null), fromHistory - NO

通过这种方式发送:

-(void)_addEventAndRefresh:(id<KandyEventProtocol>)event{

目标是将此对象转换为 JSON,如下所示:

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:event
                                                   options:0
                                                     error:&error];

但是,这会使我的应用程序崩溃,因为我假设 event 由于某种原因不满足可序列化 NSMUtableArrayNSDictionary 的所有规则。

这让我有两个选择。第一,我可以找到一些狡猾的方法将任何对象转换为 JSON。或者两个,我可以挑选出它的数据并从头开始编写一个 NSDictionary 对象。

有人知道如何拆开这种物体吗?

在我的debugger中,它似乎没有任何反应..

> po event.UUID
=> error: property 'UUID' not found on object of type 'id'
> po event.timestamp
=> error: property 'timestamp' not found on object of type 'id'

您是对的,该对象可能无法序列化为 JSON,因为它 doesn't qualify in one or all of these ways。一言以蔽之,一定是字符串、数字等集合的集合,不能是别的。

This answer suggests 如果您知道 class,这是一种获取属性的方法。简单来说就是依赖objc_property_t *properties = class_copyPropertyList(klass, &outCount);获取属性

您可以使用它来获取对象的 JSON 可序列化属性,将它们的值(以它们的名称作为键)放入字典中。然后 JSON 序列化它。

编辑 为了演示,我将此方法添加到其他答案建议的 PropertyUtil class...

+ (id)jsonSerializableFromObject:(id)object {
    if ([object isKindOfClass:[NSString self]] ||
        [object isKindOfClass:[NSNumber self]] ||
        [object isKindOfClass:[NSNull self]]) {
        return object;
    } else if ([object isKindOfClass:[NSArray self]]) {
        NSMutableArray *result = [NSMutableArray array];
        for (id e in (NSArray *)object) {
            id element = [self jsonSerializableFromObject:e];
            [result addObject:element];
        }
        return result;
    } else if ([object isKindOfClass:[NSArray self]]) {
        NSMutableDictionary *result = [NSMutableDictionary dictionary];
        for (id key in [(NSDictionary *)object allKeys])
            result[key] = [self jsonSerializableFromObject:(NSDictionary *)object[key]];
        return result;
    } else {
        NSMutableDictionary *result = [NSMutableDictionary dictionary];
        NSDictionary *props = [PropertyUtil classPropsFor:[object class]];
        for (NSString *propName in [props allKeys]) {
            id value = [object performSelector:NSSelectorFromString(propName)];
            result[propName] = [self jsonSerializableFromObject:value];
        }
        return (result.count)? result : [NSNull null];
    }
}

这里只是一个简单的草图:如果操作数可以序列化为 JSON,return 就可以了。如果操作数是数组,则回答每个元素组成的数组 json-serializable。如果是字典也一样。否则,如果对象是任意对象,应用内省方法获取它的属性,为每个 属性 调用 getter 并回答那个 json-serializable。

所以我设法得到了所有方法的列表,如下所示:

int i=0; unsigned int mc = 0; 
Method * mlist = class_copyMethodList(event, &mc); 
NSLog(@"%d methods", mc); for(i=0;i<mc;i++)     
NSLog(@"Method no #%d: %s", i, sel_getName(method_getName(mlist[i])));

然后我意识到我必须 class 强制转换对象来检索它的项目:

KandyChatMessage *chatMessage = (KandyChatMessage*)event;
chatMessage.description;