0

I'm trying to use Mantle and Core Data to build a client for reddit but I keep getting *** Caught exception setting key "upvotes" : [<Thread 0x14c61ba10> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key upvotes. thrown and I can't figure out what's wrong...

I don't think I've missed out anything from the Mantle docs.

Thread+CoreDataProperties.h

#import "Thread.h"

NS_ASSUME_NONNULL_BEGIN

@interface Thread (CoreDataProperties)

@property (nullable, nonatomic, retain) NSString *approvedBy;
@property (nullable, nonatomic, retain) NSNumber *isArchived;
@property (nullable, nonatomic, retain) NSString *author;
@property (nullable, nonatomic, retain) NSString *title;
@property (nullable, nonatomic, retain) NSDate *createdDate;
@property (nullable, nonatomic, retain) NSString *subreddit;
@property (nullable, nonatomic, retain) NSString *domain;
@property (nullable, nonatomic, retain) NSNumber *upvotes;

@end

NS_ASSUME_NONNULL_END

Thread+CoreDataProperties.m

#import "Thread+CoreDataProperties.h"

@implementation Thread (CoreDataProperties)

@dynamic approvedBy;
@dynamic isArchived;
@dynamic author;
@dynamic title;
@dynamic createdDate;
@dynamic subreddit;
@dynamic domain;
@dynamic upvotes;

@end

Thread.h

@import Foundation;
@import CoreData;
@import Mantle;
@import MTLManagedObjectAdapter;

NS_ASSUME_NONNULL_BEGIN

@interface Thread : MTLModel <MTLJSONSerializing, MTLManagedObjectSerializing>

// Insert code here to declare functionality of your managed object subclass

@end

NS_ASSUME_NONNULL_END

#import "Thread+CoreDataProperties.h"

Thread.m

#import "Thread.h"
#import <Mantle/MTLValueTransformer.h>

@implementation Thread

#pragma mark MTLManagedObjectSerializing Protocols

+ (NSString *)managedObjectEntityName
{
    return @"Thread";
}

+ (NSDictionary *)managedObjectKeysByPropertyKey
{
    return @{
             @"approvedBy": @"approvedBy",
             @"isArchived": @"isArchived",
             @"author": @"author",
             @"title": @"title",
             @"createdDate": @"createdDate",
             @"subreddit": @"subreddit",
             @"domain": @"domain",
             @"upvotes": @"upvotes"
             };
}

+ (NSSet *)propertyKeysForManagedObjectUniquing {
    return [NSSet setWithObjects:@"approvedBy",@"isArchived",@"author",@"title",@"createdDate",@"subreddit",@"domain",@"upvotes", nil];
}

#pragma mark MTLJSONSerializing Protocols

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{
             @"approvedBy": @"approved_by",
             @"isArchived": @"archived",
//             @"author": @"author",
//             @"title": @"title",
             @"createdDate": @"created",
//             @"subreddit": @"subreddit",
//             @"domain": @"domain",
             @"upvotes": @"ups"
             };
}

+ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key {
    if ([key isEqualToString:@"createdDate"]) {
        return [Thread dateJSONTransformer];
    }

    return nil;
}

+ (NSValueTransformer *)dateJSONTransformer {
    return [MTLValueTransformer transformerUsingForwardBlock:^id(NSNumber *unixTimestamp, BOOL *success, NSError *__autoreleasing *error) {
        return [NSDate dateWithTimeIntervalSince1970:unixTimestamp.doubleValue];
    } reverseBlock:^id(NSDate *date, BOOL *success, NSError *__autoreleasing *error) {
        return [NSNumber numberWithDouble:[date timeIntervalSince1970]];
    }];
}

@end
Liau Jian Jie
  • 7,071
  • 2
  • 15
  • 16
  • 1
    I'm not sure what Mantle is but, are you using the correct model version? Select your .xcdatamodeld file, click on File Inspector, go down to Model Version and make sure you're using a Model Version with a Thread entity containing the upVotes attribute. – Jonathan Dec 26 '15 at 15:31
  • 1
    Looks like Mantle creates more problems than it solves. This is way more verbose than just matching the properties and attributes without a framework. – Mundi Dec 26 '15 at 15:46
  • @Jonathan Mantle is a library for writing a simple model layer for Cocoa apps (that needs to deal with RESTful APIs). I've not dealt with model versioning before, but it's unlikely that is because of that—I literally just hacked up all of the code in 2 hours and I haven't done any model versioning. – Liau Jian Jie Dec 26 '15 at 15:48
  • @Mundi In most cases, yeah. With Mantle, I don't need so much boilerplate code for NSCoding & NSCopying protocols though. I've actually went ahead to remove Mantle... But even so, I'm really puzzled by this weird behaviour. – Liau Jian Jie Dec 26 '15 at 15:56

1 Answers1

0

I can't see how your declaration of Thread class relates to NSManagedObject. You've re-declared it as MTLModel, which is subclass of NSObject. Of course it have no upvotes or any other property defined in CoreDataProperties category since those properties are dynamic, and there will be no Core Data runtime support to provide implementation for them.

You should undo that change to Thread.h, or just delete those four files and recreate them with Xcode.

And about Mantle: I don't think that it directly supports Core Data. See here.

bteapot
  • 1,897
  • 16
  • 24
  • Mantle has an [adapter](https://github.com/Mantle/MTLManagedObjectAdapter) (now decoupled from Mantle itself) that converts between MTLModel instances and Core Data managed objects. – Liau Jian Jie Dec 26 '15 at 16:40
  • Then it obviously does not do what it should :) Maybe some misconfiguration? You can check it by instantiating a `Thread` object an query it for some `NSManagedObject` methods like `managedObjectContext`. – bteapot Dec 26 '15 at 16:46