NSLog of AFNetworking POST data - ios

I am making a POST request using AFNetwork. My AFNetwork folder contains AFNetworkActivityLogger. Does anyone know where I need to hack in order to NSLog the content that is being sent to the server? I need to make sure that what I think I am sending is indeed what is being sent. I tried a few things to no avail, including this:
NSString *body = nil;
if ([request HTTPBody])
{
body = [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding];
NSLog(#"REQUEST BODY: %#",body);
}

Related

Does an iOS http 'get' have a URL length limit

I'm trying to do a simple get in iOS (Objective C) using a simulator and not a real device.
NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:theGetURL]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
[newRequest setHTTPMethod: #"GET"];
NSError *requestError2;
NSURLResponse *urlResponse2;
NSData *response2 = [NSURLConnection sendSynchronousRequest:newRequest returningResponse:&urlResponse2 error:&requestError2];
NSString* secondResponse = [[NSString alloc] initWithData:response2 encoding:NSUTF8StringEncoding];
NSLog(#"error = %#",requestError.localizedDescription);
NSLog(#"response=%#",secondResponse);
NSLog(#"url response = %#",urlResponse);
This code works perfectly when I'm passing a simple url. When I try the code with a longer (around 4000 characters) url, the code doesn't work (no error is printed).
I am aware that a post is better for this kind of thing, but my question is, is this expected from a get request?
Also, my url works perfectly in my mac and iOS browsers.
As you suspect, I think you need to consider moving to use POST rather then GET. The server side limit is 8K, however it seems this can be much less for the client side.
The following discussion sums everything up well. It also seems to imply the limit for Safari is 2K, which probably means it is the same or less for iOS, which would explain your problem with 4000 characters.
maximum length of HTTP GET request?
I think your URL query parameter might have any character that is not encoded. Try to ensure it.
For encoding you may try this code
- (NSString *)encodeQueryParameter:(NSString *)str
{
CFStringRef ref = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)str,
NULL,
CFSTR(":/=,!$&'()*+;[]##?"),
kCFStringEncodingUTF8);
NSString *result = (__bridge_transfer NSString *)ref;
return result;
}

HTTP post w/ JSON to rails server from iOS

I have succeeded in making a post using a HTTP Client by setting the content type as application/json and this json code:
{
"order": {
"name": "Tia Carter",
"location": "Corams",
"phone_number": "707",
"food": "Bobcat Burger"
}
}
The code works perfect and the order is registered in the database. I am trying to work this into my iOS app but keep getting syntax errors regarding the colons in the json. This is the objective-c code:
NSURL *nsURL = [[NSURL alloc] initWithString:#"http://0.0.0.0:3000/orders.json"];
NSMutableURLRequest *nsMutableURLRequest = [[NSMutableURLRequest alloc] initWithURL:nsURL];
// Set the request's content type to application/x-www-form-urlencoded
[nsMutableURLRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Set HTTP method to POST
[nsMutableURLRequest setHTTPMethod:#"POST"];
// Set up the parameters to send.
NSString *paramDataString = [NSString stringWithFormat:#
"{ "order": {"%#:" ="%#","%#:"="%#","%#:"="%#","%#:"="%#"}}", #"name", _name.text, #"location", _location.text, #"phone_number", _phoneNumber.text, #"food", _order.text];
// Encode the parameters to default for NSMutableURLRequest.
NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
// Set the NSMutableURLRequest body data.
[nsMutableURLRequest setHTTPBody: paramData];
// Create NSURLConnection and start the request.
NSURLConnection *nsUrlConnection=[[NSURLConnection alloc]initWithRequest:nsMutableURLRequest delegate:self];
I'd appreciate any ideas or guidance. Thanks.
I believe you have two problems:
You didn't escape quotas (put \ before all of them)
You don't need to put text "name", "location" and etc in parameters (it's not a problem per se, just a style thing)
Also, I would recommend to work with NSDictionary and convert it to JSON when you need to (it will save you a lot of nerves for unescaped quotas, missing bracket and so on).
Look this question how to convert NSDictionary to JSON:
Generate JSON string from NSDictionary in iOS

How do I set up and implement HTTP method for authorization?

I'm trying to get into a webAPI my classmate created with my iphone APP I've created. Right now, it connects, but my app just crashes because it tells me that I need authorization. So if for example, the username is abc and password abc123, How would I implement the HTTP method specifically to get passed authorization??
NSString *geturl = #"http://192.168.1.96:50364/api/transaction" ;
setValue:(NSString*)" " forHTTPHeaderField:(NSString*)username;
getjson *mds=[[getjson alloc] init];
SEL selector = #selector(addData:);
[mds setDirectionsQuery:geturl
withSelector:selector
withDelegate:self];
Edit: if the above problem is too confusing, what is the basic syntax/code for setting up the value and the key for username and password? I am sure
setValue:(NSString*)"abc " forHTTPHeaderField:(NSString*)username;
setValue:(NSString*)"abc123 " forHTTPHeaderField:(NSString*)password;
is not correct. compiler is not letting me run the program.
Your strings are missing #
Try setValue:(NSString*)#"abc " forHTTPHeaderField:(NSString*)username; although if the code you pasted is complete, it doesn't say what your setting values to.
I personally use NSMutableRequest and create the request and authorisation like this. Note that the auth gets Base64 encoded:
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:_urlString]];
NSString *basicAuthCredentials = [NSString stringWithFormat:#"%#:%#", username, password;
NSString *authValue = [NSString stringWithFormat:#"Basic %#", AFBase64EncodedStringFromString(basicAuthCredentials)];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization"];

iOS: Get file's metadata

I have an mp3 file on a server. I want to get this file's information like what's the size of this file, what's the artists name, what's the album name, when was the file created, when was it modified, etc. I want all this information.
Is it possible to get this information without actually downloading the whole file? Using NSURLConnection or otherwise?
EDIT:
The following code doesn't give me the required information, i.e. file created by, artist name, etc
NSError *rerror = nil;
NSURLResponse *response = nil;
NSURL *url = [NSURL URLWithString:#"http://link.to.mp3"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"HEAD"];
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&rerror];
NSString *resultString = [[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"URL: %#", url);
NSLog(#"Request: %#", request);
NSLog(#"Result (NSData): %#", result);
NSLog(#"Result (NSString): %#", resultString);
NSLog(#"Response: %#", response);
NSLog(#"Error: %#", rerror);
if ([response isMemberOfClass:[NSHTTPURLResponse class]]) {
NSLog(#"AllHeaderFields: %#", [((NSHTTPURLResponse *)response) allHeaderFields]);
}
The "AllHeaderFields" is:
AllHeaderFields: {
"Cache-Control" = "max-age=0";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Type" = "text/plain; charset=ascii";
Date = "Fri, 17 Feb 2012 12:44:59 GMT";
Etag = 19202n;
Pragma = public;
Server = dbws;
"x-robots-tag" = "noindex,nofollow";
}
It is quite possible to get the ID3 information embedded in an MP3 file (artist name, track title) without downloading the whole file or using low-level APIs. The functionality is part of the AVFoundation framework.
The class to look at is AVAsset and specifically it's network friendly subclass AVURLAsset. AVAsset has an NSArray property named commonMetadata. This commonMetadata property will contain instances of AVMetadataItem, assuming of course that the reference URL contains metadata. You will usually use the AVMetadataItem's commonKey property to reference the item. I find this method of iterating through an array checking commonKeys irritating so I create an NSDictionary using the commonKey property as the key and the value property as the object. Like so:
-(NSDictionary *)dictionaryOfMetadataFromAsset:(AVAsset *)asset{
NSMutableDictionary *metaData = [[NSMutableDictionary alloc] init];
for (AVMetadataItem *item in asset.commonMetadata) {
if (item.value && item.commonKey){
[metaData setObject:item.value forKey:item.commonKey];
}
}
return [metaData copy];
}
With the addition of this simple method the AVAsset's metadata becomes quite easy to use. Here is an example of getting an MP3's metadata through a URL:
NSURL *mp3URL = [NSURL URLWithString:#"http://'AddressOfMP3File'"];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:mp3URL options:nil];
NSDictionary *metaDict = [self dictionaryOfMetadataFromAsset:asset];
NSLog(#"Available Metadata :%#",metaDict.allKeys);
NSLog(#"title:%#",[metaDict objectForKey:#"title"]);
I have found that this code seems to load just the first few seconds of your MP3 file. Also note that this code is synchronous; So use with caution. But AVURLAsset does have some async functionality described in the docs.
Once you have the AVAsset you can create a AVPlayerItem with it and feed that to an AVPlayer and play it, or not.
Yes and no. Things like the file size and modification date often come as part of the HEAD response. But not always: with a lot of dynamic URLs, you won't get all of the information.
As for the artist and album name, they're part of the MP3's ID3, which is contained inside the file, and so you won't be able to get them with a HEAD request. Since the ID3 tag is typically at the beginning of a file, you could try to grab just that part and then read the ID3 tag. But you won't be able to do it with NSURLConnection since it doesn't support just fetching part of a file, so you'll need to find a more low-level way of getting data by HTTP.
Yep, you're right on target with NSURLConnection.
I think you want to send a HEAD request for the resource you want information about and then check the information you receive in connection:didReceiveResponse: and connection:didReceiveData:
Edit
Admittedly I didn't read your question in its entirety. It won't be possible to get ID3 information, but you should be able to get size of file and maybe creation date etc.
This answer does give some good information about how to get the ID3 information. You'd need to set up a php page to examine the mp3 file server-side and return just that information you require instead of the entire mp3.

NSURLConnection Data broken in asynchronous connection

I have a NSURLConnection that receives data output from a url pointing to a php script on my server.
Most of the time everything works fine and the data is retrieved in its complete form.
However, sometimes I receive NULL or broken (i.e. the bottom half) of data at:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
When this happens, if I reload the connection it will always return the same null or broken block
of data for the request.
EDIT*:
I've realized that when I receive what I thought was nil data, I actually received data
but the NSString created from this data is nil. I still don't understand why though. My php encoding output is always UTF-8 so I don't think it is an issue of encoding and besides it works most of the time with this.
I have checked the php script with that same request to verify that it is not a problem on the server side or with the php script and confirmed that it is NOT.
My code is Below:
-(void)setUpConnectionAndMakeRequest {
NSString *URLpath = #"http://www.example.com/myphp.php";
NSURL *myURL = [[NSURL alloc] initWithString:URLpath];
NSMutableURLRequest *myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
[myURL release];
[myURLRequest setHTTPMethod:#"POST"];
//I added this because I thought it may be a problem relating to cache but it isn't
NSURLCache *cache = [NSURLCache sharedURLCache];
[cache removeAllCachedResponses];
NSString *httpBodystr = [NSString stringWithString:#"command=runscript"];
[myURLRequest setHTTPBody:[httpBodystr dataUsingEncoding:NSUTF8StringEncoding]];
[mailData setData:nil]; //mailData is a NSMutableData object which accumulates the data retrieved by the request
[NSURLConnection connectionWithRequest:myURLRequest delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *untrimmedDataSTR = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //Created so I can see the data (always text) in NSLog
NSLog(#"Live Data: %#", untrimmedDataSTR); //This is where I see that the data is broken or null when it shouldn't be
[mailData appendData:data]; //Append accumulated data to NSMutableData object used later in my app.
[untrimmedDataSTR release];
}
Any help would be much appreciated.
According to the NSString reference, -initWithData:encoding: returns nil if "the initialization fails for some reason (for example if data does not represent valid data for encoding)."
That almost certainly means that the response from the server is not, in fact, UTF-8 encoded data.
The way to check would be to NSLog the data before trying to convert to an NSString:
NSLog(#"Raw Data: %#", data);
(The -description method on NSData will return a hexadecimal representation of the contents; that's what will get logged).

Resources