iOS Mantle +大衣

Zha*_*ang 5 ios github-mantle overcoat

我正在看Overcoat图书馆,我收集的是一个扩展Mantle图书馆的图书馆.

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

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

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

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

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

超级混淆了这个过程.

Zha*_*ang 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
Run Code Online (Sandbox Code Playgroud)

3)如果您不小心生成了像我这样的Core Data实体,xcdatamodel文件实际上会在xcdatamodel内的" Configuration " 下的" Default "部分添加类名.

您需要删除"类"列中的任何值,否则您最终会遇到严重崩溃:

"XYZ" is not a subclass of NSManagedObject.
Run Code Online (Sandbox Code Playgroud)

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 @{};
}
Run Code Online (Sandbox Code Playgroud)

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

5)让我更重要的一点是服务器返回响应的方式.

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

例如

// no top level JSON dictionary, purely just an array of results
{
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    },
    {
        title: "ABC",
        ...
    },
}
Run Code Online (Sandbox Code Playgroud)

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

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

在后一种情况下,我的模糊理解中称之为"包络"类型的反应.对于这些类型的服务器响应,还有一个额外的步骤涉及告诉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
Run Code Online (Sandbox Code Playgroud)

5b)在您的APIClient类(应该是其子类OVCHTTPSessionManager)中,重写方法:

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

希望这有助于其他任何有同样问题的人试图让大衣工作.