测试已测试 | ✓ |
语言语言 | Obj-CObjective C |
许可证 | MIT |
发布最新版本 | Nov 2016 |
SPM支持 SPM | ✓ |
由Elvis Nuñez维护。
SYNCPropertyMapper利用您的Core Data模型来推断如何将您的JSON值映射到Core Data。它很简单,也很明显。为什么每个人都没有这样做呢?
使用你提供的JSON后端映射你的Core Data对象从未如此简单。
{
"firstName": "John",
"lastName": "Hyperseed"
}
NSDictionary *values = [JSON valueForKey:@"user"];
[user hyp_fillWithDictionary:values];
let userJSON = JSON["user"]
user.hyp_fill(with: userJSON)
您的Core Data实体应与您的后端模型匹配。您的属性应与它们的JSON对应物匹配。例如,firstName
映射到firstName
,address
映射到address
。
{
"first_name": "John",
"last_name": "Hyperseed"
}
NSDictionary *values = [JSON valueForKey:@"user"];
[user hyp_fillWithDictionary:values];
let userJSON = JSON["user"]
user.hyp_fill(with: userJSON)
您的Core Data实体应与您的后端模型匹配,但在camelCase
中。您的属性应与它们的JSON对应物匹配。例如,first_name
映射到firstName
,address
映射到address
。
这很直接,应该如您所期望的那样工作。JSON字符串映射为NSString和double、float、ints等,映射为NSNumber。
我们默认支持ISO 8601和Unix时间戳,因为这些是解析日期时最常用的格式。我们还有一种相当高效的方式来解析这些字符串,这克服了使用NSDateFormatter
的性能问题。
NSDictionary *values = @{@"created_at" : @"2014-01-01T00:00:00+00:00",
@"updated_at" : @"2014-01-02",
@"published_at": @"1441843200"
@"number_of_attendes": @20};
[managedObject hyp_fillWithDictionary:values];
NSDate *createdAt = [managedObject valueForKey:@"createdAt"];
// ==> "2014-01-01 00:00:00 +00:00"
NSDate *updatedAt = [managedObject valueForKey:@"updatedAt"];
// ==> "2014-01-02 00:00:00 +00:00"
NSDate *publishedAt = [managedObject valueForKey:@"publishedAt"];
// ==> "2015-09-10 00:00:00 +00:00"
如果您的日期不符合ISO 8601规范,您也可以使用变压器属性来解析日期。首先将您的属性设置为Transformable
,然后在示例中,将其名称设置为DateStringTransformer
。
您可以在DateStringTransformer中找到日期变换器的示例。
在Core Data模型器上,首先将属性设置为Binary Data
以进行数组映射。
let values = ["hobbies" : ["football", "soccer", "code"]]
managedObject.hyp_fill(with: values)
let hobbies = NSKeyedUnarchiver.unarchiveObject(with: managedObject.hobbies) as! [String]
// ==> "football", "soccer", "code"
在Core Data模型器上,首先将属性设置为Binary Data
以进行字典映射。
let values = ["expenses" : ["cake" : 12.50, "juice" : 0.50]]
managedObject.hyp_fill(with: values)
let expenses = NSKeyedUnarchiver.unarchiveObject(with: managedObject.expenses) as! [String: Any]
// ==> "cake" : 12.50, "juice" : 0.50
这个规则有两个例外。
id
应与remoteID
匹配。entityName
(例如,type
变为userType
,description
变为userDescription
等)。在JSON中它们不需要改变,例如,您可以用type
和description
保持不变。预留属性的完整列表可以在这里找到。hyper.remoteKey
并输入您想要的映射值。{
"id": 1,
"name": "John Monad",
"company": {
"name": "IKEA"
}
}
在这个例子中,如果您想避免为公司创建Core Data实体,您可以直接映射到公司的名称。通过将此添加到companyName
字段的用户信息。
hyper.remoteKey = company.name
有时REST API中的值不是您想要的形式,这导致您必须扩展模型类以包含转换为值的方法和/或属性。甚至可能需要预处理JSON才能使用SYNCPropertyMapper
。幸运的是,大多数这种情况可以通过使用ValueTransformer
来解决。
例如,在我的用户模型中,我不再得到这个:
{
"name": "Bob Dylan"
}
我们的后端开发人员决定他更喜欢数组,所以我们得到这个:
{
"name": [
"Bob Dylan"
]
}
由于SYNCPropertyMapper
期望一个值为Bob Dylan
的name
,我们必须在将其传入Core Data之前预处理这个值。为此,我们将首先创建一个ValueTransformer
的子类。
import Foundation
class BadAPIValueTransformer : ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return String.self as! AnyClass
}
override class func allowsReverseTransformation() -> Bool {
return true
}
// Used to transform before inserting into Core Data using `hyp_fill(with:)
override func transformedValue(_ value: Any?) -> Any? {
guard let valueToTransform = value as? Array<String> else {
return value
}
return valueToTransform.first!
}
// Used to transform before exporting into JSON using `hyp_dictionary`
override func reverseTransformedValue(_ value: Any?) -> Any? {
guard let stringValue = value as? String else { return value }
return [stringValue]
}
}
然后,我们将在Core Data属性的用户键中添加另一个项。键为hyper.valueTransformer
,值为BadAPIValueTransformer
。
然后在执行hyp_fill(with:]
之前,我们将做到以下几点:
ValueTransformer.setValueTransformer(BadAPIValueTransformer(), forName: NSValueTransformerName(rawValue: "BadAPIValueTransformer"))
这样!然后您的名字将是Bob Dylan
,恭喜您获得诺贝尔和平奖。
顺便说一下,这也一样有效!所以使用hyp_dictionary
将返回["Bob Dylan"]
。
UserManagedObject *user;
[user setValue:@"John" forKey:@"firstName"];
[user setValue:@"Hyperseed" forKey:@"lastName"];
NSDictionary *userValues = [user hyp_dictionary];
这就是所有必须做的事情,键将奇迹般地转换为snake_case
约定。
{
"first_name": "John",
"last_name": "Hyperseed"
}
如果您不希望导出属性/关系,您可以在排除属性或关系的用户信息中添加hyper.nonExportable
以禁止导出。
它也支持关系,例如,对于有多个笔记的用户,我们向 Rails 规则 accepts_nested_attributes_for
投诉
"first_name": "John",
"last_name": "Hyperseed",
"notes_attributes": [
{
"0": {
"id": 0,
"text": "This is the text for the note A"
},
"1": {
"id": 1,
"text": "This is the text for the note B"
}
}
]
如果不想获取嵌套关系,也可以忽略关系
let dictionary = user.hyp_dictionary(using: .none)
"first_name": "John",
"last_name": "Hyperseed"
或者作为数组获取
let dictionary = user.hyp_dictionary(using: .array)
"first_name": "John",
"last_name": "Hyperseed",
"notes": [
{
"id": 0,
"text": "This is the text for the note A"
},
{
"id": 1,
"text": "This is the text for the note B"
}
]
SYNCPropertyMapper 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile
use_frameworks!
pod 'SYNCPropertyMapper', '~> 5'
SYNCPropertyMapper 也通过 Carthage 提供。要安装它,只需在 Cartfile 中添加以下行
github "SyncDB/SYNCPropertyMapper" ~> 5.0
请参考 Hyper 的 playbook 获取贡献指南。
Hyper 制作了这个。我们是一家对良好代码充满热情的数字传播机构,如果您正在使用这个库,我们可能希望 雇佣您。
SYNCPropertyMapper 在 MIT 许可下提供。有关更多信息,请参阅 LICENSE 文件。