How to find size of object in iOS? - ios

I am working on a app in which I have to find size of web service response and response type is id. Please suggest me a suitable answer to fetch size of id object.
Here in this code I have to find the size of value.
-(void)getOneTimeWebpayCardsHandler:(id) value
{
YPGetOneTimeWebpayCardsResponse* result = (YPGetOneTimeWebpayCardsResponse*)value;
}

If it is just a simple object without any extra internal allocations, this should work:
#import <malloc/malloc.h>
NSLog(#"response size: %zd", malloc_size(response));

If I understand your question correctly:
You might check the HTTP headers of the response:
Content-Type: The value of this header specifies the MIME type, e.g. application/json and possibly additional parameters, like "charset", e.g. application/json; charset=utf-8 of the response data.
Content-Length: The value of this header specifies the length in bytes of the response data.
See also NSHTTPURLResponse and NSURLResponse in the original documentation.

Related

AFNetworking content type for HEAD request for ios8

I have a HEAD request to certain image with If-modified-since HTTP header, in order to check if image is actually modified. If modified, then i just send GET request for this image.
It used to work fine for iOS 7, And it works now for iOS 7. But for iOS 8 i got
Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: image/png"
So the same code works for ios7 and for ios8- don't. Any ideas?
First, you don't need to make a HEAD request. An appropriate NSURLRequestCachePolicy can accomplish the same thing.
Second, the error is caused by an unacceptable content type being sent by the response for the response serializer. For image/png, use AFImageResponseSerializer, or set the appropriate acceptableContentTypes property for the response serializer of your choice.
Thanks Matt for showing the way. I removed HEAD request. Now i use AFHTTPRequestOperation with AFImageResponseSerializer. Also i set 'If-Modified-Since' header in NSMutableURLRequest with setValue:forHTTPHeaderField method. This date is stored in userdefaults, where key is URL, and value is the date where this URL was modified.
I'm sure there should be much better way for this, like using NSURLCache, but i couldn't do it.

NSURLConnection retrieving JSON

I am using PromiseKit and I want to retrieve a JSON file.
[NSURLConnection GET:#"http://127.0.0.1/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Everything is fine on localhost but when I try it from another source (same file) it gives me an error:
[NSURLConnection GET:#"https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json"].then(^(NSDictionary *json) {
NSArray *questions = json[#"questions"];
Error
[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0xb07c880
JSON file:
https://dl.dropboxusercontent.com/u/11377305/resources/pack01.json
Why is it working on localhost?
I would appreciate any suggestions or even any thoughts on what questions I should be asking.
The error indicates that you're being passed an NSData rather than an NSDictionary from the remote URL.
The PromiseKit documentation states:
PromiseKit reads the response headers and decodes the result you actually wanted (in a background thread):
Therefore it's a safe bet that your remote server (which is DropBox in this case) isn't indicating that the returned data is formatted as JSON. So PromiseKit isn't parsing it.
EDIT: confirmed. DropBox is returning:
Content-Type text/plain; charset=utf-8
So PromiseKit has no way of knowing that the included data is meant to be JSON. You need a server that will return an application/json Content-Type. Or else you can force the JSON parse yourself, but then you're missing out on a large part of the PromiseKit benefit as you end up writing the same boilerplate code as the rest of us.

why is RestKit changing my response content-type?

In short: I try to fetch data form the server with the content-type of the http request header set as #"text/html.. but for some reason RestKit changes that to application/JSON
Explanation:
If I were to make this request using just AFNetworking.. things work like a charm.. this is what my AFNetworking code looks like:
AFHTTPClient *client = [AFHTTPClient alloc] initWithBaseURL:
[NSURL URLWithString:kApiBaseUrl]];
singleton.parameterEncoding = AFJSONParameterEncoding;
[singleton setDefaultHeader:#"Accept" value:#"text/html"];
[client getPath:getPath parameters:nil success:successCallback failure:failureCallback];
If I use that exact same client and attach it to
MyClient *client = [MyClient getSingleton]; //MyClient is instantiated as above
self.objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
self.objectManager.managedObjectStore = self.managedObjectStore;
// this should have already been done by my client, but putting
// it here just to be sure
[self.objectManager setAcceptHeaderWithMIMEType:#"text/html"];
[[RKObjectManager sharedManager] getObjectsAtPath:kGradesPath
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
// handle success
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
// handle failure
}];
the error i get is:
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=0x8f7acd0
digging into the subject.. i put a break point in managedObjectRequestOperationWithRequest, then I checked the acceptableContentTypes of HTTPRequestOperation created, and it's nil! So i'm assuming that RestKit is just putting its own default acceptable content types.. i just don't know where and how to prevent it. ideas?
p.s. I don't have control over the server, so I can't change it's content-type header to application/JSON
Update:
It turns out that in RKObjectRequestOperation.m it gets the mime-type from [RKMIMETypeSerialization registeredMIMETypes];(line 354).. and so in RKMIMETypeSerialization.hthere is the method:
/**
Registers the given serialization class to handle content for the given MIME Type identifier.
MIME Types may be given as either a string or as a regular expression that matches the MIME Types for which the given serialization should handle. Serializations are searched in the reverse order of their registration. If a registration is made for an already registered MIME Type, the new registration will take precedence.
#param serializationClass The class conforming to the RKSerialization protocol to be registered as handling the given MIME Type.
#param MIMETypeStringOrRegularExpression A string or regular expression specifying the MIME Type(s) that given serialization implementation is to be registered as handling.
*/
+ (void)registerClass:(Class<RKSerialization>)serializationClass forMIMEType:(id)MIMETypeStringOrRegularExpression;
how do I use this to register a text/html content-type?
RestKit generally expects a single MIMEType (JSON) for its response data. However, you can tell it to handle other types like text/plain and text/html using the method you found and in my experience it's been pretty handy. Adding this to my RestKit config (which I do in my app delegate) allows me to accept both application/json and text/html as response data content-types.
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:#"text/html"];
In my case, this is also helpful because Jersey - the web services framework the backend team at my company uses - defaults the content-type of empty payloads to text/plain, which triggers failure blocks unless I've specifically registered for that MIMEType.
Hope this helps.
I use change const value to type that recive from server api like this
NSString * const RKMIMETypeJSON = #"text/html";
if recived text structure same as JSON this approach works perfect

How to handle multiple response MIMETypes with Restkit 0.20

I have an iOS app using Restkit. Most of the response bodies from the server are in XML format. However, there is a few API's that will only send a response like "Success" in text/plain format. When calling these API's I get a 200 response but restkit will throw a mapping error because it is expecting Content-Type = application/xml as is seen in the error below.
NSLocalizedDescription=Loaded an unprocessable response (200) with content type 'application/xml'} response.body=success
I am using the RKXMLReaderSerialization class to interpret the XML received from the server and this is how I register it.
[RKMIMETypeSerialization registerClass:[RKXMLReaderSerialization class] forMIMEType:#"application/xml"];
It appears from the documentation you can register multiple MIMETypes but I haven't been able to figure out how. If that is possible can someone point it out to me. If not is there a way to handle this?
UPDATE/SOLUTION
After further research and help from Wain I discovered the error above was actually stating that the response-header for content-type had a value of application/xml. This keyed restkit to try and map the response.body as an application/xml formatted body. With a response.body containing only the word "success" the response was unprocessable. I ended up pointing this out to my server guy and he corrected the response to be formatted in the MIMEType declared by the Accept header sent with the request.
You can call setAcceptHeaderWithMIMEType: on your RKObjectManager to tell it what mime types are acceptable in the response. You may need to define and register your own serialisation class too so that RestKit can execute the whole mapping workflow without errors.

Why does my NSURLConnection report an incorrect expectedContentLength

I have an NSURLConnection and in didReceiveResponse I'm checking [response expectedContentLength] and getting really large values like 18446744073709551615. There's no way this is correct. The download is about 3k bytes, and when I expect the same request in fiddler, I see a (correct) content length header in the response of about 3k bytes.
To avoid this problem, set header field "Accept-Encoding" to #"gzip;q=0". that tells the server that you do not accept gzip, and will if possible send uncompressed.
The answer, related to the comments, is that it's because the result is gzip encoded. Oddly, the value for the expectedContentLength seems to be junk, and cannot be trusted. If the result is gzip encoded, then NSURLConnection cannot properly determine the size of the unencoded result.

Resources