I'm seeing in AFHTTPClient documentation these pretty tasks for Making HTTP Requests:
- getPath:parameters:success:failure:
- postPath:parameters:success:failure:
- putPath:parameters:success:failure:
- deletePath:parameters:success:failure:
- patchPath:parameters:success:failure:
Now if I need update or create something on my server,
let's say I want to differentiate the update/create by the method:
create -> PUT
update -> POST
Would there be a way to specify the method as a parameter somewhere, like:
- requestPath:method:parameters:success:failure:
Obviously I can create my own dispatcher, but the question is more about why this seems to be done intentionnaly as it is (hoping I'm clear).
postPath:parameters:success:failure: is a convenience method for the following:
NSMutableURLRequest *request = [client requestWithMethod:#"POST" path:#"/path" parameters:#{...}];
AFHTTPRequestOperation *operation = [client HTTPRequestOperationWithRequest:request success:^{...} failure:^{...}];
[client enqueueHTTPRequestOperation:operation];
You can customize any of the objects along the way using the long-form version.
Related
I am trying to produce a request using afnetworking in objective c, however, it seems like the hardware that I am trying to connect to only applies requests when the parameters of the request are in a specific order. So I am wondering if there is a way to make the request so that the parameters are in a specific order. (As just doing it normally seems to jumble the sequence of the params up)
Here's my code:
NSDictionary *params = #{
#"param1" : #"bla",
#"param2" : #"bla2",
#"param3" : #"bla3"
};
[requestManager GET:#"somewhere" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(#"Success!");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(#"Fail: %#", error);
}];
It actually goes to success every time, its just that the request I had applied would be practically ignored.
The actual request body becomes something like "param3=bla3¶m1=bla1¶m2=bla2 etc which would be ignored as it seems.
You can't do that using the request manager in the way you currently are.
Instead, you would need to create the parameter list yourself, and then create a request from that. Then you could use AFN to handle the request transmission and response.
Note that the server shouldn't require a specific order and that this should be changed if possible. Note also that the dictionary of parameters has no order (even though you add the keys in a set order).
Keeping the order of the parameters have a great impact on server performance. This sounds silly at first, but just think about GET requests which contain the query string as part of the URL. Web servers can cache the response for the given URL. If you mess with the order of the parameters, the cache won't be as effective as it could be.
The case is even worse if you call an API from different platforms (iOS, Android, Web) and they all reorder the params, which means that the same content will be found on 3 different cache keys.
Keeping the order is a performance issue at the first place.
I have managed to GET objects and to POST a new object to the server, but the POST generates an error on the iPhone.
Here is my setup:
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMappingFoo pathPattern:#"/foos" keyPath:#"foos" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; // Works well for GET
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[entityMappingFoo inverseMapping] objectClass:[Foo class] rootKeyPath:#"foo"]; // Client --> Server works
The problem is (I think) that:
when I GET, the back-end expects the JSON to have a plural key: {"foos":[...]} (which makes sense since there might be several objects)
when I POST one object, RestKit expects the answer from the back-end to be singular: {"foo":...}. Yet, since it uses the same responseDescriptor as for GET, it gets a plural and it is lost.
If I replace keyPath:#"foos" by keyPath:#"foo" in responseDescriptor my POST works... but not my GET.
How do I reconcile the two?
You're right. Basically you just need to create multiple response descriptors to cover the different cases. You can use the same mapping in each, but RestKit needs to know what to look for when processing a response and your 2 cases are different.
I"m trying to post data to a server from objective C and I am trying to get a JSON returned in it.
I am looking at the Snaphax API for PHP and Snaphaxpy API and trying to rewrite it from PHP into Objective C.
The links for the code are:
https://github.com/tlack/snaphax
https://github.com/jasonanovak/snaphaxpy/blob/master/snaphaxpy.py
I'm also especially looking at: http://adamcaudill.com/2012/06/16/snapchat-api-and-security/
but apparently this is outdated
My code is:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://feelinsonice.appspot.com/ph/login"]];
[request setHTTPMethod:#"POST"];
[request addValue:#"******testusername******" forHTTPHeaderField:#"username"];
[request addValue:#"*********" forHTTPHeaderField:#"password"];
[request addValue:#"M02cnQ51Ji97vwT4" forHTTPHeaderField:#"blob_enc_key"];
[request addValue:#"false" forHTTPHeaderField:#"debug"];
[request addValue:#"iEk21fuwZApXlz93750dmW22pw389dPwOk" forHTTPHeaderField:#"secret"];
[request addValue:#"m198sOkJEn37DjqZ32lpRu76xmw288xSQ9" forHTTPHeaderField:#"static_token"];
[request addValue:#"Snaphax 4.0.1 (iPad; iPhone OS 6.0; en_US)" forHTTPHeaderField:#"user_agent"];
[request addValue:#"930cf95a6731dc986ef3bceef6abbaf420e94d8d197dca87b9b47314d8c51b3b" forHTTPHeaderField:#"req_token"];
[request addValue:#"1355776346532" forHTTPHeaderField:#"timestamp"];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"%#", dataString);
I haven't included a real username/password. How come, however, does this not work as I have literally copied everything I have found and implemented in a new language...
Am I not POSTing the data correctly? I tried using ASIHTTPRequest but I couldn't get that working either...
Any suggestions or ideas based on experience??
Check my answer here: how can I use NSURLConnection Asynchronously?
You can send a POST request by using
HTTPCachedController *ctrl = [[[HTTPCachedController alloc] initWithRequestType:1 andDelegate:self] autorelease];
[ctrl postRequestToURL:#"https://feelinsonice.appspot.com/ph/login" withData:#"username=user1&password=pass& ... "];
Source code of the HTTPCachedController can be found here: HTTPCachedController
If you are looking for updated endpoints and whatnot, I wrote a quick Python script that you should be able to read through for some endpoints and the parameters they require. Some of the endpoints are as follow:
Base URL https://feelinsonice-hrd.appspot.com/
Login https://feelinsonice.appspot.com/ph/login
Get Snap by ID https://feelinsonice.appspot.com/ph/blob?id={}
Shameless Plug: I'm hosting a wrapper for the Snapchat API right now so you don't have to implement encryption into your project and you can safe time and your project can be more efficient. Check it out here!
You will also notice a lot of strange abbreviations in the JSON (like Adam said, Snapchat's API wasn't really built for human consumption), so I've gone ahead and mapped that out for you:
ID: id
Snap ID: c_id
Media Type: m = 0 (pic), 1 (video)
Sent Timestamp: sts
Opened Timestamp: ts
Sender: sn
Recipient: rp
Status: st = 1 (sent to you), 2 (sent by you)
Time: t
Screenshot Count: c
Note: I will be updating that repo with some new code within the next month or so. Also, the most up-to-date endpoints often vary between /ph/ and /bq/ for different requests for some reason, so don't accidentally use one when you meant to use the other.
I'm working on a project that requires downloading a list of users from a server —JSON data created from a PHP script that reads a MySQL database— and I would like to inform the user of the progress of the request but onDownloadProgressChanged: never gets called when sending a GET request through operationWithPath:params:httpMethod:ssl: and I don't know if that is an intended behavior or not.
MKNetworkOperation *op = [self operationWithPath:kSPGetUserListPath params:nil httpMethod:#"GET" ssl:YES];
Should onDownloadProgressChanged: be called when I send a GET request with operationWithPath:params:httpMethod:ssl: or is it only called when downloading a file using addDownloadStream:?
Whenever I send a POST request with a file attached through addData: method of MKNetworkOperation the onUploadProgressChanged: method get called accordingly.
Thank you!!!
I had the same problem because missed something like the following MKNetworkEngine initializing in the main class:
self.sampleDownloader = [[ExampleDownloader alloc] initWithHostName:nil customHeaderFields:nil];
I was wondering on how to download a file using NSUrl where the filename is not available or is not part of the request URL. I have been looking at ASIHTTPRequest (http://allseeing-i.com/ASIHTTPRequest/) library. It has
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/ben/Desktop/my_file.txt"];
But the point is you need to know the file name here. For example if you put the URL (not real URL) http://some-website/foo.pdf
It downloads a file foo.pdf and I want to save it like that. Any ideas thanks.
In the NSURLConnection delegate callback - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response you can retrieve the suggestedFileName from the NSURLResponse. If you get unknown for a name then you need to come up with another name for your file. At this point you can specify your download path before you start saving data.
suggestedFilename
Returns a suggested
filename for the response data.
(NSString *)suggestedFilename
Return Value
A suggested filename for the
response data.
Discussion
The method tries to create
a filename using the following, in
order:
A filename specified using the content
disposition header.
The last path
component of the URL.
The host of the
URL.
If the host of URL can't be
converted to a valid filename, the
filename “unknown” is used.
In most cases, this method appends the
proper file extension based on the
MIME type. This method will always
return a valid filename regardless of
whether or not the resource is saved
to disk.
Availability
Available in iOS 2.0 and
later. Declared In NSURLResponse.h