EasyMapping 0.24.0

EasyMapping 0.24.0

测试测试通过
语言语言 Obj-CObjective C
许可证 MIT
发布日期最后发布2020年8月
SPM支持 SPM

Lucas Medeiros LeiteDenys Telezhkin 维护。



  • 作者
  • Lucas Medeiros 和 Denys Telezhkin

CI codecov.io CocoaPod platform   CocoaPod version   Swift Package Manager compatible License MIT

EasyMapping

一个简单地将属性字典(来自 JSON、XML 或仅限 NSDictionary)拆解到类中并将其反向操作的方法。

联系

Lucas MedeirosDenys 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 KotovDmitriy 对性能进行了大量优化
  • Moya 组织 赞助了出色的自动发布流程。

想法

这个想法来源于

  • RestKit 的映射,它的问题是它不转换自定义值(如字符串值到枚举)
  • Mantle 的映射,但你不需要继承任何类