iOS Mantle + Пальто

Я смотрю на библиотеку Overcoat, которая из того, что я собираю, является библиотекой, расширяющей библиотеку Mantle.

Мантия: https://github.com/Mantle/Mantle/ Пальто: https://github.com/gonzalezreal/Overcoat

На страницах Mantle и Overcoat github постоянно упоминается о создании модели Mantle, но я хочу знать, как мне создать модель Mantle? Нужно ли вводить его вручную или использовать файл Xcode xcdatamodel для его визуального построения, а затем создать подкласс + изменить этот файл впоследствии?

В Базовых данных создайте сущность в файле xcdatamodel, используя Интерфейсный Разработчик, затем используйте Редактор XCode> Создать NSManagedObject подкласс.

Делаем ли мы то же самое для Mantle, а затем меняем NSManagedObject на MTLModel?

Что происходит, когда мы решили обновить сущность Core Data в файле xcdatamodel? Если мы снова создадим файл модели, не придется ли нам снова добавить все эти изменения в класс NSManagedObject?

Супер запутался в процессе.

1 ответ

Хорошо, я думаю, что начинаю понимать это немного больше. После нескольких часов проб и ошибок я смог получить базовое демонстрационное приложение Overcoat, работающее с извлечением Core Data из моего REST API.

Я получил это работать так:

1) Мы создаем сущности внутри файла xcdatamodel, НО НЕ генерируем класс NSManagedObject, используя меню "Редактор"> "Создать классы NSManagedObject".

2) Создайте подкласс модели Mantle для обычной папки проекта правой кнопки мыши (в XCode) > Новый файл> Выберите MTLModel в качестве подкласса и затем вручную введите свойства. Примечательно, что заголовок подкласса должен быть примерно таким:

@interface Book : MTLModel <MTLJSONSerializing, MTLManagedObjectSerializing> 

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

@end

3) Если вы случайно сгенерировали сущность Core Data, такую ​​как я, файл xcdatamodel фактически добавляет имя класса в раздел "Default" в разделе "Configuration" внутри xcdatamodel.

Вам нужно удалить любое значение в столбце "Класс", в противном случае вы получите неудачное сообщение:

"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",
        ...
    })
}

В последнем случае это называется ответом "Envelop" из моего смутного понимания. Для этого типа ответов сервера существует дополнительный шаг, который включает в себя указание 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];
}

Надеюсь, это поможет всем, кто испытывает ту же проблему, пытаясь заставить работать пальто.

Другие вопросы по тегам