EasyMapping
一个简单地将属性字典(来自 JSON、XML 或仅限 NSDictionary)拆解到类中并将其反向操作的方法。
联系
由 Lucas Medeiros 和 Denys Telezhkin 开发
电子邮件: [email protected]
需求
- Xcode 11 和更高版本
- iOS 9 / tvOS 9 和更高版本
- Mac OS X 10.10 和更高版本
- watchOS 2.0 和更高版本
- ARC
安装
Swift Package Manager(需要 Xcode 11)
将包添加到项目设置->Swift Packages
CocoaPods
pod 'EasyMapping', '~> 0.20'
Carthage
github "EasyMapping/EasyMapping"
使用方法
- 假设你有一些类
typedef enum {
GenderMale,
GenderFemale
} Gender;
@interface Person : NSObject <EKMappingProtocol>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, assign) Gender gender;
@property (nonatomic, strong) Car *car;
@property (nonatomic, strong) NSArray *phones;
@property (nonatomic, strong) NSURL * socialURL;
@end
@interface Car : NSObject <EKMappingProtocol>
@property (nonatomic, copy) NSString *model;
@property (nonatomic, copy) NSString *year;
@property (nonatomic, strong) NSDate *createdAt;
@end
@interface Phone : NSObject <EKMappingProtocol>
@property (nonatomic, copy) NSString *DDI;
@property (nonatomic, copy) NSString *DDD;
@property (nonatomic, copy) NSString *number;
@end
@interface Native : NSObject <EKMappingProtocol>
@property (nonatomic, readwrite) NSInteger integerProperty;
@property (nonatomic, readwrite) NSUInteger unsignedIntegerProperty;
@property (nonatomic, readwrite) CGFloat cgFloatProperty;
@property (nonatomic, readwrite) double doubleProperty;
@property (nonatomic, readwrite) BOOL boolProperty;
@end
- 映射变得像实现一个方法那么简单
@implementation Person
+(EKObjectMapping *)objectMapping
{
return [EKObjectMapping mappingForClass:self withBlock:^(EKObjectMapping *mapping) {
NSDictionary *genders = @{ @"male": @(GenderMale), @"female": @(GenderFemale) };
[mapping mapPropertiesFromArray:@[@"name", @"email"]];
[mapping mapKeyPath:@"gender" toProperty:@"gender" withValueBlock:^(NSString *key, id value) {
return genders[value];
} reverseBlock:^id(id value) {
return [genders allKeysForObject:value].lastObject;
}];
[mapping mapKeyPath:@"socialURL" toProperty:@"socialURL"
withValueBlock:[EKMappingBlocks urlMappingBlock]
reverseBlock:[EKMappingBlocks urlReverseMappingBlock]];
[mapping hasOne:[Car class] forKeyPath:@"car"];
[mapping hasMany:[Phone class] forKeyPath:@"phones"];
}];
}
@end
@implementation Car
+(EKObjectMapping *)objectMapping
{
return [EKObjectMapping mappingForClass:self withBlock:^(EKObjectMapping *mapping) {
[mapping mapPropertiesFromArray:@[@"model", @"year"]];
[mapping mapKeyPath:@"created_at" toProperty:@"createdAt" withDateFormatter:[NSDateFormatter ek_formatterForCurrentThread]];
}];
}
@end
@implementation Phone
+(EKObjectMapping *)objectMapping
{
return [EKObjectMapping mappingForClass:self withBlock:^(EKObjectMapping *mapping) {
[mapping mapPropertiesFromArray:@[@"number"]];
[mapping mapPropertiesFromDictionary:@{
@"ddi" : @"DDI",
@"ddd" : @"DDD"
}];
}];
}
@end
@implementation Native
+(EKObjectMapping *)objectMapping
{
return [EKObjectMapping mappingForClass:self withBlock:^(EKObjectMapping *mapping) {
[mapping mapPropertiesFromArray:@[
@"integerProperty", @"unsignedIntegerProperty",
@"cgFloatProperty", @"doubleProperty",
@"boolProperty"
]];
}];
}
@end
- 将 NSDictionary 或 NSArray 转换为对象类或集合现在变得容易
Person *person = [EKMapper objectFromExternalRepresentation:personRepresentation
withMapping:[Person objectMapping]];
NSArray *carsArray = [EKMapper arrayOfObjectsFromExternalRepresentation:carsRepresentation
withMapping:[Car objectMapping]];
- 将对象/集合转换为 NSDictionary/NSArray
NSDictionary *representation = [EKSerializer serializeObject:car withMapping:[Car objectMapping]];
NSArray *collectionRepresentation = [EKSerializer serializeCollection:cars withMapping:[Car objectMapping]];
- 填充现有对象
假设你有类似这样的事情
Person *person = [Person alloc] init]
要填充一个已经实例化的对象,你可以这样做
[EKMapper fillObject:person fromExternalRepresentation:personRepresentation withMapping:[Person objectMapping]];
Swift
EasyMapping 与 Swift 部分兼容。关于 EasyMapping 在 Swift 中的使用和当前局限性,请查看详细说明。
便利类
EasyMapping 提供了两个便利基类:EKObjectModel 和 EKManagedObjectModel,默认实现 EKMappingProtocol。例如,类 Person 继承自 EKObjectModel 并实现 objectMapping 方法,从 JSON 表示形式创建 Person 实例只需以下步骤
NSDictionary * parsedPersonInfo = ...;
Person * person = [Person objectWithProperties:parsedPersonInfo];
如果 Person 是 EKManagedObjectModel 子类的 Core Data 变体
NSDictionary * parsedPersonInfo = ...;
Person * person = [Person objectWithProperties:parsedPersonInfo inContext:context];
转换为 NSDictionary 更容易
NSDictionary * info = [person serializedObject];
CoreData
如果你正在使用 CoreData 对象,请使用 EKManagedObjectMapping
而不是 EKObjectMapping
。EasyMapping 通过扫描提供的 JSON 并批量获取所有现有对象,尝试加快数据库导入的速度。提供的 JSON 越详细,速度提升就越大。
递归映射
有时你可能会遇到 JSON 包含指向相同类型对象的链接的情况。一个很好的例子就是评论和评论的回复,它们具有树状结构。从 0.7.0 版本开始,EasyMapping 完全支持递归映射。
感谢
感谢以下人士
- basitali 为 EKMapper 添加了 fillObject 功能!
- Alejandro 添加了对 CoreData 的支持!
- Philip Vasilchenko 添加了对标量类型的序列化和反序列化功能!
- Dany L'Hébreux 为 Nashet 添加了支持!
- Jack 添加了 mapFieldsFromMappingObject 和 mapFieldsFromArrayToPascalCase 功能
- Yuri Kotov 和 Dmitriy 对性能进行了大量优化
- Moya 组织 赞助了出色的自动发布流程。
想法
这个想法来源于