Confusion setting mapping in RKObjectMapping - Rest - iphone

Please help in set mapping with RestKit, I am lost to find how to do this.
My JSON is like
{
"result":{
"success":"1",
"message":"You logged in successfully.",
"data":{
"user_id":"1",
"firstname":"somefirstname",
"lastname":"somelastname",
"username":"someusername",
"country_id":"someid",
"country_name":"somecountry",
"phone":"1234567890",
"status":"active"
}
}
}
What I have done so far is
RKObjectMapping *loginMapping = [RKObjectMapping mappingForClass:[Login class]];
[loginMapping addAttributeMappingsFromDictionary:#{ #"user_id":#"intUserID", #"firstname":#"strFirstName", #"lastname":#"strLastName"}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:loginMapping
method:RKRequestMethodGET
pathPattern:#"PathTOLogin"
keyPath:#"result.data"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSURL *baseURL = [NSURL URLWithString:kAPIBaseURLString];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
Login *loginObject = [[Login alloc] init];
[objectManager getObject:loginObject path:kUserLogin parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
The problems is like some times JSON response may be like
{
"result":{
"success":"0",
"message":"Invalid Username or Password",
}
}
So it throws error
Error Domain=org.restkit.RestKit.ErrorDomain Code=1001
So I thought to add 2 more properties in Model class as success/message along with all other properties but I stuck on setting custom mapping as those properties are on root and other is in key path "result.data".
Can somebody please help.

You should change your login mapping to something like:
RKObjectMapping *loginMapping = [RKObjectMapping mappingForClass:[Login class]];
[loginMapping addAttributeMappingsFromDictionary:#{ #"success":#"success", #"message":#"message", #"data.user_id":#"intUserID", #"data.firstname":#"strFirstName", #"data.lastname":#"strLastName"}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:loginMapping
method:RKRequestMethodGET
pathPattern:#"PathTOLogin"
keyPath:#"result"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Basically, remove 'data' from the key path of the response descriptor and instead use it in the mapping key paths.

you can first check whether data exists or not by checking the following condition
if([yourDictionary valueForKeyPath:#"result.data"]){
RKObjectMapping *loginMapping = [RKObjectMapping mappingForClass:[Login class]];
[loginMapping addAttributeMappingsFromDictionary:#{ #"user_id":#"intUserID", #"firstname":#"strFirstName", #"lastname":#"strLastName"}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:loginMapping
method:RKRequestMethodGET
pathPattern:#"PathTOLogin"
keyPath:#"result.data"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSURL *baseURL = [NSURL URLWithString:kAPIBaseURLString];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
Login *loginObject = [[Login alloc] init];
[objectManager getObject:loginObject path:kUserLogin parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
}
else{
NSLog(#"No data available");
}
Hope this will help you.

Related

Mapping a large JSON with Restkit

I am using restkit for a time now. And everything worked perfect. But now I want to map a json into my core database. This is a JSON of (10 MB). You can see the JSON over here.
I have an API class where I do my mapping
-(RKObjectManager *)mapGetItems{
RKEntityMapping* rubriekMapping = [RKEntityMapping mappingForEntityForName:#"Items" inManagedObjectStore:managedObjectStore];
rubriekMapping.identificationAttributes = #[#"itemNum"] ;
[rubriekMapping addAttributeMappingsFromDictionary:#{
#"ItemNum": #"itemNum",
#"ItemDescNl": #"itemDescNl",
#"ItemDescFr": #"itemDescFr",
#"Group1": #"group1",
#"Group2": #"group2",
#"Group3": #"group3",
#"Group4": #"group4",
#"DateCr": #"dateCr",
#"GrpItem": #"grpItem",
#"GrpDesc1": #"grpDesc1",
#"GrpDesc2": #"grpDesc2",
#"GrpDesc1Fr": #"grpDesc1Fr",
#"SalUnitNl": #"salUnitNl",
#"SalUnitFr": #"salUnitFr",
#"LadderQty": #"ladderQty",
#"Netprice": #"netPrice",
#"IsPromo": #"isPromo",
#"IsNew": #"isNew",
}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:rubriekMapping
pathPattern:nil
keyPath:#"ds-ttitems.tt-items" statusCodes:[NSIndexSet indexSetWithIndex:200]];
NSArray *arrResponsDescriptor = [[NSArray alloc]initWithObjects:responseDescriptor, nil];
[objectManager addResponseDescriptorsFromArray:arrResponsDescriptor];
return objectManager;
}
And a dataModel class, in this class I setup my object store.
This is all going well and everything is set up correctly.
Now for my request I do this.
-(void)fetchRubrieken{
API *api = [API new];
RKManagedObjectStore *store = [[ClaesDataModel sharedDataModel] objectStore];
NSManagedObjectContext *context = store.mainQueueManagedObjectContext;
RKObjectManager *objectManager = [api mapGetItems];
NSString *request = #"/claes/items.json";
[objectManager getObjectsAtPath:request parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSError *error = nil;
BOOL success = [store.mainQueueManagedObjectContext save:&error];
if (!success) RKLogWarning(#"Failed saving managed object context: %#", error);
NSLog(#"done fetching");
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
NSLog(#"Hit error: %#", error);
}];
NSError *error = nil;
[context save:&error];
}
The problem is not that it isn't working. It only takes a very very long time. So my question is, how can i make this go faster?
Hope that anybody can help me!
Kind regards,
PS. If you need more details, I will provide but I think this is the essential part.

AFNetworking POST created but blank

I am building a rails-backed ios app that uses AFNetworking to POST content to a server. A user can upload a photo with a comment - and this works. I also want to have the option to let a user upload just text- this is where I am having trouble. I have one method for saving a photo and text, and another method for saving just text. The save photo method works, but the save text method creates a post but the text is null.
The save photo implementation is like this:
- (void)savePhotoAtLocation:(CLLocation *)location
withBlock:(void (^)(CGFloat))progressBlock completion:(void (^)(BOOL, NSError *))completionBlock {
if (!self.content) self.content = #"";
NSDictionary *params = #{
#"post[content]" : self.content,
#"post[lat]": #(location.coordinate.latitude),
#"post[lng]": #(location.coordinate.longitude)
};
NSURLRequest *postRequest = [[APIClient sharedClient] multipartFormRequestWithMethod:#"POST" path:#"/posts" parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFileData:self.photoData
name:#"post[photo]"
fileName:#""
mimeType:#"image/png"];
}];
AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];
This method only works when there is photoData- if you don't have photoData, the app crashes.
So I am wondering what is the equivalent to a multipartFormRequest- that lets you only include a string?
This is what I have right now- which creates a post- but returns content: as well as the lat/lng params which should be returned with the current location.
This is defined in the post model
- (void)savePostAtLocation:(CLLocation *)location
withBlock:(void (^)(CGFloat progress))progressBlock completion:(void (^)(BOOL success, NSError *error))completionBlock {
if (!self.content) self.content = #"";
NSDictionary *params = #{
#"post[content]" : self.content,
#"post[lat]" : #(location.coordinate.latitude),
#"post[lng]" : #(location.coordinate.longitude)
};
NSURLRequest *postRequest = [[APIClient sharedClient]requestWithMethod:#"POST" path:#"/posts" parameters:params];
AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (operation.response.statusCode == 200 || operation.response.statusCode == 201) {
NSLog(#"Created, %#", responseObject);
NSDictionary *updatedPost = [responseObject objectForKey:#"post"];
[self updateFromJSON:updatedPost];
[self notifyCreated];
completionBlock(YES, nil);
} else {
completionBlock(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completionBlock(NO, error);
}];
[[APIClient sharedClient] enqueueHTTPRequestOperation:operation];
}
And in the AddPostViewController save calls this:
- (void)save:(id)sender
{
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
[self getLocation];
CLLocation * location = [locationManager location];
Post *post = [[Post alloc] init];
post.content = self.contentTextField.text;
[self.view endEditing:YES];
ProgressView *progressView = [ProgressView presentInWindow:self.view.window];
if (location) {
[post savePostAtLocation:self.locationManager.location withBlock:^(CGFloat progress) {
[progressView setProgress:progress];
} completion:^(BOOL success, NSError *error) {
[progressView dismiss];
if (success) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(#"ERROR: %#", error);
}
}];
} else {
NSLog(#"No Location");
}
}
Here is the log after a post is created. As you can see the attributes are null- and shouldn't be.
Created, {
post = {
content = "<null>";
"created_at" = "2013-07-21T18:45:12Z";
id = 13;
lat = "<null>";
lng = "<null>";
success = 1;
}
So the fact that a post is created but the attributes are null makes me think that the problem is simply in the NSURLRequest- and that I am not fully implementing the AFNetworking protocol but I haven't been able to find a way to implement a post request that doesn't entail fileData. How do I make a post request that doesn't append fileData?
Any help would be greatly appreciated.
Thanks!
You can copy your existing method but instead of using appendPartWithFileData:name:fileName:mimeType: to set file data you can convert your parameters to data and add them with appendPartWithFormData:name:.
This is how I got it to work:
post.h
+ (void)createNoteAtLocation:(CLLocation *)location
withContent:(NSString *)content
block:(void (^)(Post *post))block;
post.m
+ (void)createNoteAtLocation:(CLLocation *)location
withContent:(NSString *)content
block:(void (^)(Post *post))block
{
NSDictionary *parameters = #{ #"post": #{
#"lat": #(location.coordinate.latitude),
#"lng": #(location.coordinate.longitude),
#"content": content
}
};
[[APIClient sharedClient] postPath:#"/posts" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
Post *post = [[Post alloc] initWithDictionary:responseObject];
if (block) {
block(post);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block(nil);
}
}];
}
And finally in the createPostViewController:
- (void)save:(id)sender
{
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
[self getLocation];
CLLocation * location = [locationManager location];
Post *post = [[Post alloc] init];
post.content = self.contentTextField.text;
[self.view endEditing:YES];
if (location) {
[Post createNoteAtLocation:location withContent:self.contentTextField.text block:^(Post *post) {
NSLog(#"Block: %#", post);
[self.navigationController popViewControllerAnimated:YES];
}];
}

An active access token must be used to query information about the current user

I am trying to fetch user details but am currently unable to fetch images.This is the error I am getting:
{
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
}
This is my code:
if(!self.store)
{
ACAccountStore *store1 = [[ACAccountStore alloc] init];
self.store=store1;
[store1 release];
}
ACAccountType *fbAccountType =
[store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray * permissions = #[#"read_stream", #"publish_stream",#"email", #"user_birthday",#"publish_actions",#"user_photos"];
NSDictionary * dict = #{ACFacebookAppIdKey : #"my_key", ACFacebookPermissionsKey : permissions, ACFacebookAudienceKey : ACFacebookAudienceOnlyMe};
// Request permission from the user to access the available Twitter accounts
[store requestAccessToAccountsWithType:fbAccountType options:dict completion:^(BOOL granted, NSError *error) {
__block NSString * statusText = nil;
if (granted) {
statusText = #"Logged in";
NSArray * accounts = [store accountsWithAccountType:fbAccountType];
store = [accounts lastObject];
account = [accounts objectAtIndex:0];
NSLog(#"account is: %#", account);
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me?fields=picture"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = account;
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error) {
if(!error){
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data
options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
}
else{
//handle error gracefully
}
}];
}
If I use https://graph.facebook.com/me as url then it works fine. But I need the profile pic as well. What to do?
"fields" is a parameter, not a part of the URL itself. This works:
SLRequest *videoLimitsRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:[NSURL URLWithString:#"https://graph.facebook.com/me"]
parameters:#{#"fields": #"video_upload_limits"}];
FYI, token is added automatically when you attach account to the SLRequest.
you can run fql with accesstoken like this
https://graph.facebook.com/fql?q=SELECT name from user where uid = YourFAcebookID&access_token=ACCESSTOKEN
This will work for you.
This is a bit old but I forgot to answer then.
From FB api 3.2 onwards everything is managed within the api, for bot iOS 5 and 6 native login. Here is what I did:
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
FBRequest *request = [FBRequest requestWithGraphPath:#"me/albums" parameters:nil HTTPMethod:#"GET"];
FBRequestHandler handler =
^(FBRequestConnection *connection, id result, NSError *error)
{
if(!error)
{
NSDictionary *list =(NSDictionary*)result;
int flag = 0;
for (int index = 0; index < [[list objectForKey:#"data"] count];index++)
{
if ([[[[list objectForKey:#"data"] objectAtIndex:index] objectForKey:#"name"] isEqualToString:#"Profile Pictures"])
{
[self fetchAlbumImages:[[[list objectForKey:#"data"] objectAtIndex:index] objectForKey:#"id"]];
flag = 1;
}
}
if (flag == 0)
{
[self fetchAlbumImages:#"No Album"];
}
}
else
{
}
};
[newConnection addRequest:request completionHandler:handler];
//[self.requestConnection cancel];
[newConnection start];
[newConnection release];
}
- (void) fetchAlbumImages:(NSString*)albumId
{
if ([albumId isEqualToString:#"No Album"])
{
NSMutableArray *albumArray = [[NSMutableArray alloc]init];
[self performSelectorOnMainThread:#selector(sendRegistrationRequest:) withObject:albumArray waitUntilDone:YES];
[albumArray release];
}
else
{
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
FBRequest *request = [FBRequest requestWithGraphPath:[NSString stringWithFormat:#"%#/photos",albumId] parameters:nil HTTPMethod:#"GET"];
FBRequestHandler handler =
^(FBRequestConnection *connection, id result, NSError *error)
{
if(!error)
{
NSDictionary *list =(NSDictionary*)result;
NSMutableArray *albumArray = [[NSMutableArray alloc]init];
for (int index = 0; index < ([[list objectForKey:#"data"] count]<10?[[list objectForKey:#"data"] count]:10);index++)
{
[albumArray addObject:[[[list objectForKey:#"data"] objectAtIndex:index] objectForKey:#"source"]];
}
[self performSelectorOnMainThread:#selector(sendRegistrationRequest:) withObject:albumArray waitUntilDone:YES];
}
else
{
}
};
[newConnection addRequest:request completionHandler:handler];
//[self.requestConnection cancel];
self.requestConnection = newConnection;
[newConnection start];
[newConnection release];
}
}

SLRequest performRequestWithHandler does not work in ios 6

I am trying to build simple prototype where I post some text to my facebook account. I have read the ios 6 facebook integration documentation and came up with following code. Everything seems to work fine until I hit the last block where I create SLRequest object in method postTextToFacebook and try to execute performRequestWithHandler with handler block. Control never does inside the handler block. I am assuming that performRequestWithHandler call is not successful in this case. Any one have done with successfully? Here is code for your reference.
#import <Social/Social.h>
#import "ViewController.h"
#implementation ViewController
#synthesize facebookAccount;
#synthesize accountStore;
#synthesize textToPost;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(IBAction) postToFacebook:(id)sender
{
self.statusLabel.text = #"Logging in ...";
if(self.accountStore == nil)
{
self.accountStore = [[ACAccountStore alloc] init];
}
ACAccountType *facebookAccountType = [self.accountStore enter code hereaccountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSMutableDictionary *myOptions = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"172197712918906", ACFacebookAppIdKey,
[NSArray arrayWithObjects:#"email", #"user_about_me", #"user_likes", nil], ACFacebookPermissionsKey, ACFacebookAudienceFriends, ACFacebookAudienceKey, nil];
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:myOptions completion:^(BOOL granted, NSError *error){
__block NSString *statusText;
if(granted)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
self.facebookAccount = [accounts lastObject];
[myOptions setObject:[NSArray arrayWithObjects:#"publish_stream", nil] forKey:ACFacebookPermissionsKey];
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:myOptions completion:^(BOOL granted, NSError *error) {
__block NSString *statusText1;
if(granted && error == nil)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
self.facebookAccount = [accounts lastObject];
[self postTextToFacebook];
statusText1 = #"Text Posted.";
}
else{
statusText1 = #"Publish Failed.";
}
dispatch_async(dispatch_get_main_queue(), ^{
self.statusLabel.text = statusText1;
});
}];
}
else{
statusText = #"Login Failed.";
NSLog(#"Error = %#",error);
}
}];
}
-(void) postTextToFacebook
{
NSDictionary *parameters = #{#"message":self.textToPost.text};
NSURL *feedURL = [NSURL URLWithString:#"https://graphs.facebook.com/me/feed"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:feedURL parameters:parameters];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Facebook request received, status code %d", urlResponse.statusCode);
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response data: %#", response);
//handle errors
if(error == nil)
{
dispatch_async(dispatch_get_main_queue(), ^{
self.statusLabel.text = #"text posted to facebook";
});
}
}];
}
#end
Your url should be
https://graph.facebook.com/me/feed
instead of
https://graphs.facebook.com/me/feed
I was having a same issue and got an NSURLErrorDomain -1003 error on it.

How to get cookies and use them for other requests like POST ( iOS )?

My previous question was about the problem that I have to login each time for doing web services like posting a link or uploading a picture. Philipe answered that I have to use cookies instead of login process for each request. I found this method for getting cookies:
- (void)getCookies {
NSHTTPURLResponse * response;
NSError * error;
NSMutableURLRequest *request;
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://MyWebsite.com/login.php"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:120];
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"%#", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:#"http://MyWebsite.com/login.php"]];
NSLog(#"%d", all.count);
for (NSHTTPCookie *cookie in all) {
NSLog(#"Name: %# : Value: %#", cookie.name, cookie.value);
NSLog(#"Comment: %# : CommentURL: %#", cookie.comment, cookie.commentURL);
NSLog(#"Domain: %# : ExpiresDate: %#", cookie.domain, cookie.expiresDate);
NSLog(#"isHTTPOnly: %c : isSecure: %c", cookie.isHTTPOnly, cookie.isSecure);
NSLog(#"isSessionOnly: %c : path: %#", cookie.isSessionOnly, cookie.path);
NSLog(#"portList: %# : properties: %#", cookie.portList, cookie.properties);
NSLog(#"version: %u", cookie.version);
}
}
I also found this code to use these cookies, but I'm not sure how to use it:
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookies];
Here is my method for POSTing, I am using RestKit API:
- (IBAction)addLinkPressed:(UIButton *)sender {
[RKClient clientWithBaseURLString:#"http://MyWebsite.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
self.linkField.text, #"url",
self.linkTitleField.text, #"title",
self.linkSummaryField.text, #"summary",
nil];
RKRequest *request = [[RKClient sharedClient] post:#"/send_link.php" params:params delegate:self];
[request setUserData:#"sendLink"];
}
Question: Which property of cookies should I store to use it for login information and where should I put it in my code?
I solved this issue by some inefficient way. Here is my methodology:
First I try to post to the web service and after posting I parse the returning HTML to see if the posting was successful or not. If posting was successful I give an appropriate message to the user that you post successfully but if it was not successful it could have two reasons: First: there were some error during the post execution Second: the user was not logged in. The way that I recognize the differentiation between fist and second error is just parsing the response HTML.
Here is the code that I used for this methodology (this is for the time that the user wants to change the password)
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSRange range = [[error localizedDescription] rangeOfString:#"-1012"];
if (range.length > 0){
//First error occurs here
}
RKLogError(#"Hit error: %#", error);
}
- (IBAction)requestToChangePasswordPressed {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Loading";
[RKClient clientWithBaseURLString:#"http://WebServiceDomain.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
self.oldPasswordField.text, #"oldPassword",
self.passwordNew.text, #"newPassword",
self.confirmPasswordField.text, #"confirmPassword",
nil];
RKRequest *request = [[RKClient sharedClient] post:#"/change_password.php" params:params delegate:self];
[request setUserData:#"changePassword"];
[self.view endEditing:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
- (void)autoLogin {
[RKClient clientWithBaseURLString:#"http://WebServiceDomain.com"];
[RKObjectManager sharedManager].client=[RKClient sharedClient];
RKParams *parameters = [RKParams params];
[parameters setValue:[[NSUserDefaults standardUserDefaults] objectForKey:#"defaultUsername"] forParam:#"username"];
[parameters setValue:[[NSUserDefaults standardUserDefaults] objectForKey:#"defaultPassword"] forParam:#"password"];
[[RKClient sharedClient] setAuthenticationType:RKRequestAuthenticationTypeHTTP];
// because we have two POSTs and we want to use the same method for both of the for didLoadResponse: we set the UserDate like bellow
RKRequest *request = [[RKClient sharedClient] post:#"/login.php" params:parameters delegate:self];
[request setUserData:#"login"];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Loading";
id userData = [request userData];
if ([userData isEqual:#"login"]) {
if ([request isGET]) {
// Handling GET /foo.xml
if ([response isOK]) {
// Success! Let's take a look at the data
NSLog(#"Retrieved XML: %#", [response bodyAsString]);
}
} else if ([request isPOST]) {
// Handling POST /other.json
if ([response isJSON]) {
NSLog(#"Got a JSON response back from our POST!");
}
} else if ([request isDELETE]) {
// Handling DELETE /missing_resource.txt
if ([response isNotFound]) {
NSLog(#"The resource path '%#' was not found.", [request resourcePath]);
}
}
}
else if ([userData isEqual:#"sendLink"]) {
NSData *addLinksHtmlData = response.body;
// 2
TFHpple *addlinksParser = [TFHpple hppleWithHTMLData:addLinksHtmlData];
// 3
NSString *errorLinksXpathQueryString = #"//div[#class='errorBox']/ul/li";
NSArray *errorLinksNodes = [addlinksParser searchWithXPathQuery:errorLinksXpathQueryString];
// 4
NSMutableArray *newErrorLinks = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in errorLinksNodes) {
// 5
AllModels *errorTitle = [[AllModels alloc] init];
[newErrorLinks addObject:errorTitle];
// 6
errorTitle.errorTitle = [[element firstChild] content];
}
// 8
self.linkErrorObjects = newErrorLinks;
NSString *successLinksXpathQueryString = #"//div[#class='successBox']";
NSArray *successLinksNodes = [addlinksParser searchWithXPathQuery:successLinksXpathQueryString];
// 4
NSMutableArray *newSuccessLinks = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in successLinksNodes) {
// 5
AllModels *successTitle = [[AllModels alloc] init];
[newSuccessLinks addObject:successTitle];
// 6
successTitle.successTitle = [[element firstChild] content];
}
// 8
self.linkSuccessObjects = newSuccessLinks;
}
else {
NSLog(#"HTTP status code: %d", response.statusCode);
NSLog(#"HTTP status message: %#", [response localizedStatusCodeString]);
NSLog(#"Header fields: %#", response.allHeaderFields);
NSLog(#"Body: %#", response.bodyAsString);
NSData *HtmlData = response.body;
// 2
TFHpple *addParser = [TFHpple hppleWithHTMLData:HtmlData];
// 3
NSString *errorXpathQueryString = #"//div[#class='errorBox']/ul/li";
NSArray *errorNodes = [addParser searchWithXPathQuery:errorXpathQueryString];
// 4
NSMutableArray *newError = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in errorNodes) {
// 5
AllModels *errorTitle = [[AllModels alloc] init];
[newError addObject:errorTitle];
// 6
errorTitle.errorTitle = [[element firstChild] content];
}
// 8
self.ErrorObjects = newError;
NSString *successXpathQueryString = #"//div[#class='successBox']";
NSArray *successNodes = [addParser searchWithXPathQuery:successXpathQueryString];
// 4
NSMutableArray *newSuccess = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in successNodes) {
// 5
AllModels *successTitle = [[AllModels alloc] init];
[newSuccess addObject:successTitle];
// 6
successTitle.successTitle = [[element firstChild] content];
}
// 8
self.successObjects = newSuccess;
[self errorCheck];
}
[MBProgressHUD hideHUDForView:self.view animated:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
- (void)errorCheck {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Loading";
if(self.errorObjects.count > 0) {
AllModels *errorlink = [self.errorObjects objectAtIndex:0];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"There is a problem" message:errorlink.errorTitle delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil , nil];
[alert show];
}
else {
if(self.linkErrorObjects.count > 0) {
[self autoLogin];
[self requestToChangePasswordPressed];
}
else {
AllModels *successlink = [self.successObjects objectAtIndex:0];
self.successLabel.hidden = NO;
self.successLabel.text = successlink.successTitle;
NSLog(#"Success Title: %#",successlink.successTitle);
[UIView animateWithDuration:3.0
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{ self.successLabel.alpha = 0.0; }
completion:^(BOOL fin) { if (fin) [self.successLabel removeFromSuperview]; }];
[self performSelector:#selector(dismissModalViewController) withObject:nil afterDelay:1.0];
}
}
[MBProgressHUD hideHUDForView:self.view animated:YES];
[MBProgressHUD hideHUDForView:self.view animated:YES];
}