I am new to restkit.I have integrated restkit 0.20.0-pre6 successfully by following instructions from github. Then I have build my project in console, I got the following
restkit:RKLog.m:34 RestKit logging initialized...
after that I would like to get data at a path
Initially there is an activation screen .so I would like to send activation code to it and if it is correct, I would like to get corresponding details .
NSURL *urll=[NSURL URLWithString:#"http://url/FirstRest/rest/application/Activate"];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:urll];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:client];
[RKObjectManager setSharedManager:manager];
Article *article = [Article new];
article.activationCode = #"S1234";
[manager.router.routeSet addRoute:[RKRoute routeWithClass:[Article class] pathPattern:#"/FirstRest/rest/application/Activate/:activationCode" method:RKRequestMethodGET]];
[[RKObjectManager sharedManager] getObject:article path:nil parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *result)
{
// Request
NSLog(#"result is ************* %#",result);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}];
`
in my console I'm getting
I restkit.network:RKHTTPRequestOperation.m:179 GET 'http://url/FirstRest/rest/application/Activate/S1234' (200 OK) [1.4744 s]
2013-01-28 14:07:59.284 Polls[985:15103] E restkit.network:RKResponseMapperOperation.m:240 Failed to parse response data: Loaded an unprocessable response (200) with content type 'application/json'
I couldn't find out what does it really means and how to overcome this
The JSON you are getting as a response is probably malformed.
I've encoutered a similar situation and checked out the actual error object (CMD+SHIFT+F for "Failed to parse response", you'll find the lines).
After print description of the error, I found the JSON I was getting had duplicate keys, therefore was not parseable (altough most browsers / json viewers just ignored it).
Related
I use the below code to upload image to server.
NSString *url = [NSString stringWithFormat:#"http://192.250.1.52:xxx/api/user/profileUploadUser?userid=27&emailid=tom#gnts.in"];
NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc]init];
[jsonDict setObject:ImageToUpload forKey:#"file"];
////////ImageToUpload = /var/mobile/Containers/Data/Application/89112E0B-C1D6-4408-8586-6C5B4A431713/Documents/61.png
[manager POST:url parameters:jsonDict
success:^(AFHTTPRequestOperation *operation, id responseObject)
{ //////success code }
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Image upload" message:#"failure" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
NSLog(#"error message %#",error);
// handle failure
}];
It always enter into the failure block and
shows the error message.
error message : Error Domain=NSURLErrorDomain Code=-1001 "The request
timed out."
UserInfo={NSErrorFailingURLStringKey=http://192.250.1.52:xxxx/api/user/profileUploadUser?userid=27&emailid=tom#gnts.in, _kCFStreamErrorCodeKey=-21022}}}
Check your internet speed might be slow,
[manager.requestSerializer setTimeoutInterval:30];//Set request timeout interval time & interact with backend developer for same.
One more thing you can manage one retry counter in singleton & give second request if fails & if again fails then show toast message internet speed is slow.
You are trying to a POST operation whereas what you want is a file upload.
Try out AFNetworking multipart file upload.
I'm new to IOS development and was doing something related to dynamic data request through a 3rd party api using AFNetworing, I assume this is the good way to do networking in IOS?
One issue I have so far is I have two AFHTTPSessionManager in two different class implementation files. When I ran the application, the first one executes successfully. but the second one is not working and the problem is in debug mode, I can see that the
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:PLACE_DETAIL_URL
parameters:#{ #"key": APPLICATION_KEY,
#"placeid": placeid,
#"extensions": #"review_summary"
}
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#", responseObject);
placeDetail = [[NSDictionary alloc] initWithDictionary: (NSDictionary *) [responseObject objectForKey:#"result"]];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Places"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
is not even executing. It's been skipped for some reason. Is this a bug or I can only have on AFHTTPSessionManager or AFHTTPOperationManager at a time?
P.S.
debug gif posted here for clear idea.
thanks for all your help.
I have a Django Rest Api with a iOS app and right now I'm testing AFNetworking to change the HTTP Request my app is doing but i came with this dilema that i dont know how to handle, first is that on REST Standards when i get an error i should return a 404_BAD_REQUEST as a status if either sends or something wrong happens and this is OK. The issue comes when AFNetworking sees this 404. I still want to see the JSON that it returns.
curl -X POST http://domain.com:8000/user-login/ -d "nick=superUser&pass_field=superPassword"
i get 202 Status HTTP:
{
"nick": "eddwinpaz", "rate": 30, "name": "Eddwin Paz", "avatar": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/t1.0-1/p160x160/10270540_10154074250190063_1762683854515424400_n.jpg", "id": 9}eddwinpazs-MacBook-Pro:~ eddwinpaz$
}
When i get 404 BAD REQUEST i get:
{"message": "Invalid Username or Password"}
I want to grab that message json tag if i get a 404 Error
I've the following code. and put it on the message on the Alert
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"nick": #"eddwinpaz",#"pass_field":#"eddwinpaz1"};
AFHTTPRequestOperation *operation = [manager POST:#"http://domain.com/user-login/"];
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
[manager POST:#"http://domain.com/user-login/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Login Failed"
message:#"E-mail or password are wrong, Please Try Again"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[hud hide:YES];
}];
Per default the error code 404 is handled as an error code. You could add it as one of the accepted error codes via
AFHTTPRequestOperation *operation = [manager POST:#"http://doma...
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
Then success: is called on an 404 response and you can handle it there.
The answer by #miho did not work for me. addAcceptableStatusCodes does not exist in AFNetworking 2.5.0 from what I can tell. I had to do the following.
NSMutableIndexSet *acceptedCodes = [[NSMutableIndexSet alloc]
initWithIndexSet:operation.responseSerializer.acceptableStatusCodes];
[acceptedCodes addIndex:304];
operation.responseSerializer.acceptableStatusCodes = [acceptedCodes copy];
Hello and thanks in advance for your help. I've been looking but couldn't find an answer for this. I've only been programing for iOS for a week.
So far, all the connections to the web services are functioning and I've created a class and methods to do those calls. I'm making a standard login, user enters login info, the app passes those values to the web service and it returns a bool value depending if the info matches anything on the database. After that, the app gets the return value and it moves to the next screen or shows an error alert. Or at least that's what I'm aiming for.
The problem is that, the conditional is being executed before the rest call is made or the response parsed and I'm not having much luck finding a solution. I've read about asynchronous and synchronous calls but hadn't have much luck at implementing them.
This is the call code:
//Class that has the methods for calling the web services
__restObj = [[restCalls alloc] init];
bool login = [__restObj restLogin:user passwd:pass];
if (login) {
[self performSegueWithIdentifier:#"adminLogin" sender:self];
}
else{
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Incorrect group name or password." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
The conditional in being performed before the actual POST occurs and there for is always false.
This is my method:
- (bool)restLogin:(NSString*)user passwd:(NSString*)pass{
// Load the object model via RestKit
RKObjectManager *objectManager = [RKObjectManager sharedManager];
groupInfo *gi = [[groupInfo alloc] init];
gi.gName = user;
gi.pass = pass;
RKObjectMapping *userInfoMapping = [RKObjectMapping requestMapping];
[userInfoMapping addAttributeMappingsFromDictionary:#{#"gName": #"groupName",#"pass":#"pass"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userInfoMapping
objectClass:[groupInfo class]
rootKeyPath:nil];
[objectManager addRequestDescriptor:requestDescriptor];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager postObject:gi
path:#"adminLoginIos"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSArray* statuses = [mappingResult array];
NSLog(#"Loaded statuses: %#", statuses);
_result = [statuses objectAtIndex:0];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Hit error: %#", error);
}
];
return _result;
}
Thanks in advance and keep in mind that I'm really new at this so I appreciate your help and if my code is not the best please tell me so.
Regards,
ChmlGr
You need to pass in a block and then inside the success callback, block return the _result.
An example based on your structure would be something like:
-(void) restLogin:(NSString*)user passwd:(NSString*)pass block:(void (^)(id))block {
// Load the object model via RestKit
RKObjectManager *objectManager = [RKObjectManager sharedManager];
groupInfo *gi = [[groupInfo alloc] init];
gi.gName = user;
gi.pass = pass;
RKObjectMapping *userInfoMapping = [RKObjectMapping requestMapping];
[userInfoMapping addAttributeMappingsFromDictionary:#{#"gName": #"groupName",#"pass":#"pass"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userInfoMapping
objectClass:[groupInfo class]
rootKeyPath:nil];
[objectManager addRequestDescriptor:requestDescriptor];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager postObject:gi
path:#"adminLoginIos"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSArray* statuses = [mappingResult array];
NSLog(#"Loaded statuses: %#", statuses);
_result = [statuses objectAtIndex:0];
block(_result);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Hit error: %#", error);
block(nil);
}
];
}
Your call to that method would be something like:
[__restObj restLogin:user passwd:pass block:^(id obj) {
// do something here to translate that object into a BOOL and check value
}];
I don't use RestKit, so I can't verify this is exactly what you need, but it should get you on the right path. That said, if you wanted to check out AFNetworking, I wrote a NetworkClient wrapper that I don't mind sharing.
I am trying to post to a URL using AFNetworking and no matter what I do I keep getting the error:
Error Code: -1011 - Expected status code in (200-299), got 404
My code is as follows:
NSString *baseurl = #"http://mysiteurl";
NSString *path = #"/user/register/";
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseurl]];
[client registerHTTPOperationClass:[AFJSONRequestOperation class]];
//[client setAuthorizationHeaderWithUsername:#"myusername" password:#"mypassword"];
[client postPath:path parameters:[NSDictionary dictionaryWithObjectsAndKeys:_userName,#"user", _email, #"email",_password,#"password", nil] success:^(AFHTTPRequestOperation *operation, id JSON) {
//NSLog(#"sjson: %#", [JSON valueForKeyPath:#"entries"]);
NSLog(#"sjson: %#", JSON);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error Code: %i - %#",[error code], [error localizedDescription]);
}];
When I go to http://mysiteurl/user/register/ directly I am able to see JSON.
What am I doing wrong?
When I go to http://mysiteurl/user/register/ directly I am able to see JSON.
If you're doing this through a browser, you are making a GET request, whereas in your code, you are making a POST request.
A 404 is not just the visible address, it includes the HTTP method as well. You need to make sure that your server responds to a POST at http://mysiteurl/user/register/. Depending on your framework (e.g. Rails), you may have to add [client setDefaultHeader:#"Accept" value:#"text/json"] to get the correct route.
i usually use [client getPath: parameters:params success:] not Post but i guess this will work for both cases since your response is in a JSON format too
add these two lines
[client.parameterEncoding = AFJSONParameterEncoding;
[client setDefaultHeader:#"Accept" value:#"text/json"];
before
[client registerHTTPOperationClass:[AFJSONRequestOperation class]];