RestKit RKMappingResult给出[__NSCFBoolean length]:发送到实例的无法识别的选择器

时间:2016-03-08 16:17:38

标签: objective-c json api restkit

我使用Reskit从纽约时报畅销书JSON API获取数据。我相信我的属性映射存在问题。必须获取的典型JSON对象类似于下面的结构。我的代码也会显示出来。 API调用确实返回与预期结果数匹配的对象,但requestDataFromAPI方法中的RKMappingResult返回“[__NSCFBoolean length]:发送到实例的无法识别的选择器”。我无法访问它们,因为打印书籍没有。我不确定我做错了什么。

{
    "status":"OK",
    "copyright":"Copyright (c) 2016 The New York Times Company.  All Rights Reserved.",
    "num_results":10,
    "last_modified":"2016-03-04T13:12:31-05:00",
    "results":
        {
         "list_name":"Animals",
         "bestsellers_date":"2016-02-27",
         "published_date":"2016-03-13",
         "display_name":"Animals",
         "normal_list_ends_at":10,
         "updated":"MONTHLY",
         "books": [
            {"rank":1,
            "rank_last_week":0,
            "weeks_on_list":0,
            "asterisk":0,
            "dagger":0,
            "primary_isbn10":"0802123414",
            "primary_isbn13":"9780802123411",
            "publisher":"Grove Atlantic",
            "description":"A grief-stricken British woman decides to raise a goshawk, a fierce bird that is notoriously difficult to tame.",
            "price":0,
            "title":"H IS FOR HAWK","author":"Helen Macdonald",
            "contributor":"by Helen Macdonald",

            "isbns": [
                {"isbn10":"0802123414",
                "isbn13":"9780802123411"
                },
                {"isbn10":"1448130727",
                "isbn13":"9781448130726"
                },
                {"isbn10":"1481530968",
                "isbn13":"9781481530965"
                },
                {"isbn10":"148153095X",
                "isbn13":"9781481530958"
                },
                {"isbn10":"1410483614",
                "isbn13":"9781410483614"
                },
                {"isbn10":"0802124739",
                "isbn13":"9780802124739"
                }]
        }
    }

    - (void) initializeRestAPI
    {
        // Initialize RestKit using API base address
        NSURL * baseURL = [NSURL URLWithString:@"http://api.nytimes.com"];
        RKObjectManager * objectManager = [RKObjectManager managerWithBaseURL:baseURL];

        // Initialize Core Data's managed object model from the bundle
        NSManagedObjectModel * managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

        // Initialize RestKit's managed object store
        RKManagedObjectStore * managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
        objectManager.managedObjectStore = managedObjectStore;

        // Complete Core Data stack initialization via RestKit
        [managedObjectStore createPersistentStoreCoordinator];
        NSString * persistentStorePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"DataModel.sqlite"];
        NSString * seedDatabasePath = [[NSBundle mainBundle] pathForResource:@"RKSeedDatabase" ofType:@"sqlite"];
        NSError * error;

        NSPersistentStore * persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:persistentStorePath fromSeedDatabaseAtPath:seedDatabasePath withConfiguration:nil options:nil error:&error];
        NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

        // Create RestKit's managed object contexts
        [managedObjectStore createManagedObjectContexts];

        // Configure a managed object cache
        managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];

        [self setupEntityMappingForObjectStore:managedObjectStore withObjectManager:objectManager];
        [self requestDataFromAPI];
    }

    -(void) setupEntityMappingForObjectStore: (RKManagedObjectStore *) managedObjectStore withObjectManager: (RKObjectManager *) objectManager
    {
        RKEntityMapping * bookListMapping = [RKEntityMapping mappingForEntityForName:@"BookList" inManagedObjectStore:managedObjectStore];
        bookListMapping.identificationAttributes = @[@"listName"];
        [bookListMapping addAttributeMappingsFromDictionary:
                        @{@"results.list_name": @"listName",
                        @"results.bestsellers_date": @"bestsellersDate",
                        @"results.published_date": @"publishedDate",
                        @"results.display_name": @"displayName",
                        @"results.normal_list_ends_at": @"normalListEndsAt",
                        @"results.updated": @"updated"
                        }];

        RKEntityMapping * bookMapping = [RKEntityMapping mappingForEntityForName:@"Book" inManagedObjectStore:managedObjectStore];
        bookMapping.identificationAttributes = @[@"title"];
        [bookMapping addAttributeMappingsFromDictionary:
                    @{@"rank": @"rank",
                    @"rank_last_week": @"rankLastWeek",
                    @"weeks_on_list": @"weeksOnList",
                    @"primary_isbn10": @"primaryIsbn10",
                    @"primary_isbn13": @"primaryIsbn13",
                    @"amazon_product_url": @"productUrl",
                    @"book_image": @"bookImage",
                    @"publisher": @"publisher",
                    @"description": @"bookDescription",
                    @"title": @"title",
                    @"contributor": @"contributor",
                    @"author": @"author",
                    @"price": @"price"
                    }];

        [bookListMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"results.books" toKeyPath:@"books" withMapping:bookMapping]];

        RKResponseDescriptor * bookListResponseDescriptor =
        [RKResponseDescriptor responseDescriptorWithMapping:bookListMapping
                                                 method:RKRequestMethodGET
                                            pathPattern:nil
                                                keyPath:@"results.books"
                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
        ];

        [objectManager addResponseDescriptor:bookListResponseDescriptor];

        // Enable Activity Indicator Spinner
        [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    }

    - (void)fetchBooksFromContext
    {
        NSManagedObjectContext * context = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
        NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"BookList"];
        NSSortDescriptor * descriptor = [NSSortDescriptor sortDescriptorWithKey:@"listName" ascending:YES];
        fetchRequest.sortDescriptors = @[descriptor];
        NSError *error = nil;
        NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
        BookList * bookList = [fetchedObjects firstObject];
        NSArray * books = [bookList.books allObjects];
        //NSArray * books = [fetchedObjects firstObject];
        NSLog(@"Books: %@",books);
    }

    - (void)requestDataFromAPI
    {
        NSDictionary * apiKeyData = [[NSUserDefaults standardUserDefaults] objectForKey:@"apiKeyData"];
        NSString * apiKey = [apiKeyData objectForKey:@"apiKeyData"];
        NSLog(@"requestDataFromAPI apiKey: %@",apiKey);
        NSString * requestPath = [[NSString alloc] initWithFormat:@"/svc/books/v3/lists/%@?&api-key=%@",_categoryListName, apiKey];

        [[RKObjectManager sharedManager]
                getObjectsAtPath:requestPath
                  parameters:nil
                     success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
                                {
                                [self fetchBooksFromContext];
                                }
                      failure: ^(RKObjectRequestOperation *operation, NSError *error)
                                {
                                RKLogError(@"Loading from API failed with error: %@", error);
                                }
         ];
    }

核心数据对象模型如图所示

#import "BookList.h"

NS_ASSUME_NONNULL_BEGIN

@interface BookList (CoreDataProperties)

@property (nullable, nonatomic, retain) NSString *listName;
@property (nullable, nonatomic, retain) NSDate *bestsellersDate;
@property (nullable, nonatomic, retain) NSDate *publishedDate;
@property (nullable, nonatomic, retain) NSString *displayName;
@property (nullable, nonatomic, retain) NSNumber *normalListEndsAt;
@property (nullable, nonatomic, retain) NSString *updated;
@property (nullable, nonatomic, retain) NSSet<Book *> *books;

@end

@interface BookList (CoreDataGeneratedAccessors)

- (void)addBooksObject:(Book *)value;
- (void)removeBooksObject:(Book *)value;
- (void)addBooks:(NSSet<Book *> *)values;
- (void)removeBooks:(NSSet<Book *> *)values;

@end

NS_ASSUME_NONNULL_END

#import "Book.h"

NS_ASSUME_NONNULL_BEGIN

@interface Book (CoreDataProperties)

@property (nullable, nonatomic, retain) NSNumber *rankLastWeek;
@property (nullable, nonatomic, retain) NSNumber *weeksOnList;
@property (nullable, nonatomic, retain) NSString *primaryIsbn10;
@property (nullable, nonatomic, retain) NSString *primaryIsbn13;
@property (nullable, nonatomic, retain) NSString *productUrl;
@property (nullable, nonatomic, retain) NSString *bookImageUrl;
@property (nullable, nonatomic, retain) NSString *publisher;
@property (nullable, nonatomic, retain) NSString *bookDescription;
@property (nullable, nonatomic, retain) NSString *title;
@property (nullable, nonatomic, retain) NSString *contributor;
@property (nullable, nonatomic, retain) NSString *author;
@property (nullable, nonatomic, retain) NSNumber *price;

@end

NS_ASSUME_NONNULL_END

0 个答案:

没有答案