Ios 有没有办法从这个模糊的对象获取属性并将其转换为JSON?

Ios 有没有办法从这个模糊的对象获取属性并将其转换为JSON?,ios,objective-c,json,nsjsonserialization,Ios,Objective C,Json,Nsjsonserialization,我正在与一个正在交付的远程库合作 如果我设置了调试器,我将获得以下信息: 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

我正在与一个正在交付的远程库合作

如果我设置了调试器,我将获得以下信息:

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{
但是,由于某种原因,
event
没有满足可序列化
NSMUtableArray
NSDictionary
的所有规则,这会使我的应用程序崩溃

这让我有两个选择。首先,我可以找到一些巧妙的方法将任何对象转换为JSON。或者,我可以从中挑选数据,从头开始编写NSDictionary对象

有没有人知道如何把这种东西分开

在我的
调试器中
,它似乎没有任何响应

> 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,因为它是可序列化的。简而言之,它必须是字符串、数字和其他集合的集合,而不是其他集合

如果您了解该类,则可以获取属性。简而言之,它依赖于
objc_property_t*properties=class_copyPropertyList(klass,&outCount)以获取属性

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

编辑 为了演示,我将此方法添加到另一个答案建议的PropertyUtil类中

+ (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,则返回它。如果操作数是一个数组,则回答使json可序列化的每个元素的数组。如果是字典也是一样的。否则,如果对象是任意的,则应用内省方法获取其属性,为每个属性调用getter并回答json可序列化的问题。

因此我设法获得了所有方法的列表,如下所示:

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])));

我可能还不习惯调试器。但似乎大多数方法都不符合
po
语法,我相信如果我只编写代码并尝试运行应用程序,它们会起作用。你知道有没有一种资源可以让你更容易地使用这段代码,而不是每次我想尝试另一段代码时都要编译我的整个应用程序。。从您的链接问题中实现该类之后,哪个命令将运行
PropertyUtil
的代码?我认为这是一个常见的难题。有时候,当我以这种方式慢下来时,我会做一个小的辅助项目,做我唯一感兴趣的调试工作。您甚至不需要外部库。只需创建一个对象,其中包含一些不会序列化的内容,它是一个类方法,因此您必须在将其添加到的任何类上调用它。它以类作为参数。。。你可以将其作为someId发送到你的ID。class@Trip-我添加了一个方法来更完整地描述递归思想。看看这是否能从不透明对象中生成所需的内容。这很奇怪,因为它符合
KandyEventProtocol
,它应该能够响应
uuid
(小写)和
timestamp
以及
eventType
,根据文档。NSLog(@“Class:%@,[event Class])`返回什么?也许
[event valueForKeyPath:@“uuid”]
会返回一些东西。@Larme Yours是我一直在寻找的答案。谢谢@Larme奇怪的是,
valueForKeyPath
po
一起工作,但在实际应用中不起作用。我想知道在实时和调试环境中使用两个不相关的方法对开发人员有什么好处。您能记录事件的类吗?另外,由于它是一个协议,我猜它并不总是同一个类。您是否可以检查
[event conformsToProtocol:@protocol(KandyEventProtocol)]
,如果没有(这很奇怪),请检查它是否尊重返回
错误的一个()@Larme:找不到“KandyEventProtocol”的协议声明

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])));
KandyChatMessage *chatMessage = (KandyChatMessage*)event;
chatMessage.description;