5

我正在查看 Overcoat 库,我收集到的是一个扩展 Mantle 库的库。

地幔:https ://github.com/Mantle/Mantle/ 大衣:https ://github.com/gonzalezreal/Overcoat

Mantle 和 Overcoat github 页面不断提到创建 Mantle 模型,但我想知道如何生成 Mantle 模型?我是手动输入还是使用 Xcode xcdatamodel 文件以可视方式构建它,然后生成 sublass + 之后修改该文件?

在 Core Data 中,使用 Interface Builder 在 xcdatamodel 文件中创建实体,然后使用 Xcode 的 Editor > Create NSManagedObject 子类。

我们是否对 Mantle 做同样的事情,然后从 NSManagedObject 更改为 MTLModel ?

当我们决定更新 xcdatamodel 文件中的 Core Data 实体时会发生什么?如果我们再次重新生成模型文件,我们是否必须将所有这些更改重新添加到 NSManagedObject 类中?

对这个过程超级困惑。

4

1 回答 1

12

好的,我想我开始掌握更多了。经过几个小时的反复试验,我能够获得一个基本的 Overcoat 演示应用程序,该应用程序使用从我的 REST API 中提取的 Core Data。

我让它像这样工作:

1) 我们在 xcdatamodel 文件中创建实体,但不要使用 Editor > Create NSManagedObject Classes 菜单生成 NSManagedObject 类。

2)根据正常的右键单击项目文件夹(在Xcode中)>新建文件>选择MTLModel作为子类创建Mantle模型子类,然后手动输入属性。值得注意的是,子类标题应该是这样的:

@interface Book : MTLModel <MTLJSONSerializing, MTLManagedObjectSerializing> 

@property (nonatomic, copy) NSString *title;
...

@end

3)如果你像我一样不小心生成了Core Data实体,xcdatamodel文件实际上是在xcdatamodel里面的“ Configuration ”下的“ Default ”部分添加了类名。

您需要删除“类”列中的任何值,否则最终会出现严重崩溃:

"XYZ" is not a subclass of NSManagedObject.

4) 确保在您的 Mantle 模型类中实现 MTLJSONSerialization 和 MTLManagedObjectSerializing 的序列化方法。

#pragma mark - MTLJSONSerialization -

+(NSDictionary *)JSONKeyPathsByPropertyKey
{    
    return @{
             @"title": @"title",
             ...
             };
}

#pragma mark - MTLManagedObjectSerializing -

+(NSString *)managedObjectEntityName
{
    // ------------------------------------------------
    // If you have a Core Data entity called "Book"
    // then you return @"Book";
    //
    // Don't return the Mantle model class name here.
    // ------------------------------------------------
    return @"TheCoreDataEntityName";
}

+(NSDictionary *)managedObjectKeysByPropertyKey
{
    // ------------------------------------------------
    // not really sure what this does, I just put 
    // it in as the example does it too
    // ------------------------------------------------
    return @{};
}

这些方法本质上是将 JSON 响应从服务器映射到核心数据实体的粘合剂。

5)让我更重要的一件事情是服务器返回响应的方式。

您的服务器可能使用 HTTP 状态代码,但没有顶级 JSON 字典

例如

// no top level JSON dictionary, purely just an array of results
{
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    },
}

然而,其他类型的 REST 服务器可能会返回顶级 JSON 字典,其结果键路径位于子级别,如下所示:

{
    count: 20,
    next: "http://www.server.com/api/resource?page=2",
    previous: null,
    results:(
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    })
}

在后一种情况下,根据我的模糊理解,这被称为“信封”类型的响应。对于这些类型的服务器响应,有一个额外的步骤涉及告诉 Overcoat 结果键路径数组在 JSON 响应中的位置。

为此,我们需要:

5a) 创建一个 ServerResponse 类,它是 OVCresponse 的子类:

// .h file
#import "OVCResponse.h"

@interface ServerResponse : OVCResponse

@end

// .m file
@implementation ServerResponse

+(NSString *)resultKeyPathForJSONDictionary:(NSDictionary *)JSONDictionary
{
    // --------------------------------------------------------------------
    // we're telling Overcoat, the array of entities is found under the
    // "results" key-value pair in the server response JSON dictionary
    // --------------------------------------------------------------------
    return @"results";
}

@end

5b) 在您的 APIClient 类(应该是 的子类OVCHTTPSessionManager)中,覆盖该方法:

+(Class)responseClass
{
    // --------------------------------------------------
    // ServerResponse class will let Overcoat know 
    // where to find the results array
    // --------------------------------------------------
    return [ServerResponse class];
}

希望这可以帮助其他遇到同样问题的人尝试让 Overcoat 工作。

于 2014-08-12T09:19:36.110 回答