I'm doing a Restkit GET operation but getting an error with Restkit. I tried the same operation with the REST COnsole on Chrome and it works:
DEtails of the GET operation are:
URL: https://www.ez-point.com/ezpoints
Operation: GET
Authorization Header: xxxxxxxxxxxxxxxxxxx
With the Chrome REST Console, it works and I get the proper response in JSON.
With Restkit, it doesn't work. THese are my Restkit codes:
//trying restkit
NSURL *endpoint = [NSURL URLWithString:#"https://www.ez-point.com/"];
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:endpoint];
[objectManager.HTTPClient setAuthorizationHeaderWithToken:#"xxxxxxxxxxxxxxxxxxx"];
[objectManager getObjectsAtPath:#"ezpoints" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
//NSLog(mappingResult);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
//NSLog(operation);
//NSLog(error);
}];
I'm getting this error:
2013-10-25 11:00:11.690 EZ-POINT[1089:c07] I restkit:RKLog.m:34 RestKit logging initialized...
2013-10-25 11:00:12.820 EZ-POINT[1089:c07] I restkit.network:RKObjectRequestOperation.m:180 GET 'https://www.ez-point.com/ezpoints'
2013-10-25 11:00:14.184 EZ-POINT[1089:4507] E restkit.network:RKObjectRequestOperation.m:576 Object request failed: Underlying HTTP request operation failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1016 "Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html" UserInfo=0x110a3560 {AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest https://www.ez-point.com/ezpoints>, NSErrorFailingURLKey=https://www.ez-point.com/ezpoints, NSLocalizedDescription=Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x110b42b0>}
2013-10-25 11:00:14.185 EZ-POINT[1089:4507] E restkit.network:RKObjectRequestOperation.m:243 GET 'https://www.ez-point.com/ezpoints' (401 Unauthorized / 0 objects) [request=0.0000s mapping=0.0000s total=1.3657s]: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1016 "Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html" UserInfo=0x110a3560 {AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest https://www.ez-point.com/ezpoints>, NSErrorFailingURLKey=https://www.ez-point.com/ezpoints, NSLocalizedDescription=Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x110b42b0>}
2013-10-25 11:00:14.599 EZ-POINT[1089:c07] Failure
Any suggestion?
The error already gives a hint: it doesn't accept "text/xml" as a content type by default. Right now, it accepts
application/x-www-form-urlencoded
application/json
You can register it using RKMIMETypeSerialization and add "text/xml" to one of the accepted content types:
[RKMIMETypeSerialization registerClass:[RKXMLReaderSerialization class] forMIMEType:RKMIMETypeTextXML];
[objectManager setAcceptHeaderWithMIMEType:#"text/xml"];
Related
Im making an app that communicates with a rails based backend server.
I already have all the server calls ready and working via RESTKit, but I am having
problems with creating error mappings for my update calls.
My response descriptors for one of my classes
RKResponseDescriptor *descriptor = [RKResponseDescriptor responseDescriptorWithMapping:[Mappings liveViewMapping]
method:RKRequestMethodAny
pathPattern:nil
keyPath:#"event_enriched"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self addResponseDescriptor:descriptor];
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[Mappings errorMapping]
method:RKRequestMethodAny
pathPattern:nil
keyPath:#"error"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[self addResponseDescriptor:errorDescriptor];
Edit: I've also tried it with keyPath "errors" and 'nil' .. same results
My error mapping is quite simple:
+ (RKObjectMapping *)errorCollectionMapping {
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[ErrorCollection class]];
NSDictionary *mappingDictionary = #{#"error" : #"message",
#"errors" : #"messages",
};
[errorMapping addAttributeMappingsFromDictionary:mappingDictionary];
return errorMapping;
}
This is how I am trying to update my Book object
[self putObject:book
path:API_BOOK
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
if (success) {
Book *book = [mappingResult.dictionary objectForKey:#"book"];
success(book);
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if (failure) failure(operation, error);
}
];
But when I get a server error, which should be handled by my response descriptor I get the following error:
Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No mappable object representations were found at the key paths searched." UserInfo=0x7f935d07c7a0 {NSLocalizedDescription=No mappable object representations were found at the key paths searched., NSLocalizedFailureReason=The mapping operation was unable to find any nested object representations at the key paths searched: book
The representation inputted to the mapper was found to contain nested object representations at the following key paths: error, error_description
This likely indicates that you have misconfigured the key paths for your mappings., keyPath=null, DetailedErrors=(
)}
What am I doing wrong?
I already have some GET requests, that have multiple mappings (non of them is an error mapping yet) which works fine, but can't "replicate" the same behavior with error mapping
oh.. I am using restkit-0.24 :)
edit:
the error responses coming back from my rails server are in this form:
{"errors": ["error1", "error2" ... ] }
or
{"error": "error message" }
i feel so stupid right now ...
The server responses had code 200 and not the 400-499 range that RKStatusCodeClassClientError predicts.
OK, so I've reviewed almost every single one of the other questions on this site, to no avail.
Here's my JSON that comes back from a REST service:
{
"errors" : {};
"result" : {
"messagebody" : "Hello!";
"timestamp" : "2014-08-21T04:12:28.4689099+00:00";
};
"success" : {};
}
I am trying to pull out the result object via RestKit v0.20.3
Here's a block of my code where it gets configured/executed:
- (void) configureRestKit
{
NSURL *cminstance = [NSURL URLWithString:#"http://<domain>"];
AFHTTPClient *cmclient = [[AFHTTPClient alloc] initWithBaseURL:cminstance];
RKObjectManager *objmgr = [[RKObjectManager alloc] initWithHTTPClient:cmclient];
RKObjectMapping *messageMap = [RKObjectMapping mappingForClass:[Message class]];
[messageMap addAttributeMappingsFromDictionary:#{ #"messagebody" : #"messagebody", #"timestamp": #"timestamp"}];
messageMap.forceCollectionMapping = YES;
RKResponseDescriptor *descriptor =
[RKResponseDescriptor
responseDescriptorWithMapping:messageMap
method:RKRequestMethodGET
pathPattern:#"/v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test"
keyPath:#"result"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objmgr addResponseDescriptor:descriptor];
}
- (IBAction)helloButtonClicked:(id)sender {
[[RKObjectManager sharedManager].HTTPClient setDefaultHeader:#"X-App-ApiKey" value:#"2c130c75dc9f4c2c8ef7c8753e8b7c56"];
NSLog(#"ResponseDescriptors %#", [[RKObjectManager sharedManager] responseDescriptors]);
[[RKObjectManager sharedManager] getObjectsAtPath:#"/v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
_Response.text = [mappingResult.dictionary objectForKey:#"messagebody"];
} failure:^(RKObjectRequestOperation *operation, NSError *error)
{
_Response.text = #"Something went wrong.";
}];
}
Here's the error from the trace:
2014-08-21 00:12:30.653 The-App[13924:3707] E restkit.network:RKObjectRequestOperation.m:208 GET 'http:///v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test' (200 OK / 0 objects) [request=2.7297s mapping=0.0000s total=2.7365s]:
error=Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No response descriptors match the response loaded." UserInfo=0xb164380 {NSErrorFailingURLStringKey=http:///v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test, NSLocalizedFailureReason=A 200 response was loaded from the URL 'http:///v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test', which failed to match all (0) response descriptors:, NSLocalizedDescription=No response descriptors match the response loaded., keyPath=null, NSErrorFailingURLKey=http:///v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test, NSUnderlyingError=0xb1641c0 "No mappable object representations were found at the key paths searched."}
response.body={"success":{},"errors":{},"result":{"messagebody":"Hello!","timestamp":"2014-08-21T04:12:28.4689099+00:00"}}
Any ideas here on how to troubleshoot? I've been banging my head on this one for a few hours and google has not been my friend.
EDIT: The Response Descriptors
2014-08-22 10:41:21.580 Apprenda-CloudMine-App[10987:60b] ResponseDescriptors (
"<RKResponseDescriptor: 0x17826c180 method=(GET) pathPattern=/v1/app/e51cb2dd24af47a49232b942210e758d/text?f=test keyPath=result statusCodes=200-299 : <RKObjectMapping:0x17826bfc0 objectClass=Message propertyMappings=(\n \"<RKAttributeMapping: 0x1780499f0 timestamp => timestamp>\",\n \"<RKAttributeMapping: 0x17804cf30 messagebody => messagebody>\"\n)>>"
)
Thanks!
-Chris
That error indicates that the path between your request and your response descriptor are not matching. It is subtle, the (0) response descriptors in the error message also indicate to me that there are no response descriptors for that path. For more information on the error messages for RestKit path mismatches see this GitHub issue.
Why then are you getting a path mismatch? After all, the path in your request is exactly the same as your path in your response descriptor. It would seem that your problem is likely the GET parameter specified in the response descriptors path. You need to remove the get parameter from your response descriptors path since it is not technically part of the path.
It should be the following instead.
[RKResponseDescriptor
responseDescriptorWithMapping:messageMap
method:RKRequestMethodGET
pathPattern:#"/v1/app/e51cb2dd24af47a49232b942210e758d/text"
keyPath:#"result"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Thanks to Flaviu Simihaian for realizing this.
I receive this error when I attempt to use postObject in XCODE 5 for iOS 7:
Here is the error message without the URLs which point to https:// service
E restkit.network:RKObjectRequestOperation.m:542 Object request failed: Underlying HTTP request operation failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=-1016 "Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html" UserInfo=0xb9a44f0 {NSLocalizedRecoverySuggestion={"status": "ok"}, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest: 0x8dd14c0> { URL: http:
NSLocalizedDescription=Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/html, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xb998d30>
{ status code: 200, headers {
Connection = close;
"Content-Length" = 16;
"Content-Type" = "text/html; charset=utf-8";
Any object the I put in postObject method just returns text/html and not JSON. I does not appear to use the requestDescriptor or requestMapping that I defined. Its simply posting the object as text/html.
Is there another method of posting using RestKit?
Is there a fix or workaround for this issue?
Here's my code sample:
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary
[requestMapping addAttributeMappingsFromArray:#[#"email", #"nickname"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[RegisterDeviceInfo class] rootKeyPath:nil method:RKRequestMethodAny];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:_uuidURL]];
[RKObjectManager setSharedManager:objectManager];
[objectManager addRequestDescriptor:requestDescriptor];
RegisterDeviceInfo *deviceInfo = [RegisterDeviceInfo new];
deviceInfo.email = email;
deviceInfo.nickname = nickname;
// This is not accepted by the postObject and mapped to JSON object using above mappings and requestDescriptor
NSLog(#"deviceInfo is: %#", deviceInfo);
[[RKObjectManager sharedManager] postObject:deviceInfo path:(_uuidURL) parameters:nil success: nil failure: nil];
NSLog(#"deviceInfo is: %#", deviceInfo);
You should show the rest of the error (the lines before what you show). This is about the response, not the request. An HTML response often means an error message and you need to see what that is to know what's wrong.
The issue appears to be that you are using (_uuidURL) as the path when you call postObject but that it is the full URL.
The path should be relative to the base URL that was used to create the object manager. i.e.
baseURL = #"www.myserver.com/"
path = #"mycontent"
I'm using RESTKit v0.20.3. Since I'm not expecting a responseObject, I decided to use AFHTTPClient to POST. I have the following Code:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
httpClient.parameterEncoding = AFJSONParameterEncoding;
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient setDefaultHeader:#"Accept" value:#"application/json"];
[httpClient postPath:#"/update" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"AFJSONRequestOperation Alt response MIMEType %#",[responseObject MIMEType]);
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"***ERROR*****: %#", [error localizedDescription]);
}];
Here is my log
2014-04-01 16:43:01.125 App[13181:60b] E restkit.network:RKObjectRequestOperation.m:209 POST 'http://api.domain.com' (200 OK) [0.1158 s]: Error Domain=AFNetworkingErrorDomain Code=-1016 "Expected content type {(
"text/json",
"application/json",
"text/javascript"
)}, got text/html" UserInfo=0xccab6a0 {NSLocalizedRecoverySuggestion=<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Not Found</h1><h2>404</h2><pre>Error: Not Found
at Object.handle (/var/app/current/app.js:175:15)
at next (/var/app/current/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at pass (/var/app/current/node_modules/express/lib/router/index.js:110:24)
at Router._dispatch (/var/app/current/node_modules/express/lib/router/index.js:173:5)
at Object.router (/var/app/current/node_modules/express/lib/router/index.js:33:10)
at next (/var/app/current/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at SessionStrategy.module.exports.strategy.pass (/var/app/current/node_modules/passport/lib/middleware/authenticate.js:314:9)
at SessionStrategy.authenticate (/var/app/current/node_modules/passport/lib/strategies/session.js:61:12)
at pass (/var/app/current/node_modules/passport/lib/authenticator.js:333:31)
at deserialized (/var/app/current/node_modules/passport/lib/authenticator.js:345:7)</pre></body></html>, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest: 0xda43280> { URL: http://api.domain.com/update }, NSErrorFailingURLKey=http://api.domain.com/update, NSLocalizedDescription=Expected content type {(
"text/json",
"application/json",
"text/javascript"
)}, got text/html, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xdd50720> { URL: http://api.domain.com/update } { status code: 200, headers {
"Content-Length" = 1083;
"Content-Type" = "text/html; charset=utf-8";
Date = "Tue, 01 Apr 2014 23:43:12 GMT";
"Proxy-Connection" = "Keep-alive";
Server = "nginx/1.4.3";
"X-Powered-By" = Express;
} }}
2014-04-01 16:43:01.126 App[13181:60b] ***ERROR*****: Expected content type {(
"text/json",
"application/json",
"text/javascript"
)}, got text/html
I get the error is in receiving text/html, but how can I tell AFHTTPClient to expect text/html?
I tried adding:
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
that returns:
2014-04-01 16:48:13.110 App[13289:60b] ***ERROR*****: The operation couldn’t be completed. (Cocoa error 3840.)
If I use AFHTTPRequestOperation, how do I pass parameters to it? I'm using RESTKit, so I can't use AFNetworking 2.0. Code Example would be greatly appreciated!
If you check the content of the HTML it actually says:
<h1>Not Found</h1><h2>404</h2>
So, the problem is not that the page you request doesn't exist rather than the returned content type being wrong.
Verify the URL and path that you are using.
I'm working on an iOS app (pretty new to iOS) and I have my registration flow working where i post data to my server... The server returns JSON, but my question is, how do I parse that into variables?
The data that it returns is:
{"token":"67f41f60-9a9a-11e3-8310-11b6baf18c40","userId":13,"stationId":1}
The code I'm using to make the post request is:
[manager POST:#"http://localhost:3000/service/register_user/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error!!!!!: %#", error);
}];
Also, when I make the post request, this is what I get in the log in xcode
2014-02-20 20:50:39.799 FlashoverResponse[4668:70b] Error!!!!!: Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x8a5e4f0 {NSErrorFailingURLKey=http://localhost:3000/service/register_user/, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x8a5e200> { URL: http://localhost:3000/service/register_user/ } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 74;
"Content-Type" = "text/html; charset=utf-8";
Date = "Fri, 21 Feb 2014 01:50:39 GMT";
"X-Powered-By" = Express;
} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
Is your server configured to respond in text/json application/json?
and/or have you set this?
manager.responseSerializer.acceptableContentTypes
it takes a NSSet of content types this parser will attempt to parse, if you cannot change the server to respond in json you can add text/html into that set, so the parser will parse it anyway.