有没有办法从这个晦涩的对象中获取属性并将其转换为 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
由于某种原因不满足可序列化 NSMUtableArray
或 NSDictionary
的所有规则。
这让我有两个选择。第一,我可以找到一些狡猾的方法将任何对象转换为 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;
我正在使用正在交付 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
由于某种原因不满足可序列化 NSMUtableArray
或 NSDictionary
的所有规则。
这让我有两个选择。第一,我可以找到一些狡猾的方法将任何对象转换为 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;