我一直在努力让我的项目使用 RestKit 将我的 JSON 对象保存到 Core Data 中。我有 RestKit 0.10.2 并且经历了大杂烩的教程并在这里拼凑了一些东西。当我的 Event 是一个 NSObject 时,我之前已经取得了成功,并且我没有实现 Core Data。现在我使用 Core Data 进行持久性,我在将 JSON 导入数据库时遇到了问题。我尝试过的所有操作要么用 [0] 对象调用 objecLoader,要么像现在这样,我无法调用 objectLoader。
显示 JSON 后我的 Xcode 控制台输出显示以下消息:
2012-12-11 19:44:43.508 fish[19404:15b03] I restkit.core_data:RKInMemoryManagedObjectCache.m:34 Creating thread-local entity cache for managed object context: <NSManagedObjectContext: 0x11249470>
2012-12-11 19:44:43.508 fish[19404:15b03] I restkit.core_data:RKInMemoryManagedObjectCache.m:50 Caching instances of Entity 'Event' by primary key attribute 'eventId'
并在此时挂起:
libobjc.A.dylib`property_getAttributes:
0x1cecd27: pushl %ebp
0x1cecd28: movl %esp, %ebp
0x1cecd2a: movl 8(%ebp), %eax
0x1cecd2d: movl 4(%eax), %eax
0x1cecd30: popl %ebp
0x1cecd31: ret
根视图控制器.h
@interface RootViewController : UITableViewController <CLLocationManagerDelegate, RKObjectLoaderDelegate> {
NSArray *eventsArray;
NSManagedObjectContext *managedObjectContext;
CLLocationManager *locationManager;
UIBarButtonItem *addButton;
User *user;
RKClient *client;
RKObjectManager *objectManager;
NSArray *data;
}
@property (nonatomic, retain) NSArray *eventsArray;
@property (nonatomic, retain) NSArray *data;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, retain) UIBarButtonItem *addButton;
@property (nonatomic, retain) User *user;
@property (nonatomic, retain) RKClient *client;
@property (nonatomic, retain) RKObjectManager *objectManager;
rootViewcontroller.m
@implementation RootViewController
@synthesize eventsArray, managedObjectContext, addButton, locationManager;
@synthesize objectManager;
@synthesize user, client, data;
#pragma mark -
#pragma mark View lifecycle
- (User *)user {
if (user == nil) {
//NSURL *url = [NSURL URLWithString:[ObjectiveResourceConfig getSite]];
self.user = [User currentUserForSite:gBaseURL];
[user addObserver:self];
}
return user;
}
- (void)viewDidLoad {
LocationsAppDelegate *appDelegate = (LocationsAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
[self configureRestKit];
client = appDelegate.client;
// Initialize RestKit
RKURL *baseURL = [RKURL URLWithBaseURL:gBaseURL];
objectManager = [RKObjectManager sharedManager];
objectManager = [RKObjectManager managerWithBaseURL:gBaseURL];
objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
objectManager.client.baseURL = baseURL;
objectManager.client.username = self.user.login;
objectManager.client.password = self.user.password;
NSError *error = nil;
NSManagedObjectModel *managedObjectModel = appDelegate.managedObjectModel;
NSString *databaseName = @"Fishn.sqlite";
//RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
RKManagedObjectStore *managedObjectStore =[[RKManagedObjectStore alloc] init];
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:databaseName usingSeedDatabaseName:nil managedObjectModel:managedObjectModel delegate:self];
objectManager.objectStore = managedObjectStore;
[super viewDidLoad];
// Enable automatic network activity indicator management
objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
//NSLog(@"===> %@ / %@",objectManager.client.username,objectManager.client.password);
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"Fishn.sqlite"];
[self setupMapping];
[self sendRequest];
}
- (void)configureRestKit {
#if TARGET_IPHONE_SIMULATOR
gBaseURL = [[NSURL alloc] initWithString:@"http://localhost:3000"];
#else
gBaseURL = [[NSURL alloc] initWithString:@"http://localhost:3000"];
#endif
//self.user.login = @"user@example.com";
//self.user.password = @"please";
}
- (void)sendRequest
{
[objectManager loadObjectsAtResourcePath:@"/events.json" delegate:self];
}
- (void)objectLoader:(RKManagedObjectLoader *)objectLoader didFailWithError:(NSError *)error
{
NSLog(@"Error: %@", [error localizedDescription]);
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
if ([request isGET]) {
if ([response isOK]) {
NSLog(@"Data returned: %@", [response bodyAsString]);
}
} else if ([request isPOST]) {
if ([response isJSON]) {
NSLog(@"POST returned a JSON response");
}
} else if ([request isDELETE]) {
if ([response isNotFound]) {
NSLog(@"Resource '%@' not exists", [request resourcePath]);
}
}
}
- (void)objectLoader:(RKManagedObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
NSLog(@"Number of objects [%d]", [objects count]);
data = objects;
self.eventsArray = objects;
[self.tableView reloadData];
}
- (void)setupMapping {
RKObjectMappingProvider *omp = [RKObjectManager sharedManager].mappingProvider;
RKManagedObjectMapping *eventMapping = [RKManagedObjectMapping mappingForClass:[Event class] inManagedObjectStore:objectManager.objectStore];
[eventMapping mapKeyPathsToAttributes:
@"id",@"eventId",
@"name",@"name",
@"amount",@"amount",
@"length",@"length",
@"updated_at",@"updatedAt",
@"created_at",@"createdAt",
@"latitude",@"latitude",
@"longitude",@"longitude",
@"thumbnail",@"thumbnail",
@"airTemp",@"airTemp", nil];
eventMapping.primaryKeyAttribute = @"eventId";
eventMapping.rootKeyPath = @"event";
[omp addObjectMapping:eventMapping];
[omp setObjectMapping:eventMapping forResourcePathPattern:@"/events.json"];
//[objectManager loadObjectsAtResourcePath:@"/events.json" delegate:self];
//[eventMapping mapAttributes:@"name", @"amount", @"latitude", @"longitude", @"airTemp", @"length",@"thumbnail", nil];
//[eventMapping mapKeyPathsToAttributes:
// @"created_at", @"createdAt",
// @"updated_at", @"updatedAt",
// @"id", @"eventId",
// nil];
}
Event.h
@class Photo;
@interface Event : NSManagedObject {
NSNumber *eventId;
NSString *name;
NSString *amount;
NSDate *updatedAt;
NSDate *createdAt;
NSNumber *latitude;
NSNumber *longitude;
NSNumber *airTemp;
NSNumber *length;
UIImage *thumbnail;
}
@property (nonatomic, retain) UIImage *thumbnail;
//@property (nonatomic, retain) NSDate *creationDate;
@property (nonatomic, retain) Photo *photo;
@property (nonatomic, retain) NSNumber *eventId;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *amount;
@property (nonatomic, retain) NSDate *updatedAt;
@property (nonatomic, retain) NSDate *createdAt;
@property (nonatomic, strong) NSNumber *latitude;
@property (nonatomic, retain) NSNumber *longitude;
@property (nonatomic, retain) NSNumber *airTemp;
@property (nonatomic, retain) NSNumber *length;
@end
这是我的控制台日志:
2012-12-12 21:46:03.144 fish[30797:11f03] I restkit:RKLog.m:33 RestKit initialized...
2012-12-12 21:46:03.256 fish[30797:11f03] AppDelegeate I am your RKClient singleton : <RKClient: 0x9838ee0>
2012-12-12 21:46:03.257 fish[30797:11f03] Uname and PW = user@example.com , please
2012-12-12 21:46:03.264 fish[30797:11f03] User has street cred
2012-12-12 21:46:03.265 fish[30797:11f03] Application windows are expected to have a root view controller at the end of application launch
2012-12-12 21:46:03.266 fish[30797:11f03] I restkit.support:RKCache.m:189 Invalidating cache at path: /Users/yoshi/Library/Application Support/iPhone Simulator/6.0/Applications/6BB57AD9-7949-4B0B-A1B5-4441005FA87A/Library/Caches/RKClientRequestCache-localhost/SessionStore
2012-12-12 21:46:03.267 fish[30797:11f03] I restkit.network.reachability:RKReachabilityObserver.m:162 Reachability observer initialized with hostname localhost
2012-12-12 21:46:03.268 fish[30797:11f03] D restkit.network:RKClient.m:294 Reachability observer changed for client <RKClient: 0x79542b0>, suspending queue <RKRequestQueue: 0x79543f0 name=(null) suspended=YES requestCount=0 loadingCount=0/5> until reachability to host 'localhost' can be determined
2012-12-12 21:46:03.268 fish[30797:11f03] I restkit.support:RKCache.m:189 Invalidating cache at path: /Users/yoshi/Library/Application Support/iPhone Simulator/6.0/Applications/6BB57AD9-7949-4B0B-A1B5-4441005FA87A/Library/Caches/RKClientRequestCache-localhost/SessionStore
2012-12-12 21:46:03.294 fish[30797:11f03] I restkit.network.reachability:RKReachabilityObserver.m:391 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x983d860 host=localhost isReachabilityDetermined=YES isMonitoringLocalWiFi=NO reachabilityFlags=-R -----ld>
2012-12-12 21:46:03.294 fish[30797:11f03] D restkit.network:RKClient.m:437 Reachability to host 'localhost' determined for client <RKClient: 0x9838ee0>, unsuspending queue <RKRequestQueue: 0x9839300 name=(null) suspended=YES requestCount=0 loadingCount=0/5>
2012-12-12 21:46:03.295 fish[30797:11f03] D restkit.network.queue:RKRequestQueue.m:338 Queue <RKRequestQueue: 0x9839300 name=(null) suspended=YES requestCount=0 loadingCount=0/5> has been unsuspended
2012-12-12 21:46:03.295 fish[30797:11f03] I restkit.network.reachability:RKReachabilityObserver.m:391 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x983c6c0 host=localhost isReachabilityDetermined=YES isMonitoringLocalWiFi=NO reachabilityFlags=-R -----ld>
2012-12-12 21:46:03.296 fish[30797:11f03] D restkit.network:RKClient.m:437 Reachability to host 'localhost' determined for client <RKClient: 0x79542b0>, unsuspending queue <RKRequestQueue: 0x79543f0 name=(null) suspended=YES requestCount=1 loadingCount=0/5>
2012-12-12 21:46:03.296 fish[30797:11f03] D restkit.network.queue:RKRequestQueue.m:338 Queue <RKRequestQueue: 0x79543f0 name=(null) suspended=YES requestCount=1 loadingCount=0/5> has been unsuspended
2012-12-12 21:46:03.297 fish[30797:11f03] D restkit.network.queue:RKRequestQueue.m:309 Sent request <RKManagedObjectLoader: 0x7c5c860> from queue <RKRequestQueue: 0x79543f0 name=(null) suspended=NO requestCount=1 loadingCount=1/5>. Loading count = 1 of 5
2012-12-12 21:46:03.299 fish[30797:11f03] D restkit.network:RKRequest.m:437 Sending asynchronous GET request to URL http://localhost:3000/events.json.
2012-12-12 21:46:03.301 fish[30797:11f03] D restkit.network:RKResponse.m:198 Proceeding with request to <NSURLRequest http://localhost:3000/events.json>
2012-12-12 21:46:03.315 fish[30797:11f03] D restkit.network:RKResponse.m:175 Asked if canAuthenticateAgainstProtectionSpace: with authenticationMethod = NSURLAuthenticationMethodDefault
2012-12-12 21:46:03.315 fish[30797:11f03] D restkit.network:RKResponse.m:147 Received authentication challenge
2012-12-12 21:46:03.418 fish[30797:11f03] D restkit.network:RKResponse.m:219 NSHTTPURLResponse Status Code: 304
2012-12-12 21:46:03.419 fish[30797:11f03] D restkit.network:RKResponse.m:220 Headers: {
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = close;
Date = "Thu, 13 Dec 2012 02:46:03 GMT";
Etag = "\"1a8ebe93a30136774e4a26d6f0d3b714\"";
Server = "WEBrick/1.3.1 (Ruby/1.9.3/2012-02-16)";
"X-Request-Id" = 404311fe98d4bf07e27c13171346a593;
"X-Runtime" = "0.097077";
"X-Ua-Compatible" = "IE=Edge";
}
2012-12-12 21:46:03.420 fish[30797:11f03] I restkit.network:RKRequest.m:680 Updating cache date for request <RKManagedObjectLoader: 0x7c5c860> to 2012-12-13 02:46:03 +0000
2012-12-12 21:46:03.421 fish[30797:11f03] Data returned: [{"event":{"airTemp":72.1,"amount":1,"created_at":"2012-11-25T01:21:29Z","id":1,"latitude":55.5555,"length":22.0,"longitude":-88.88888,"name":"Grouper","thumbnail":null,"updated_at":"2012-11-25T01:21:29Z","user_id":1}},{"event":{"airTemp":69.1,"amount":2,"created_at":"2012-11-27T16:30:51Z","id":2,"latitude":33.333,"length":36.0,"longitude":124.4555555,"name":"Haddock","thumbnail":null,"updated_at":"2012-11-27T16:30:51Z","user_id":null}}]
2012-12-12 21:46:03.421 fish[30797:11f03] D restkit.network.queue:RKRequestQueue.m:501 Received response for request <RKManagedObjectLoader: 0x7c5c860>, removing from queue. (Now loading 1 of 5)
2012-12-12 21:46:03.422 fish[30797:16707] D restkit.network:RKObjectLoader.m:280 Beginning object mapping activities within GCD queue labeled: org.restkit.ObjectMapping
2012-12-12 21:46:03.422 fish[30797:16707] D restkit.network:RKObjectLoader.m:267 No object mapping provider, using mapping provider from parent object manager to perform KVC mapping
2012-12-12 21:46:03.423 fish[30797:16707] D restkit.object_mapping:RKObjectMapper.m:336 Performing object mapping sourceObject: (
{
event = {
airTemp = "72.09999999999999";
amount = 1;
"created_at" = "2012-11-25T01:21:29Z";
id = 1;
latitude = "55.5555";
length = 22;
longitude = "-88.88888";
name = Grouper;
thumbnail = "<null>";
"updated_at" = "2012-11-25T01:21:29Z";
"user_id" = 1;
};
},
{
event = {
airTemp = "69.09999999999999";
amount = 2;
"created_at" = "2012-11-27T16:30:51Z";
id = 2;
latitude = "33.333";
length = 36;
longitude = "124.4555555";
name = Haddock;
thumbnail = "<null>";
"updated_at" = "2012-11-27T16:30:51Z";
"user_id" = "<null>";
};
}
)
and targetObject: (null)
2012-12-12 21:46:03.423 fish[30797:16707] D restkit.object_mapping:RKObjectMapper.m:275 Found mappable collection at keyPath 'event': (
{
airTemp = "72.09999999999999";
amount = 1;
"created_at" = "2012-11-25T01:21:29Z";
id = 1;
latitude = "55.5555";
length = 22;
longitude = "-88.88888";
name = Grouper;
thumbnail = "<null>";
"updated_at" = "2012-11-25T01:21:29Z";
"user_id" = 1;
},
{
airTemp = "69.09999999999999";
amount = 2;
"created_at" = "2012-11-27T16:30:51Z";
id = 2;
latitude = "33.333";
length = 36;
longitude = "124.4555555";
name = Haddock;
thumbnail = "<null>";
"updated_at" = "2012-11-27T16:30:51Z";
"user_id" = "<null>";
}
)
2012-12-12 21:46:03.424 fish[30797:16707] I restkit.core_data:RKInMemoryManagedObjectCache.m:34 Creating thread-local entity cache for managed object context: <NSManagedObjectContext: 0x795c1a0>
2012-12-12 21:46:03.424 fish[30797:16707] I restkit.core_data:RKInMemoryManagedObjectCache.m:50 Caching instances of Entity 'Event' by primary key attribute 'eventId'