I need to POST a video to a server in the background. Until now i've been using this sort of pattern when POSTing:
- (BOOL)loginUser:(user *)user
{
BOOL ret = NO;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.waitView startWithMessage:#"Signing in ..."];
[self.objectManager postObject:user usingBlock:^(RKObjectLoader *loader)
{
loader.delegate = self;
loader.targetObject = nil;
loader.objectMapping = [RKObjectMapping mappingForClass:[user class] usingBlock:^(RKObjectMapping *mapping)
{
[mapping mapKeyPath:#"id" toAttribute:#"ID"];
[mapping mapKeyPath:#"last_name" toAttribute:#"last_name"];
[mapping mapKeyPath:#"first_name" toAttribute:#"first_name"];
[mapping mapKeyPath:#"middle_name" toAttribute:#"middle_name"];
[mapping mapKeyPath:#"email" toAttribute:#"email"];
[mapping mapKeyPath:#"password" toAttribute:#"password"];
[mapping mapKeyPath:#"authentication_token" toAttribute:#"authentication_token"];
}];
loader.serializationMapping = [loader.objectMapping inverseMapping];
loader.serializationMapping.rootKeyPath = NSStringFromClass([user class]);
}];
return ret;
}
... but this pattern doesn't seem to let me access any RKRequest object on which to set the backgroundPolicy. So, i've looked at using RKClient like so:
- (BOOL)postBigMediaFile:(NSString *)pathToBigFile
{
BOOL ret = NO;
NSString *resourcePath = #"/bigFile";
[[RKClient sharedClient] post:resourcePath usingBlock:^(RKRequest *request)
{
request.backgroundPolicy = RKRequestBackgroundPolicyContinue;
// how do I set up the object mapping?
}];
return ret;
}
... but the RKRequest object doesn't seem to have a way of accessing an RKObjectLoader for which to setup the mapping on. How do I post data in the background using object mapping?
Silly me ... RKObjectLoader is a subclass of RKRequest, so I can just do loader.backgroundPolicy = ... :-)
Related
My app receives a json object the first time is executed (with three pin point locations); there is a mapKit (the first screen) and a TableView where the user can check those locations. The issue is that when I first launch the app, there are no pins on the map. But if I switch to the table I can see them - on the cells - and if I switch again to the map, the pins appear...I don't Know why this happens, shouldn't I see the pins right after the app launch? The Map code:
- (void)viewDidLoad {
[super viewDidLoad];
NSNotificationCenter *notification=[NSNotificationCenter defaultCenter];
[notification addObserver:self selector:#selector (receiveNotification:) name:#"notification" object:self];
_mapView.showsUserLocation=YES;
_mapView.showsBuildings=YES;
_locationManager = [[CLLocationManager alloc] init];
[_locationManager requestAlwaysAuthorization];
_mapView.delegate = self;
_locationManager.delegate=self;
}
-(void)viewDidAppear:(BOOL)animated{
[self receiveNotification:nil];
}
-(void)receiveNotification:(NSNotification*)notification{
NSArray *spots = [Spot spotType:#"users"];
NSArray *places = [Spot spotWithType:#"users"];
[_mapView addAnnotations:spots];
[_mapView addAnnotations:places];
}
And the table:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.detailList=#[#"Your Favourite Spots",#"Our suggestion"];
}
-(void)viewDidAppear:(BOOL)animated{
_lisbonSpots = [[Spot spotType:#"users"]mutableCopy];
_users=[[Spot spotWithType:#"users"]mutableCopy];
[self.tableView reloadData];
}
EDIT - The Spot Class
#implementation Spot
#dynamic ID;
#dynamic name;
#dynamic desc;
#dynamic type;
#dynamic phone;
#dynamic latitude;
#dynamic longitude;
+ (instancetype)spotWithName:(NSString *)name andCoord:
(CLLocationCoordinate2D)coord type:(NSString*)type desc:(NSString*)desc phone:(NSString*)phone{
NSPersistentContainer *persistenceContainer = [AppDelegate sharedDelegate].persistentContainer;
NSManagedObjectContext *context = persistenceContainer.viewContext;
Spot *spot = [NSEntityDescription insertNewObjectForEntityForName:#"Spot" inManagedObjectContext:context];
spot.name = name;
spot.latitude = coord.latitude;
spot.longitude = coord.longitude;
spot.type=type;
spot.desc=desc;
spot.phone=phone;
[[AppDelegate sharedDelegate] saveContext];
return spot;
}
+ (instancetype)spotWithDict:(NSDictionary *)dict {
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake([dict[#"latitude"] doubleValue], [dict[#"longitude"] doubleValue]);
return [Spot spotWithName:dict[#"name"] andCoord:coord type:dict[#"type"] desc:dict[#"desc"] phone:dict[#"phone"]];
}
+ (NSArray*)getSpotType:(NSString*)type withPredicate:(NSString*) pred andMessage:(NSString*)message {
NSPersistentContainer *persistenceContainer = [AppDelegate sharedDelegate].persistentContainer;
NSPredicate* predicate = [NSPredicate predicateWithFormat:pred, type];
NSManagedObjectContext *context = persistenceContainer.viewContext;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Spot"];
[request setPredicate:predicate];
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
if (error != nil) {
NSLog(message, [error localizedDescription]);
return nil;
}
return result;
}
+ (NSArray*)spotType:(NSString*)type {
return [Spot getSpotType:type withPredicate:#"type =%#" andMessage:#"[Spot spotType] -> %#"];
}
+ (NSArray*)spotWithType:(NSString*)type {
return [Spot getSpotType:type withPredicate:#"NOT (type = %#)" andMessage:#"[Spot spotWithType] -> %#"];
}
- (CLLocationCoordinate2D)coordinate {
return CLLocationCoordinate2DMake(self.latitude, self.longitude);
}
- (NSString *)title {
return self.name;
}
- (NSString *)description {
return [NSString stringWithFormat:#"%#", self.name];
}
#end
EDIT: The SpotService class
#implementation SpotService
+ (NSURL *)serviceURL {
return [NSURL URLWithString:#"http://training.reativ.io/ios/lisbon-spots"];
}
+ (BOOL)service:(id<SpotServiceInvoker>)invoker {
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[SpotService serviceURL]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error != nil) {
NSLog(#"Response: %#", response);
NSLog(#"Error: %#", error);
return;
}
NSArray *lisbonSecrets = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if ([invoker respondsToSelector:#selector(receiveSpot:)]){
[invoker receiveSpot:lisbonSecrets];
}
for(NSDictionary *dict in lisbonSecrets) {
[Spot spotWithDict:dict];
}
});
}];
[task resume];
return YES;
}
My guess is - your Spot class retrieve data asynchronously and when you call [Spot spotType:#"users"] for the first time from viewDidAppear on your MapView there is no data retrieved yet. When you switch view controller the data appears and the everything works smoothly.
But it's better to show us your Spot class. Probably your need a completion handler or something like this to achieve expected behaviour.
Also, you call addAnnotations every time when your map appears on the screen and it means that MKMapView will add a copy of the annotations each time your call this methods. It's better to add additional checks to be sure that you do not add the same annotations more than once.
I have a singleton class that checks the login status of the app.
There's a method named attemptToLogin in the singleton class that makes an http request with parameters and returns with json data about the login status. (true or false)
Now in the main TabBarViewController i did the following:
#interface CustomTabBarController ()
#end
#implementation CustomTabBarController{
LoginCheckSingleton *loginSingleton;
dispatch_queue_t myCustomQueue;
}
-(void)viewDidAppear:(BOOL)animated{
myCustomQueue = dispatch_queue_create("com.myDomain.appName", NULL);
loginSingleton = [LoginCheckSingleton sharedInstance];
dispatch_sync(myCustomQueue, ^{
[loginSingleton attemptToLogin];
});
if([loginSingleton.loginstat isEqual: #"true"]){
NSLog(#"Logged In");
}else{
NSLog(#"Not Logged In");
[self performSegueWithIdentifier:#"goToLoginView" sender:self];
}
}
The dispatch_sync is not working properly here, i want to execute the function inside the dispatch_sync and get the results before executing the if statement under it. But the if statement is executed before the block inside the dispatch_sync has finished.
This is the Singleton Class:
#import "LoginCheckSingleton.h"
#import "AFNetworking.h"
#import "SSKeychain.h"
#import "CustomTabBarController.h"
static LoginCheckSingleton *sharedInstance = nil;
#interface LoginCheckSingleton (){
NSString *serverURLString;
NSURL *serverURL;
NSString *userId;
NSString *password;
NSString *email;
NSMutableArray *jsonContents;
NSMutableDictionary *dictionary;
NSString *loggedInStatus;
bool loggedInTF;
}
#end
#implementation LoginCheckSingleton{
}
+ (LoginCheckSingleton*) sharedInstance {
static dispatch_once_t _singletonPredicate;
static LoginCheckSingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
-(void)attemptToLogin{
// Retrieve credentials from Keychain
userId = [SSKeychain passwordForService:#"com.lazemni.iFresh"
account:#"ifreshUserId"];
password = [SSKeychain passwordForService:#"com.lazemni.iFresh"
account:#"ifreshPassword"];
email = [SSKeychain passwordForService:#"com.lazemni.iFresh"
account:#"ifreshEmail"];
if(email == nil || password == nil){
NSLog(#"empty username or password");
}else{
NSLog(#"not empty username or password");
serverURLString = #"http://www.lazemni.com/demo/ifresh/api/login/";
serverURLString = [serverURLString stringByAppendingString:email];
serverURLString = [serverURLString stringByAppendingString:#"/"];
serverURLString = [serverURLString stringByAppendingString:password];
NSLog(#"%#",serverURLString);
serverURL = [NSURL URLWithString:serverURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:serverURL];
//AFNetworking asynchronous url request
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
jsonContents = [responseObject objectForKey:#"login"];
NSLog(#"%#",jsonContents);
dictionary = [jsonContents objectAtIndex:0];
loggedInStatus = [dictionary objectForKey:#"status"];
if([loggedInStatus isEqual: #"true"]){
NSLog(#"Succefully loggedin!");
[SSKeychain setPassword:[dictionary objectForKey:#"user_id"] forService:#"com.lazemni.iFresh" account:#"ifreshUserId"];
[SSKeychain setPassword:[dictionary objectForKey:#"email"] forService:#"com.lazemni.iFresh" account:#"ifreshEmail"];
[SSKeychain setPassword:[dictionary objectForKey:#"password"] forService:#"com.lazemni.iFresh" account:#"ifreshPassword"];
self.loginstat = #"true";
loggedInTF = true;
}else if([loggedInStatus isEqual: #"false"]){
NSLog(#"Wrong email/password combination!");
self.loginstat = #"false";
loggedInTF = false;
}
} failure:nil];
[operation start];
}
}
#end
I never understood how dispatch_sync really works,
Any idea how to wait for the [loginSingleton attemptToLogin]; to finish ?
attemptToLogin is probably an asynchronous method. You want to write attemptToLogin in such a way that it gives you a callback when the HTTP Request finishes executing. You can do that by means of a completion block, or a delegate, or a notification.
If you wait for the request to finish, you'll end up blocking the main thread, which will freeze user interactions, leading to a terrible UX.
- (void)attemptToLogin:(void(^)(BOOL login))complete {
...
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
....
// After you get login status
complete(your_login_status_here);
}
}
And in CustomTabBarController
-(void)viewDidAppear:(BOOL)animated{
myCustomQueue = dispatch_queue_create("com.myDomain.appName", NULL);
loginSingleton = [LoginCheckSingleton sharedInstance];
[loginSingleton attemptToLogin:^(loginStatus){
if([loginStatus isEqual: #"true"]){
NSLog(#"Logged In");
}else{
NSLog(#"Not Logged In");
dispatch_async(dispatch_get_main_queue(), {
[self performSegueWithIdentifier:#"goToLoginView" sender:self];
});
}
}];
}
I am novice on objective c.
I don't understand why my function doesn't work, it make an error SIGBART on the return of the function.
+ (NSArray*) jsonToArray:(NSString*)jsonString
{
id mappedObj = nil;
RKObjectMappingProvider* mapProv = [[RKObjectMappingProvider alloc] init];
RKObjectMapping* answerMapping = [SMAnswersWrapper entityMappingForSerializer];
answerMapping.objectClass = [NSMutableDictionary class];
[mapProv setSerializationMapping:answerMapping forClass:[SMAnswersWrapper class]];
RKObjectMapping *proofsEntityMapping = [SMEntityArrayWrapper entityMappingWithContentMapping:answerMapping];
[mapProv setMapping:proofsEntityMapping forKeyPath:#""];
if (jsonString)
{
id obj = [jsonString objectFromJSONString];
if (obj)
{
RKObjectMapper* mapper = [[RKObjectMapper alloc] initWithObject:obj mappingProvider:mapProv];
RKObjectMappingResult* res = [mapper performMapping];
mappedObj = [res asCollection];
[mapper release];
}
}
[mapProv release];
return [[[mappedObj content] retain] autorelease];
}
The error location is at this line :
return [[[mappedObj content] retain] autorelease];
Thank you.
EDIT
I find my error, I can't access to content at [[[mappedObj content] retain] autorelease]; i had to cast mappedObj.
Try following :
+ (NSArray*) jsonToArray:(NSString*)jsonString
{
id mappedObj = nil;
RKObjectMappingProvider* mapProv = [[RKObjectMappingProvider alloc] init];
RKObjectMapping* answerMapping = [SMAnswersWrapper entityMappingForSerializer];
answerMapping.objectClass = [NSMutableDictionary class];
[mapProv setSerializationMapping:answerMapping forClass:[SMAnswersWrapper class]];
RKObjectMapping *proofsEntityMapping = [SMEntityArrayWrapper entityMappingWithContentMapping:answerMapping];
[mapProv setMapping:proofsEntityMapping forKeyPath:#""];
if (jsonString)
{
id obj = [jsonString objectFromJSONString];
if (obj)
{
RKObjectMapper* mapper = [[RKObjectMapper alloc] initWithObject:obj mappingProvider:mapProv];
RKObjectMappingResult* res = [mapper performMapping];
mappedObj = [res asCollection];
[mapper release];
}
}
[mapProv release];
if (mappedObj)
{
return [[[mappedObj content] retain] autorelease];
}
return [NSArray array];
}
In your code if jsonString or obj will be nil, mappedObj will not be initialized. This case may cause crash while accessing [mappedObj content].
Try this, this will help you.....
I find my error, I can't access to content at [[[mappedObj content] retain] autorelease]; i had to cast mappedObj.
I'm getting the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to perform mapping: No `managedObjectContext` assigned. (Mapping response.URL = https://www.someurl.com/lastrequest=2014-12-08T02%3A44%3A52Z)'
The app stops at the following line in RKResponseMapperOperation.m:
- (RKMappingResult *)performMappingWithObject:(id)sourceObject error:(NSError **)error
{
NSLog(#"managedObjectContext: %#, Source Object: %# Error: %#", self.managedObjectContext, sourceObject, (*error).description);
NSAssert(self.managedObjectContext, #"Unable to perform mapping: No `managedObjectContext` assigned. (Mapping response.URL = %#)", self.response.URL);
....
I noticed that the above method was called 27 (this number varies) times prior to the app crashing. In each instance, NSManagedObjectContext was present i.e. the line below:
2014-12-07 18:44:48.721 MyApp[19011:3258405] managedObjectContext:managedObjectContext: <NSManagedObjectContext: 0x1701f5800>, Source Object: {
friends = (
);
} Error: (null)
However right before it crashed, the NSManagedObjectContext was null:
2014-12-07 18:44:53.454 MyApp[19011:3258404] managedObjectContext: (null), Source Object: {
friends = (
);
} Error: (null)
Since the app functions normally for a while before it crashes, I'm not sure how to address this. Any pointers would be greatly appreciated.
* EDIT *
In Appdelegaate. This method is called once in viewDidLoad when the User logs in.
- (RKManagedObjectStore *)managedObjectStore
{
if (!_managedObjectStore && [Persistence loggedIn])
{
NSError * error;
NSURL * modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"App" ofType:#"momd"]];
NSManagedObjectModel * managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
self.managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[_managedObjectStore createPersistentStoreCoordinator];
NSArray * searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentPath = [searchPaths objectAtIndex:0];
NSString *dbName = [NSString stringWithFormat:#"%#App%#.sqlite", documentPath, [Persistence username]];
NSPersistentStore * persistentStore = [_managedObjectStore addSQLitePersistentStoreAtPath:dbName
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:[self optionsForSqliteStore]
error:&error];
NSAssert(persistentStore, #"Failed to add persistent store with error: %#", error);
NSLog(#"Path: %#", dbName);
if(!persistentStore)
{
NSLog(#"Failed to add persistent store: %#", error);
}
[_managedObjectStore createManagedObjectContexts];
self.managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
return self.managedObjectStore;
}
return _managedObjectStore;
}
- (id)optionsForSqliteStore
{
return #{
NSInferMappingModelAutomaticallyOption: #YES,
NSMigratePersistentStoresAutomaticallyOption: #YES
};
}
Creating MOC:
For Core Data stack, I'm using the Default Core Data code in AppDelegate that's provided when the project is created in Xcode.
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
MOC Operation:
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != 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();
}
}
}
Inside the App, the methods below are used to set, get, and clear ObjectManager:
- (void)refreshMOC
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.objectManager = [self getObjectManager];
self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
self.objectManager.managedObjectStore.managedObjectCache = appDelegate.managedObjectStore.managedObjectCache;
self.managedObjectContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;
}
- (RKObjectManager *)setupObjectManager
{
NSURL *baseURL = [NSURL URLWithString:kBaseURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:baseURL];
RKObjectManager *manager = [[RKObjectManager alloc]initWithHTTPClient:httpClient];
[manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[manager.HTTPClient setParameterEncoding:AFJSONParameterEncoding];
[RKMIMETypeSerialization registeredMIMETypes];
[RKObjectManager setSharedManager:manager];
return [RKObjectManager sharedManager];
}
- (RKObjectManager *)getObjectManager
{
self.objectManager = (!self.objectManager) ? [self setupObjectManager] : self.objectManager;
return self.objectManager;
}
- (RKObjectManager*)newObjectManager
{
[self clearRKObjectManager];
return [self getObjectManager];
}
- (void)clearRKObjectManager
{
if (self.objectManager)
{
self.objectManager = nil;
}
}
Remove all of the app delegate template Core Data methods. When you use RestKit and create a managed object store you're asking RestKit to manage the Core Data stack for you so those other methods are not required (and confuse things).
When you need a MOC, get it / one from the managed object store.
Note, the above applies to saving too as you need to use the RestKit method for saving to the persistent store rather than just saving the individual MOC.
I'm somewhat new to iOS development so I'm trying to figure out posting a JSON string to a webserver and getting back some information. In the first page I ask for the user to give me their first name and last name. I then generate an ID for them and pass them to the second page. When the second page loads I want to send a JSON string to the server to tell it the users first name, last name among other things. The request would be like follows:
{
"user":{
"first_name":"Joe",
"last_name":"User",
"device_descriptor":"iPhone",
"idfa":"12345678",
"btmacid":"01:23:45:67:89:ab"
}
}
The create response successful would come back as follows:
{
"id": "8",
"first_name: "Joe",
"last_name": "User",
"device_descriptor": "iPhone",
"created_at": "2014-10-07T05:25:36.119Z",
"updated_at": "2014-10-07T05:25:36.119Z",
"idfa": "12345678",
"btmacid": "01:23:45:67:89:ab"
}
The code I have thus far is as follows:
#import "WelcomeViewController.h"
#import "CoreDataStack.h"
#import "UserInformation.h"
#import <CoreData/CoreData.h>
#import <RestKit/RestKit.h>
#interface WelcomeViewController ()
#property (nonatomic,strong) NSFetchedResultsController *fetchResultsController;
#property (strong, nonatomic) IBOutlet UILabel *welcomeTextLabel;
#end
#implementation WelcomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.fetchResultsController performFetch:nil];
UserInformation *entry = [[self.fetchResultsController fetchedObjects] objectAtIndex:0];
_welcomeTextLabel.text = [NSString stringWithFormat: #"Welcome " #"%#!", entry.firstName];
[self postUserInformation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSFetchRequest *)entryFetchRequest{
NSFetchRequest *fetchReqeust = [NSFetchRequest fetchRequestWithEntityName:#"UserInformation"];
fetchReqeust.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"createdAt" ascending:NO]];
return fetchReqeust;
}
- (NSFetchedResultsController *)fetchResultsController {
if (_fetchResultsController != nil) {
return _fetchResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryFetchRequest];
_fetchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
return _fetchResultsController;
}
- (void) postUserInformation {
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
[self.fetchResultsController performFetch:nil];
UserInformation *entry = [[self.fetchResultsController fetchedObjects] objectAtIndex:0];
RKObjectManager *manager = [RKObjectManager sharedManager];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[UserInformation class]];
NSDictionary *userInformation = #{
#"id" : #"userID",
#"first_name" : #"firstName",
#"last_name" : #"lastName",
#"device_descriptor" : #"deviceHardwareID",
#"created_at" : #"created_at",
#"updated_at" : #"updated_at",
#"idfa" : #"deviceAdvertisementID",
#"btmacid" : #"btmac_Id"
};
[responseMapping addAttributeMappingsFromDictionary:userInformation];
manager.requestSerializationMIMEType = RKMIMETypeJSON;
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:#"/users" keyPath:nil statusCodes:statusCodes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:userInformation];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[userInformation class] rootKeyPath:nil method:RKRequestMethodAny];
[manager addResponseDescriptor:responseDescriptor];
[manager addRequestDescriptor:requestDescriptor];
// NSDictionary *params = #{
// #"id" : entry.userID,
// #"first_name" : entry.firstName,
// #"last_name" : entry.lastName,
// #"device_descriptor" : entry.deviceHardwareID,
// #"created_at" : entry.createdAt,
// #"updated_at" : entry.updatedAt,
// #"idfa" : entry.deviceAdvertisementID,
// #"btmacid" : entry.btmacID
// };
[manager postObject:userInformation path:#"http://serverendpoint.com/users" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Any help you all could provide would be greatly appreciated.
You shouldn't create the request mapping with
[requestMapping addAttributeMappingsFromDictionary:userInformation];
Because the inputs and outputs are the wrong way around. Instead, use the inverseMapping from your response mapping.