如果我有一本字典
{
name: "Bob",
cars: [
{ make: "ford", year: "1972" },
{ make: "mazda", year: "2000" }
],
}
Run Code Online (Sandbox Code Playgroud)
和两个模型,如:
@interface CarModel : MTLModel
@property (nonatomic, strong) NSString *make;
@property (nonatomic, strong) NSString *year;
@end
@interface PersonModel : MTLModel
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *cars;
@end
Run Code Online (Sandbox Code Playgroud)
我如何使用Mantle以便我的人模型中的汽车阵列是CarModels?
我正在构建一个需要大量JSON数据处理的应用程序.在讨论了不同的框架之后,由于其丰富的功能集和易用性,我选择了JSONModel(https://github.com/icanzilb/JSONModel)和github Mantle(https://github.com/github/Mantle). .
它们在功能方面非常相似,如数据转换,归档,复制,自动和自定义键映射等.但是,JSONModel有一些额外的开箱即用映射选项和内置模型级联支持,Mantle是相对更受欢迎,显然github支持它背后.
对我而言,性能和易用性很重要,所以我只是想知道是否有人在使用它们时都有真正的经验并且可以分享,主要是在性能和易用性方面.
由于许多内置的键映射选项和模型级联,我自己倾向于JSONModel,但不确定如何使用大型数据集执行.
编辑(2015年4月28日):我最终使用Github Mantle,因为它与我的应用程序架构完美融合,而且它有更多的模块化设计,您可以插入自己的属性格式化程序,核心数据支持,嵌套模型,以及什么不是.
已经使用了近2年,从来没有遇到过它对我不起作用的情况,不开玩笑!它与AFNetworking或Alamofire框架配合使用,适用于Swift.我试图寻找替代方案,当Swift支持仍然很小的补丁,男人,我甚至远远不能找到任何东西.
我有从MTLModel继承的MyModel(使用GitHub Mantle pod).MyModel.h
#import <Mantle/Mantle.h>
@interface MyModel : MTLModel <MTLJSONSerializing>
@property (nonatomic, copy, readonly) NSString *UUID;
@property (nonatomic, copy) NSString *someProp;
@property (nonatomic, copy) NSString *anotherProp;
@end
Run Code Online (Sandbox Code Playgroud)
MyModel.m
#import "MyModel.h"
@implementation MyModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return @{
@"UUID": @"id",
@"someProp": @"some_prop",
@"anotherProp": @"another"
};
}
}
@end
Run Code Online (Sandbox Code Playgroud)
现在我想使用AFNetworking将JSON发送到后端.在此之前,我将模型实例转换为JSON NSDictionary,以在我的请求中用作参数/主体有效负载.
NSDictionary *JSON = [MTLJSONAdapter JSONDictionaryFromModel:myModel];
Run Code Online (Sandbox Code Playgroud)
但是这个JSON包含奇怪的""字符串,用于我的模型属性为零.我想要的是Mantle省略这些键/值对,只吐出一个只有非nil或NSNull.null属性的JSON,无论如何.
我正在使用Mantle来解析一些通常看起来像这样的JSON:
"fields": {
"foobar": 41
}
Run Code Online (Sandbox Code Playgroud)
但是有时foobar的值为null:
"fields": {
"foobar": null
}
Run Code Online (Sandbox Code Playgroud)
这会导致MTLValidateAndSetValue抛出异常,因为它试图通过键值编码设置nil值.
我想要做的是检测此null值的存在并用-1替换它.
我尝试覆盖foobarJSONTransformer我的MTLModel子类,如下所示:
+ (NSValueTransformer *)foobarJSONTransformer {
return [MTLValueTransformer transformerWithBlock:^id(id inObj) {
if (inObj == [NSNull null]) {
return [NSNumber numberWithInteger: -1];
} else {
return inObj;
}
}];
Run Code Online (Sandbox Code Playgroud)
...我可以看到这个代码被调用但是inObj永远不会等于[NSNull null],因此替换不会发生,并且Mantle仍然抛出异常.
捕获此JSON null case并进行替换的正确方法是什么?
在地幔中是否有办法更新核心数据中的现有记录而不是总是创建新记录?这篇博客文章看起来很有希望,但我没有updateWithJSON:在Mantle的某个地方找到这个方法.现在,我正在做以下事情:
MantleObject *mantleObject = [MTLJSONAdapter modelOfClass:[MantleObject class] fromJSONDictionary:dictionary error:NULL];
CoreDataObject *coreDataObject = [CoreDataObject MR_findFirstByAttribute:@"primaryKey" withValue:mantleObject.primaryKey];
// avoid duplicates
if (coreDataObject != nil) {
[coreDataObject MR_deleteEntity];
}
[MTLManagedObjectAdapter managedObjectFromModel:mantleObject insertingIntoContext:[NSManagedObjectContext MR_contextForCurrentThread] error:NULL];
Run Code Online (Sandbox Code Playgroud)
它按预期工作,但我不喜欢总是一遍又一遍地删除和创建"相同"对象的想法.所以我希望有机会更新现有的对象(覆盖很好;新对象的所有值都可以替换现有对象).
在使用Mantle时,是否有可能在返回我们正在创建的对象之前(在这种情况下通过JSON)来验证X和Y属性是否为零?
想象一下这堂课:
@interface Person : MTLModel <MTLJSONSerializing>
@property(nonatomic,strong,readonly)NSString *name;
@property(nonatomic,strong,readonly)NSString *age;
@end
Run Code Online (Sandbox Code Playgroud)
我想要一种方法来验证如果我收到的JSON没有name(由于某种原因在服务器的DB上存在问题),我将返回一个nilPerson,因为没有该属性集创建该对象没有意义.
我需要你的帮助,因为我无法理解这一点.我在iOS中使用Mantle和CoreData.
我的关系定义如下:
帖子1:N评论
当我从我的REST服务中提取数据时,我创建了一个Mantle对象帖子,其中包含一个NSMutableArray of Comments.这完美无瑕.
然后我将其存储在Core Data中,这是我不知道我是否正确行事的地方.
[MTLManagedObjectAdapter managedObjectFromModel:post insertingIntoContext:[self getManagedObjectContext] error:&error];
Run Code Online (Sandbox Code Playgroud)
所以我这样做是为了将我的帖子对象存储到Core Data中.核心数据模型具有称为"post_has_comments"的关系,这是一种级联的一对多关系.所以在对象帖子上我有"posts_has_comments" - >级联,在我的对象"评论"上我与"Nullify"有一对一的关系.
Afaik,Core Data将其视为NSSet.我试图放入的是一个NSMutableArray,因为Mantle会照顾这个(至少那是它的源代码中的快速看起来告诉我的).
不幸的是,当我从Core Data获取对象时
Post* post = [MTLManagedObjectAdapter modelOfClass:Post.class fromManagedObject:[[self fetchedResultsController] objectAtIndexPath:indexPath] error:nil];
Run Code Online (Sandbox Code Playgroud)
对post对象的属性注释是一个空的NSSet,并且在事先插入事物时我遇到了一些错误.我得到的错误:
Core Data: annotation: repairing missing delete propagation for to-many relationship post_has_comments on object [...]
Run Code Online (Sandbox Code Playgroud)
我被卡住了 - 也许我错过了一些巨大的东西?
My Post Class实现以下静态方法:
+ (NSDictionary *)managedObjectKeysByPropertyKey {
return @{
@"post_id" : @"id",
@"comments" : @"post_has_comments"
};
}
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"post_id" : @"id",
};
}
+ (NSDictionary …Run Code Online (Sandbox Code Playgroud) @interface Entity ()
@property (assign) int searchTotalPagesAll;
@property (assign) int searchTotalPagesIdeas;
@end
@implementation Entity
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"Id": @"entity.id_entity",
@"name": @"entity.name",
@"coverage" : @"entity.coverage",
@"id_city": @"entity.Id_City",
@"cityName":@"entity.city",
@"countryName":@"entity.country",
@"stateName":@"entity.district",
@"countryCode": @"entity.countrycode",
@"keyword1": @"entity.key1",
... etc
Run Code Online (Sandbox Code Playgroud)
由于mantle示例没有init方法,我应该在哪里初始化这些属性(searchTotalPagesAll,searchTotalPagesIdeas)以获取默认值?此模型具有需要此内容和其他几个属性的内部方法.
我有一些看起来像这样的json数据:
{
items: [
{ // object 1
aProperty: "aValue",
anotherProperty: "anotherValue",
anObjectProperty: {}
},
{ //object 2
aProperty: "aValue",
anotherProperty: "anotherValue",
anObjectProperty: {}
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想使用Mantle将这个json映射到两个对象的数组中.
这将如下所示:
@interface MyObject : MTLModel <MTLJSONSerializing>
@property (nonatomic, strong) NSString *myProperty;
@property (nonatomic, strong) NSString *anotherProperty;
@property (nonatomic, strong) NSObject *anObject;
@end
@implementation MyObject
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"myProperty": @"myProperty",
@"anotherProperty" : @"anotherProperty",
@"anObject": @"anObject"
};
}
@end
Run Code Online (Sandbox Code Playgroud)
但是,这需要我去json中找到"items"键,然后解析该键内部的内容.
相反,我希望Mantle只为我绘制整个对象.所以,我提出了这个解决方案:
@interface MyObjects : MTLModel <MTLJSONSerializing>
@property (nonatomic) NSArray *items;
@end …Run Code Online (Sandbox Code Playgroud) 如何使用Github Mantle根据同一类中的另一个属性选择属性类?(或者更坏的情况是JSON对象的另一部分).
例如,如果我有这样的对象:
{
"content": {"mention_text": "some text"},
"created_at": 1411750819000,
"id": 600,
"type": "mention"
}
Run Code Online (Sandbox Code Playgroud)
我想做一个像这样的变压器:
+(NSValueTransformer *)contentJSONTransformer {
return [MTLValueTransformer transformerWithBlock:^id(NSDictionary* contentDict) {
return [MTLJSONAdapter modelOfClass:ETMentionActivityContent.class fromJSONDictionary:contentDict error:nil];
}];
}
Run Code Online (Sandbox Code Playgroud)
但传递给变换器的字典只包含JSON的"内容"部分,因此我无法访问"类型"字段.反正有没有访问对象的其余部分?或者以某种方式将"内容"的模型类基于"类型"?
我之前被迫做过这样的黑客攻击解决方案:
+(NSValueTransformer *)contentJSONTransformer {
return [MTLValueTransformer transformerWithBlock:^id(NSDictionary* contentDict) {
if (contentDict[@"mention_text"]) {
return [MTLJSONAdapter modelOfClass:ETMentionActivityContent.class fromJSONDictionary:contentDict error:nil];
} else {
return [MTLJSONAdapter modelOfClass:ETActivityContent.class fromJSONDictionary:contentDict error:nil];
}
}];
}
Run Code Online (Sandbox Code Playgroud) github-mantle ×10
ios ×9
objective-c ×6
core-data ×2
json ×2
frameworks ×1
ios7 ×1
jsonmodel ×1