I'm creating a post where I can register and save ads from my application to my api. When I click on register it returns the error got 422 but if I put the user id manually and permanent (user_id = @ "1") it works normally but it with this code: newAd.user_id = [[ [AppDelegate sharedDelegate] currentUser] _id]; , it does not work and returns the error.
This is my WebService:
#import "JVWebService.h"
#import <RestKit/RestKit.h>
#import "AppDelegate.h"
#import "JVUtils.h"
#import "Ads.h"
static NSString *kServerURL = @"http://localhost:3000";
@interface JVWebService ()
@property (strong, nonatomic) RKObjectManager *restKitObjectManager;
@end
#define kSuccessStatusCode RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
@implementation JVWebService
+ (instancetype)sharedService {
static JVWebService *sharedService = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedService = [[self alloc] init];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
sharedService.restKitObjectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:kServerURL]];
[sharedService.restKitObjectManager.HTTPClient setAuthorizationHeaderWithUsername:[[[AppDelegate sharedDelegate] currentUser] email]
password:[[[AppDelegate sharedDelegate] currentUser] password]];
});
return sharedService;
}
#pragma mark - User
- (void)getUserForEmail:(NSString *)email andPassword:(NSString *)password {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:User.class];
[objectMapping addAttributeMappingsFromDictionary:self.userAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postUserAttributes];
NSString *path = @"/users/sign_in.json";
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:User.class
rootKeyPath:@"user"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:@"user"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
User *user = [User new];
user.email = email;
user.password = password;
[[NSUserDefaults standardUserDefaults] setObject:[[NSUUID UUID] UUIDString] forKey:@"authencity_token"];
NSDictionary *params = @{@"authenticity_token" : [[NSUserDefaults standardUserDefaults] objectForKey:@"authencity_token"]};
[self.restKitObjectManager.HTTPClient setAuthorizationHeaderWithUsername:email password:password];
[self.restKitObjectManager postObject:user path:path parameters:params success:^(RKObjectRequestOperation *operation,
RKMappingResult *result){
User *user = (User *)result.array.firstObject;
user.password = password;
[[AppDelegate sharedDelegate] login:user];
[[AppDelegate sharedDelegate] setLoggedViaFacebook:NO];
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:user];
} failure:^(RKObjectRequestOperation *operation, NSError *error){
RKLogError(@"Operation failed with error: %@", error);
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (void)createUser:(User *)user{
NSString *path = @"/users.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:User.class];
[objectMapping addAttributeMappingsFromDictionary:self.userAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postUserAttributes];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:User.class
rootKeyPath:@"user"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:@"user"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSMutableURLRequest *request = [self.restKitObjectManager multipartFormRequestWithObject:user method:RKRequestMethodPOST path:path parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {}];
RKObjectRequestOperation *operation = [self.restKitObjectManager objectRequestOperationWithRequest:request success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
User *user = (User *)result.array.firstObject;
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:user];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager enqueueObjectRequestOperation:operation];
[self.restKitObjectManager removeRequestDescriptor:requestDescriptor];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (void)updateUser:(User *)user withProfileImage:(UIImage *)profileImage {
NSString *path = @"/users.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:User.class];
[objectMapping addAttributeMappingsFromDictionary:self.userAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postUserAttributes];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:User.class
rootKeyPath:@"user"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:@"user"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSDictionary *params = @{@"authencity_token" : [[NSUserDefaults standardUserDefaults] objectForKey:@"authencity_token"]};
NSMutableURLRequest *request = [self.restKitObjectManager multipartFormRequestWithObject:user method:RKRequestMethodPATCH path:path parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// [formData appendPartWithFileData:UIImagePNGRepresentation(profileImage)
// name:@"user[avatar]"
// fileName:@"profileImage.jpg"
// mimeType:@"image/jpg"];
}];
RKObjectRequestOperation *operation = [self.restKitObjectManager objectRequestOperationWithRequest:request success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
[[AppDelegate sharedDelegate] login:(User *) result.array.firstObject];
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:result.firstObject];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager enqueueObjectRequestOperation:operation];
[self.restKitObjectManager removeRequestDescriptor:requestDescriptor];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (void)logout {
NSString *path = @"/users/sign_out.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:User.class];
[objectMapping addAttributeMappingsFromDictionary:self.userAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postUserAttributes];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:User.class
rootKeyPath:@"user"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:@"user"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSDictionary *params = @{@"authenticity_token" : [[NSUserDefaults standardUserDefaults] objectForKey:@"authencity_token"]};
[self.restKitObjectManager deleteObject:[[AppDelegate sharedDelegate] currentUser] path:path parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
[[AppDelegate sharedDelegate] logout];
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:nil];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Operation failed with error: %@", error);
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager removeRequestDescriptor:requestDescriptor];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (void)sendResetPasswordInstructionsToEmail:(NSString *)email {
NSString *path = @"/send_lost_password.json";
NSDictionary *params = @{@"email" : email};
[self.restKitObjectManager getObject:nil path:path parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:nil];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Operation failed with error: %@", error);
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
}
- (void)postAd:(Ads *)ad {
NSString *path = @"/ads.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:Ads.class];
[objectMapping addAttributeMappingsFromDictionary:self.adAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postAdAttributes];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:Ads.class
rootKeyPath:@"ad"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:@"ad"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSMutableURLRequest *urlRequest = [self.restKitObjectManager multipartFormRequestWithObject:ad method:RKRequestMethodPOST path:path parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// NSArray *photosArray = ad.photos[0];
// for(int i = 0; i < photosArray.count; i++) {
//
// NSString *name = [NSString stringWithFormat:@"ad[photos_attributes][%i][picture]", i];
// NSString *fileName = [NSString stringWithFormat:@"photo%i.jpg", i];
// [formData appendPartWithFileData:UIImagePNGRepresentation(photosArray[i])
// name:name
// fileName:fileName
// mimeType:@"image/jpg"];
// }
}];
RKObjectRequestOperation *operation = [self.restKitObjectManager objectRequestOperationWithRequest:urlRequest
success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
if ([self.serviceDelegate respondsToSelector:@selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:nil];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if ([self.serviceDelegate respondsToSelector:@selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager enqueueObjectRequestOperation:operation];
[self.restKitObjectManager removeRequestDescriptor:requestDescriptor];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (NSDictionary *)adAttributes {
return @{
@"id" : @"_id",
@"title" : @"title",
@"price" : @"price",
@"local" : @"local",
@"description" : @"especification",
@"categories" : @"categories",
@"photos" : @"photos",
@"latitude" : @"latitude",
@"longitude" : @"longitude"
};
}
- (NSDictionary *)postAdAttributes {
return @{
@"_id" : @"id",
@"title" : @"title",
@"price" : @"price",
@"local" : @"local",
@"especification" : @"description",
@"categories" : @"category_ids",
@"user_id" : @"user_id",
@"latitude" : @"latitude",
@"longitude" : @"longitude"
};
}
- (NSDictionary *)userAttributes {
return @{
@"id" : @"_id",
@"email" : @"email",
@"name" : @"name",
@"avatar" : @"profileImageUrl",
@"phone" : @"phone",
@"password" : @"password",
@"contact_pref" : @"communicationPreference",
@"products_alerts" : @"productsAlerts"
};
}
- (NSDictionary *)postUserAttributes {
return @{
@"_id" : @"id",
@"email" : @"email",
@"name" : @"name",
@"phone" : @"phone",
@"password" : @"password",
@"password" : @"password_confirmation",
@"communicationPreference" : @"contact_pref"
};
}
@end
This is my AppDelegate where I put my CurrentUser:
#import "AppDelegate.h"
#import "BaseViewController.h"
#import "JVUtils.h"
#import "JVWebService.h"
#import "NSUserDefaults+RMSaveCustomObject.h"
#import "NSObject+RMArchivable.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
+ (instancetype)sharedDelegate {
static AppDelegate *sharedDelegate = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
});
return sharedDelegate;
}
- (void) login:(User *)user {
[[NSUserDefaults standardUserDefaults] rm_setCustomObject:user forKey:@"currentUser"];
}
- (void) logout {
self.currentUser = nil;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"currentUser"];
}
- (User *) user {
if(!self.currentUser) {
self.currentUser = [[NSUserDefaults standardUserDefaults] rm_customObjectForKey:@"currentUser"];
}
return self.currentUser;
}
// During the Facebook login flow, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "br.com.JaVendi" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"JaVendi" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"JaVendi.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
@end
And now the view where I registered an ad:
#import "NewAdViewController.h"
#import "Ads.h"
#import "JVUtils.h"
#import "JVWebService.h"
#import "AppDelegate.h"
@interface NewAdViewController ()
@end
@implementation NewAdViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//iguala os valores das strings com os campos de textos
- (IBAction)signUp:(id)sender {
if (self.titleField.text.length <= 0) {
[JVUtils showMessage:@"Você precisa dar um nome ao seu anúncio." withTitle:@"Opa!"];
} else if (self.priceField.text.length <= 0) {
[JVUtils showMessage:@"você precisa dar um preço ao seu anúncio" withTitle:@"Opa!"];
} else if (self.localField.text.length <= 0) {
[JVUtils showMessage:@"Qual o local do anúncio?" withTitle:@"Opa!"];
} else if (self.descriptionField.text.length <= 0) {
[JVUtils showMessage:@"Descreva seu anúncio" withTitle:@"Opa!"];
} else {
Ads *newAd = [Ads new];
newAd.title = self.titleField.text;
newAd.price = self.priceField.text;
newAd.local = self.localField.text;
newAd.especification = self.descriptionField.text;
newAd.categories = nil;
newAd.user_id = [[[AppDelegate sharedDelegate] currentUser] _id];
newAd.latitude = nil;
newAd.longitude = nil;
newAd.photos = nil;
[[JVWebService sharedService] setServiceDelegate:self];
[[JVWebService sharedService] postAd:newAd];
}
}
//se o cadastro tiver sucesso
- (void)successfulRequestDidReturnObject:(NSObject *)object {
[JVUtils showMessage:@"Anuncio cadastrado =D" withTitle:@"hadoukeeeen !"];
[[AppDelegate sharedDelegate] setCurrentUser:(User *)object];
[self dismissViewControllerAnimated:YES completion:nil];
}
//se o cadastro falhar
- (void)requestDidFailWithError:(NSError *)error {
[JVUtils showMessage:error.localizedDescription withTitle:@"Errohue"];
}
@end