I am trying to connect to Magento REST with OAuth authentication on iOS. I already have: consumer_key, consumer_secret, token, token_secret and the url. With Chrome Rest Client I can connect without problems but in iOS using OAUthiOS library I can not. This library has some example to authenticate to Facebook and Twitter but what I need is to connect to my rest services.
What I have tried so far:
NSString *key = #"Authorization";
NSString *value = #"OAuth realm="http://www.myweb.com/",oauth_consumer_key="xxxx",oauth_token="yyyyy",oauth_nonce="zzzz",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1111111",oauth_version="1.0",oauth_signature="wwwwww"";
request = [[OAuthIORequest alloc] init];
[request addHeaderWithKey:key andValue:value];
[request get:PRODUCTS_SERVICE success:^(NSDictionary *output, NSString *body, NSHTTPURLResponse *httpResponse)
{
NSLog(#"body %#", body);
}];
But nothing happend. What should I do? Is there any framework better?
Thanks!
I have resolved this issue using another framework: AFNetworking and AFOAuth1Client instead of OAUthiOS.
AFOAuth1Client * client = [[AFOAuth1Client alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL] key:CONSUMER_KEY secret:CONSUMER_SECRET];
[client setOauthAccessMethod:#"GET"];
[client setSignatureMethod:AFHMACSHA1SignatureMethod];
[client setDefaultHeader:#"Accept" value:#"application/json"];
[client setAccessToken:[[AFOAuth1Token alloc] initWithKey:TOKEN secret:TOKEN_SECRET session:nil expiration:nil renewable:FALSE]];
NSMutableURLRequest * request =[client requestWithMethod:#"GET" path:PRODUCTS_SERVICE parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[client registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
Related
My code is below:
NSString *urlString = [[NSString stringWithFormat:#"/players?skip=%ld",(long)skipSize] DVURL];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//[request set]
[request setValuesForKeysWithDictionary:[filter filteringDictionary]];
AFHTTPRequestOperation *operation =
[[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject %#", responseObject);
totalPages = ([[responseObject
objectForKey:#"count"] intValue] / 20);
NSLog(#"%#",[responseObject objectForKey:#"players"]);
for (NSDictionary *playerDict in [responseObject objectForKey:#"players"]) {
DVPlayer *player = [[DVPlayer alloc] initWithDictionary:playerDict];
if (![self.playerArray.players containsObject:player]) {
[self.playerArray.players addObject:player];
}
}
[playerCollectionView reloadData];
} failure:
^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
[[[UIAlertView alloc]
initWithTitle:#"Error fetching players!"
message:#"Please try again later"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}];
[operation start];
When I use AFHTTPRequestOperationManager, I used NSDictionary as parameter for GET method.
So I thought [request setValuesForKeysWithDictionary:[filter filteringDictionary]]; would be corresponding.
But I got an error :
setValue:forUndefinedKey:]: this class is
not key value coding-compliant for name(ex)
I architected the parameter is NSDictionary for convenience...
Can't I set parameter as NSDictionary when using AFHTTPRequestOperation , not AFHTTPRequestOperationManager?
Help me please
AFHTTPRequestOperation takes an NSURLRequest as an init parameter. As such, you need to handle the serialization yourself, append it to your url, and then encode the url:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[yourUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
Just one more reason why AFHTTPRequestOperationManager is easier ;)
I'm having a problem with AFNetworking.
Currently I can send a POST request in JSON format [AFJSONParameterEncoding] using NSDictionary to a server and it correctly replies, the problem is that the server replies with a JSON formatted response too, response I'm able to convert to NSString using:
[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
// responseObject is the server response
The problem is I'm not able to transform the response in any other format, other than NSString like in the code posted before. How can that be possible? I would like to convert the response to JSON format so I can read a precise value, the value associated with the key "isInformative"
Here's my code so far:
NSDictionary *requestBody = [NSDictionary dictionaryWithObjectsAndKeys:
#"value1", #"key1",
#"value2", #"key2",
nil];
NSDictionary *requestHead = #{
#"RequestHead": requestBody
};
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://XXX.XXX.XXX.XXX:XXXX"]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"/public-mobile-sdk/"
parameters:requestHead];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *requestOperation, id responseObject) {
// Here I can convert the responseObject to NSSTring correctly
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *requestOperation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[requestOperation start];
Note - I can't update the AFNetworking version bundled in the Xcode project since it's not my own, so sadly I must stick and use version 1.X
This solved my problem:
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:jailbreakRequest];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *requestOperation, id responseObject) {
//Place this line of code below to create a NSDictionary from the async server response
NSDictionary *jsonList = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
} failure:^(AFHTTPRequestOperation *requestOperation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[requestOperation start];
Thanks anyway :-)
I have a question about AFNetworking 2.0
I have to make a GET request like this:
http://myhost.come/entity?language=en&query=$UserId=14 and $EntityCreationDate>'2014-09-01'
How to generate the Dictionary parameters for this request?
In particular I not understand how can I build this: and $EntityCreationDate>'2014-09-01'
Here I found a good tutorial.
Which states a simple GET request can be sent like this:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://samwize.com/"]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET"
path:#"http://samwize.com/api/pigs/"
parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
I am using AFNetworking and I've read that synchronous responses are discouraged. yet I need to check whether a user already exist in the online database before the person can go to the next stage of the app. Yes, a typical registration process.
My code as it stands it returns NO because is asynchronous. I need to find a way to check for the success call and return YES or NO depending on this callback.
Could anyone point me in the right direction of how to write an app that waits for the success call so that I know that the user has not been set?
-(BOOL)doesTheUserExistAlreadyOnServer:(NSString *)parsedEmail
{
BOOL *methodResponse = NO;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://www.myurl.co.uk/"]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"http://www.myurl.co.uk/igym.php"
parameters:#{#"myvar2":#"piggy"}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
// NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
if ([[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] isEqualToString:#"piggy"]) {
__block methodResponse = YES;
NSLog(#"%#",[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
return (BOOL)methodResponse;
}
EDIT:
I solved the problem using the following logic.
The user clicks on the registration button. The main method does all the preliminary non-web checks, then calls the [self doesTheUserExistAlreadyOnServer:_email.text];
that method code is now
-(void)doesTheUserExistAlreadyOnServer:(NSString *)parsedEmail
{
if(![_spinner isAnimating])
{
[_spinner startAnimating];
}
__block RegistrationViewController* me = self;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://www.myurl.co.uk/"]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"http://www.myurl.co.uk/igym.php"
parameters:#{#"myvar2":#"piggy"}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
if ([[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] isEqualToString:#"piggy"]) {
NSLog(#"%#",[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
[me registrationPartTwo:YES];
} else
{
[me registrationPartTwo:NO];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];
}
Then once that block/callback is successful it calls
-(void)registrationPartTwo:(BOOL)doesItExistOnServer
{
[_spinner stopAnimating];
NSString *emailAlreadyInUseMessage = [NSString stringWithFormat:#"This email is already in use"];
if (doesItExistOnServer)
{
self.screenMsg.text = emailAlreadyInUseMessage;
//here more code to send the user the the next step
}
}
basically i solved this using a 2method registration process dependant upon callback, dont know if thats the best or most efficient way. but thats the way i could solve it on my own.
Use a delegate callback to notify when the operation completes. If needed, before starting the operation, put up an UIActivityIndicatorView (the spinner) to prevent the user from interacting with the app.
i want to implement afnetworking with put request, but it always shows error when i run it.
it works fine with post method, but when i change it to PUT it shows error.
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:urls];
[httpClient defaultValueForHeader:#"Accept"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
#"345", #"page_id",
#"john",#"username",
nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"PUT"
path:#""
parameters:params];
//Add your request object to an AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation,
id responseObject) {
NSString *response = [operation responseString];
NSLog(#"response: [%#]",response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", [operation error]);
}];
//call start on your request operation
[operation start];
the error says:
Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 404" UserInfo=0x75a9d40 {NSLocalizedRecoverySuggestion={"status":false,"error":"Unknown method."}