我正在开发一个使用 RestKit 的 iPhone 应用程序。我在将对象发布到服务器时遇到问题。当我保存帖子时,它会显示在 TableView 提要中,但不会保存到服务器。我在 xcode 中收到一条错误消息:
Object request failed: Underlying HTTP request operation failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1011 "Expected status code in (200-299), got 500"
在控制台的更下方,我得到:
AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest https://stormy.herokuapp.com/posts>, NSErrorFailingURLKey=https://stormy.herokuapp.com/posts, NSLocalizedDescription=Expected status code in (200-299), got 500, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x841d450>}
我的 NSManagedObject MPost 看起来像
@interface MPost : NSManagedObject
@property (nonatomic, retain) NSNumber * postID;
@property (nonatomic, retain) id jsonURL;
@property (nonatomic, retain) id htmlURL;
@property (nonatomic, retain) NSString * bodyText;
@property (nonatomic, retain) NSDate * createdAt;
@property (nonatomic, retain) MUser *user;
这是我的 AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Markofresh" ofType:@"momd"]];
// NOTE: Due to an iOS 5 bug, the managed object model returned is immutable.
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
// Initialize the Core Data stack
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add persistent store: %@", error);
[managedObjectStore createManagedObjectContexts];
// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Configure the object manager
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"https://stormy.herokuapp.com"]];
objectManager.managedObjectStore = managedObjectStore;
[RKObjectManager setSharedManager:objectManager];
RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:@"Post" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"id": @"postID",
@"url": @"jsonURL",
@"body": @"bodyText",
@"public": @"public",
@"created_at": @"createdAt"}];
entityMapping.identificationAttributes = @[ @"postID" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:@"/posts" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
RKRequestDescriptor * requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[entityMapping inverseMapping] objectClass:[MPost class] rootKeyPath:@"/posts"];
[objectManager addRequestDescriptor:requestDescriptor];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[MPost class]];
[responseMapping addAttributeMappingsFromArray:@[@"bodyText", @"postID", @"createdAt"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *postDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:@"/posts" keyPath:@"/posts" statusCodes:statusCodes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary
[requestMapping addAttributeMappingsFromArray:@[@"bodyText", @"postID", @"createdAt"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[MPost class] rootKeyPath:@"posts"];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"https://stormy.herokuapp.com"]];
[manager addRequestDescriptor:requestDescriptor];
[manager addResponseDescriptor:postDescriptor];
[objectManager addRequestDescriptor:requestDescriptor];
// Override point for customization after application launch.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
return YES;
}
NewPost 类中的 savePost 方法是这样的:
-(void)saveChanges {
RKManagedObjectStore *objectStore = [[RKObjectManager sharedManager] managedObjectStore];
MPost *post = [NSEntityDescription insertNewObjectForEntityForName:@"Post" inManagedObjectContext:objectStore.mainQueueManagedObjectContext];
[post setBodyText:@"This is the body."];
[[RKObjectManager sharedManager] postObject:post path:@"/posts" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Success saving post");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failure saving post: %@", error.localizedDescription);
}];
有任何想法吗?
是否因为我的 rails 应用程序模型中有 user_id presenece:true parmam 而失败 - 但我的 xcode 应用程序中没有用户?还是 xcode 和 rails 中的类声明之间存在差异?
编辑这是来自成功帖子的服务器日志
2013-06-18T17:46:41.822383+00:00 app[web.1]: Started POST "/posts" for 76.171.148.52 at 2013-06-18 17:46:41 +0000
2013-06-18T17:46:41.825320+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"8VvNPJXOuTNvS4ewEmXAvYHkcyKAnktHrpfQhRgHFy4=", "post"=>{"body"=>"shyea"}, "commit"=>"Create Post"}
2013-06-18T17:46:41.825160+00:00 app[web.1]: Processing by PostsController#create as HTML
2013-06-18T17:46:41.943001+00:00 app[web.1]: Redirected to https://stormy-river-3647.herokuapp.com/posts/4
2013-06-18T17:46:41.943001+00:00 app[web.1]: Completed 302 Found in 116ms (ActiveRecord: 7.8ms)
2013-06-18T17:46:42.410628+00:00 heroku[router]: at=info method=GET path=/posts/4 host=stormy-river-3647.herokuapp.com fwd="76.171.148.52" dyno=web.1 connect=1ms service=66ms status=200 bytes=2040
2013-06-18T17:46:42.353386+00:00 app[web.1]: Started GET "/posts/4" for 76.171.148.52 at 2013-06-18 17:46:42 +0000
2013-06-18T17:46:42.357829+00:00 app[web.1]: Processing by PostsController#show as HTML
2013-06-18T17:46:42.366143+00:00 app[web.1]: Parameters: {"id"=>"4"}
2013-06-18T17:46:42.381884+00:00 app[web.1]: Rendered posts/show.html.erb within layouts/application (4.0ms)
2013-06-18T17:46:41.943499+00:00 heroku[router]: at=info method=POST path=/posts host=stormy.herokuapp.com fwd="76.171.148.52" dyno=web.1 connect=1ms service=142ms status=302 bytes=113
这是发布失败后的服务器日志中的:
2013-06-18T22:55:01.571679+00:00 app[web.1]: Started POST "/posts" for 76.171.148.52 at 2013-06-18 22:55:01 +0000
2013-06-18T22:55:01.579270+00:00 app[web.1]: WARNING: Can't verify CSRF token authenticity
2013-06-18T22:55:01.579270+00:00 app[web.1]: Processing by PostsController#create as JSON
2013-06-18T22:55:01.578909+00:00 app[web.1]: app/controllers/posts_controller.rb:39:in `create'
2013-06-18T22:55:01.578909+00:00 app[web.1]: NoMethodError (undefined method `posts' for nil:NilClass):
2013-06-18T22:55:01.579270+00:00 app[web.1]: Parameters: {"post"=>{"body"=>"This is the body."}}
2013-06-18T22:55:01.579270+00:00 app[web.1]: Completed 500 Internal Server Error in 1ms
问题出在轨道方面吗?在posts_controller 中?