I am using AFNetworking 3, Xcode 7.2 for iOS 9.
AFURLSessionManager *ses = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
ses.responseSerializer = [AFJSONResponseSerializer serializer];
//Request
[[AFJSONRequestSerializer serializer] setValue:#"application/json" forHTTPHeaderField:#"Accept"];
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:#"GET" URLString:endPoint parameters:parameters error:nil];
NSURLSessionDataTask *dataTask = [ses dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"%# %#", response, responseObject);
}
}];
[dataTask resume];
but I am getting error response as:
Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/plain"
The request content type is still set to "text/plain"
I am not sure what I am missing .
I used http response serializer itself and it worked fine.
AFURLSessionManager *ses = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
ses.responseSerializer = [AFHTTPResponseSerializer serializer];
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:responseObject options:kNilOptions error:&error1];
Related
I'm trying to implement this example link of a DocuSign service that download an envelope document, but when the execution arrive to this line in step 3:
NSMutableString *jsonResponse = [[NSMutableString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
jsonResponse is nil and when I open the document, it has a lot of strange characters and I can't read it.
My code for downloadind is the following:
NSString *url = #"https://demo.docusign.net/restapi/v2/accounts/373577/envelopes/08016140-e4dc-4697-8146-f8ce801abf92/documents/1";
NSMutableURLRequest *documentsRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[documentsRequest setHTTPMethod:#"GET"];
[documentsRequest setURL:[NSURL URLWithString:url]];
[documentsRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[documentsRequest setValue:[self jsonStringFromObject:authenticationHeader] forHTTPHeaderField:#"X-DocuSign-Authentication"];
NSError *error1 = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:documentsRequest returningResponse:&responseCode error:&error1];
NSMutableString *jsonResponse = [[NSMutableString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
if([responseCode statusCode] != 200){
NSLog(#"Error sending %# request to %#\nHTTP status code = %i", [documentsRequest HTTPMethod], url, [responseCode statusCode]);
NSLog( #"Response = %#", jsonResponse );
return;
}
// download the document to the same directory as this app
NSString *appDirectory = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
NSMutableString *filePath = [NSMutableString stringWithFormat:#"%#/%#", appDirectory, #"eee"];
[oResponseData writeToFile:filePath atomically:YES];
NSLog(#"Envelope document - %# - has been downloaded to %#\n", #"eee", filePath);
If no data is coming back from
NSMutableString *jsonResponse = [[NSMutableString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
then that means oResponseData is most likely nil which means the URL is not being constructed correctly for each envelope document. Are you doing step 2 in the sample that you linked to, where it first retrieves the envelopeDocuments information about the envelope, then it dynamically builds each unique document uri in preparation of downloading each one.
Instead of hardcoding your URL you should dynamically retrieve the envelopeDocuments data, then build each document uri dynamically then your response data will not be nil. Here's the full working sample:
- (void)getDocumentInfoAndDownloadDocuments
{
// Enter your info:
NSString *email = #"<#email#>";
NSString *password = #"<#password#>";
NSString *integratorKey = #"<#integratorKey#>";
// need to copy a valid envelopeId from your account
NSString *envelopeId = #"<#envelopeId#>";
///////////////////////////////////////////////////////////////////////////////////////
// STEP 1 - Login (retrieves accountId and baseUrl)
///////////////////////////////////////////////////////////////////////////////////////
NSString *loginURL = #"https://demo.docusign.net/restapi/v2/login_information";
NSMutableURLRequest *loginRequest = [[NSMutableURLRequest alloc] init];
[loginRequest setHTTPMethod:#"GET"];
[loginRequest setURL:[NSURL URLWithString:loginURL]];
// set JSON formatted X-DocuSign-Authentication header (XML also accepted)
NSDictionary *authenticationHeader = #{#"Username": email, #"Password" : password, #"IntegratorKey" : integratorKey};
// jsonStringFromObject() function defined further below...
[loginRequest setValue:[self jsonStringFromObject:authenticationHeader] forHTTPHeaderField:#"X-DocuSign-Authentication"];
// also set the Content-Type header (other accepted type is application/xml)
[loginRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection sendAsynchronousRequest:loginRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *loginResponse, NSData *loginData, NSError *loginError) {
if (loginError) { // succesful GET returns status 200
NSLog(#"Error sending request %#. Got Response %# Error is: %#", loginRequest, loginResponse, loginError);
return;
}
// we use NSJSONSerialization to parse the JSON formatted response
NSError *jsonError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:loginData options:kNilOptions error:&jsonError];
NSArray *loginArray = responseDictionary[#"loginAccounts"];
// parse the accountId and baseUrl from the response (other data included)
NSString *accountId = loginArray[0][#"accountId"];
NSString *baseUrl = loginArray[0][#"baseUrl"];
//--- display results
NSLog(#"\naccountId = %#\nbaseUrl = %#\n", accountId, baseUrl);
///////////////////////////////////////////////////////////////////////////////////////
// STEP 2 - Get Document Info for specified envelope
///////////////////////////////////////////////////////////////////////////////////////
// append /envelopes/{envelopeId}/documents URI to baseUrl and use as endpoint for next request
NSString *documentsURL = [NSMutableString stringWithFormat:#"%#/envelopes/%#/documents", baseUrl, envelopeId];
NSMutableURLRequest *documentsRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:documentsURL]];
[documentsRequest setHTTPMethod:#"GET"];
[documentsRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[documentsRequest setValue:[self jsonStringFromObject:authenticationHeader] forHTTPHeaderField:#"X-DocuSign-Authentication"];
[NSURLConnection sendAsynchronousRequest:documentsRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *documentsResponse, NSData *documentsData, NSError *documentsError) {
NSError *documentsJSONError = nil;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:documentsData options:kNilOptions error:&documentsJSONError];
if (documentsError){
NSLog(#"Error sending request: %#. Got response: %#", documentsRequest, documentsResponse);
NSLog( #"Response = %#", documentsResponse );
return;
}
NSLog( #"Documents info for envelope is:\n%#", jsonResponse);
NSError *jsonError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:documentsData options:kNilOptions error:&jsonError];
// grab documents info for the next step...
NSArray *documentsArray = responseDictionary[#"envelopeDocuments"];
///////////////////////////////////////////////////////////////////////////////////////
// STEP 3 - Download each envelope document
///////////////////////////////////////////////////////////////////////////////////////
NSMutableString *docUri;
NSMutableString *docName;
NSMutableString *docURL;
// loop through each document uri and download each doc (including the envelope's certificate)
for (int i = 0; i < [documentsArray count]; i++)
{
docUri = [documentsArray[i] objectForKey:#"uri"];
docName = [documentsArray[i] objectForKey:#"name"];
docURL = [NSMutableString stringWithFormat: #"%#/%#", baseUrl, docUri];
[documentsRequest setHTTPMethod:#"GET"];
[documentsRequest setURL:[NSURL URLWithString:docURL]];
[documentsRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[documentsRequest setValue:[self jsonStringFromObject:authenticationHeader] forHTTPHeaderField:#"X-DocuSign-Authentication"];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:documentsRequest returningResponse:&responseCode error:&error];
NSMutableString *jsonResponse = [[NSMutableString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
if([responseCode statusCode] != 200){
NSLog(#"Error sending %# request to %#\nHTTP status code = %i", [documentsRequest HTTPMethod], docURL, [responseCode statusCode]);
NSLog( #"Response = %#", jsonResponse );
return;
}
// download the document to the same directory as this app
NSString *appDirectory = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
NSMutableString *filePath = [NSMutableString stringWithFormat:#"%#/%#", appDirectory, docName];
[oResponseData writeToFile:filePath atomically:YES];
NSLog(#"Envelope document - %# - has been downloaded to %#\n", docName, filePath);
} // end for
}];
}];
}
- (NSString *)jsonStringFromObject:(id)object {
NSString *string = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:object options:0 error:nil] encoding:NSUTF8StringEncoding];
return string;
}
1.Is it necessary https://www.mysite.com/my_services/user/token
get that token and i set for login call but its get error 'csrf token issue'
before https://www.mysite.com/my_services/user/login
with post paramater username and password
i am question
whether i have to call user/token every time ..for getting token and set the x-csrf-token value in header for post requests.
(void)viewDidLoad
{
[super viewDidLoad];
NSString *notificationName = #"MTPostNotificationTut";
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(useNotificationWithString:)
name:notificationName
object:nil];
}
(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated {
NSString *urlString = #"https://www.mysite.com/my_services/user/token.json";
NSString *urlS = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlS]cachePolicy:NSURLCacheStorageAllowed timeoutInterval:10.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *string = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"stringFromData = %#",string);
id jsonResponseData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSLog(#"jsonResponseData = %#",jsonResponseData);
NSDictionary *jsonResponseDict;
if ([jsonResponseData isKindOfClass:[NSDictionary class]]) {
jsonResponseDict = jsonResponseData;
} else {
// Error-handling code
}
jsonResponseData = [jsonResponseDict objectForKey:#"d"];
if (jsonResponseData == nil) {
id jsonExceptioTypeData = [jsonResponseDict objectForKey:#"ExceptionType"];
if (jsonExceptioTypeData != nil) {
NSLog(#"%s ERROR : Server returned an exception", __func__);
NSLog(#"%s ERROR : Server error details = %#", __func__, jsonResponseDict);
}
}
token = [jsonResponseDict objectForKey:#"token"];
NSLog(#"token = %#",token);
if (token !=NULL) {
NSString *notificationName = #"MTPostNotificationTut";
NSString *key = #"token";
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:token forKey:key];
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil userInfo:dictionary];
}
}
-(void)checkWithServer:(NSString *)urlname jsonString:(NSString *)jsonString {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlname]cachePolicy:NSURLCacheStorageAllowed timeoutInterval:10.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *string = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"stringFromData = %#",string);
id jsonResponseData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSDictionary *jsonResponseDict;
if ([jsonResponseData isKindOfClass:[NSDictionary class]]) {
jsonResponseDict = jsonResponseData;
} else {
}
jsonResponseData = [jsonResponseDict objectForKey:#"d"];
if (jsonResponseData == nil) {
id jsonExceptioTypeData = [jsonResponseDict objectForKey:#"ExceptionType"];
if (jsonExceptioTypeData != nil) {
NSLog(#"%s ERROR : Server returned an exception", __func__);
NSLog(#"%s ERROR : Server error details = %#", __func__, jsonResponseDict);
}
}
NSLog(#"jsonResponseData = %#",jsonResponseDict);
token = [jsonResponseDict objectForKey:#"token"];
NSLog(#"token = %#",token);
}
-(void)useNotificationWithString:(NSNotification*)notification {
NSString *urlString = #"https://www.mysite.com/my_services/user/login.json";
NSString *urlS = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSDictionary *inputData = [[NSDictionary alloc] initWithObjectsAndKeys:
#"ranjeet.gholave", #"username",
#"ran123", #"password",
nil];
NSError *error = nil;
NSData *jsonInputData = [NSJSONSerialization dataWithJSONObject:inputData options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonInputString = [[NSString alloc] initWithData:jsonInputData encoding:NSUTF8StringEncoding];
[self getTokenFromServer:urlS jsonString:jsonInputString];
}
-(void)getTokenFromServer:(NSString *)urlname jsonString:(NSString *)jsonString {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlname]cachePolicy:NSURLCacheStorageAllowed timeoutInterval:30.0];
[request setHTTPMethod:#"POST"];
// [request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:token forHTTPHeaderField:#"X-CSRFToken"];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(#"responseDataIn Second Method = %#",responseData);
id jsonResponseData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSLog(#"jsonResponseData = %#",jsonResponseData);
NSDictionary *jsonResponseDict;
if ([jsonResponseData isKindOfClass:[NSDictionary class]]) {
jsonResponseDict = jsonResponseData;
} else {
// Error-handling code
}
jsonResponseData = [jsonResponseDict objectForKey:#"d"];
if (jsonResponseData == nil) {
id jsonExceptioTypeData = [jsonResponseDict objectForKey:#"ExceptionType"];
if (jsonExceptioTypeData != nil) {
NSLog(#"%s ERROR : Server returned an exception", __func__);
NSLog(#"%s ERROR : Server error details = %#", __func__, jsonResponseDict);
}
}
}
if i cookie allowed then csrf token validation issue comes
and when i cookie not allowed then csrf token issue not comes ....how to resolved issue..thanks
Regards,
Ranjeet Gholave
I know this is a bit of an old thread. But you should check out https://github.com/kylebrowning/drupal-ios-sdk as well as AFNetworking. You're really working way harder than you have to.
But to answer your question, once you log in, the CSRF token will be returned in the user object and will be valid for then entire user session. So you can cache it and use it until the user logs out or their session expires.
With Drupal IOS SDK it is as simple as:
[DIOSUser userMakeSureUserIsLoggedInWithUsername:username
andPassword:password
success:^(AFHTTPRequestOperation *op, id response) {
DLog(#"user: %#", response);
[DIOSSession sharedSession].user = response;
//NOTE: fix for services 3.4+ CSRF Token Validation
[[DIOSSession sharedSession] setDefaultHeader:#"X-CSRF-Token" value:response[#"token"]];
[self saveLoginInfoForUserWithUsername:username andPassword:password];
[self processUserInfoWithUser:response];
success(response);
}
failure:^(AFHTTPRequestOperation *op, NSError *err) {
failure(err);
}
];
I want to wait until server reponse and parse XML done, then call another function. How can i do that? I used this code to send request to server and use NSXMLParser to parse XML response.
NSURL *url1 = [NSURL URLWithString:#"linkserver"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL: url1] ;
NSDictionary *params1 = #{
#"a" : vd;
#"b" : #"all"
};
NSMutableURLRequest *afRequest = [httpClient requestWithMethod:#"GET" path:nil parameters:params1] ;
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
NSString * parsexmlinput = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
[self parseXMLFile:parsexmlinput];// parse xml
[self getItemFromStatus];// wait to call another function at here???
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);
}
];
[httpClient enqueueHTTPRequestOperation:operation];
}
Please give me any suggestion. Thanks much
You have to make your request synchronous.
refer code something like:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://api.twitter.com/1.1/friends/ids.json?"]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
[request setHTTPMethod: #"GET"];
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
check this tutorial Ray Wenderlich using AFnetworking.
Using blocks and callbacks
- (IBAction)xmlTapped:(id)sender{
NSString *weatherUrl = [NSString stringWithFormat:#"%#weather.php?format=xml",BaseURLString];
NSURL *url = [NSURL URLWithString:weatherUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFXMLRequestOperation *operation =
[AFXMLRequestOperation XMLParserRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = self;
[XMLParser setShouldProcessNamespaces:YES];
[XMLParser parse];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[NSString stringWithFormat:#"%#",error]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[av show];
}];
[operation start];
}
You can do it in synchronous way...
NSURLResponse *response = nil;
NSError *error = nil;
NSURL *url = [NSURL URLWithString:urlStr];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
httpClient.parameterEncoding = AFFormURLParameterEncoding;
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST" path:[url path] parameters:params];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString * parsexmlinput = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if(error) {
errorCallback(error, nil);
} else {
//parse the xml here
}
OR
You can achive it by adding [operation waitUntilFinished],after it's added to the operation queue.Refer this==>Can AFNetworking return data synchronously (inside a block)?
OR
EDIT: In case you don't want to use the AFNetworking library.I prefer this way.
NSString *action_Post =[[NSString alloc] initWithFormat:#"authToken=%#",theMutableString];
NSURL *action_Url =[NSURL URLWithString:#"ur url here"];
NSData *action_PostData = [action_Post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *action_postLength = [NSString stringWithFormat:#"%d", [action_PostData length]];//your parameter to be posted here
NSMutableURLRequest *action_Request = [[NSMutableURLRequest alloc] init];
[action_Request setURL:action_Url];
[action_Request setHTTPMethod:#"POST"];
[action_Request setValue:action_postLength forHTTPHeaderField:#"Content-Length"];
[action_Request setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
//[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[action_Request setHTTPBody:action_PostData];
NSURLResponse *action_response;
NSData *action_Result = [NSURLConnection sendSynchronousRequest:action_Request returningResponse:&action_response error:&error];
if (!action_Result)
{
NSLog(#"Error");
}
else
{
//Parse your xml here
//call ur function
}
Modify it according to your GET/PUT methods.But i suggest you to go for POST method,as it is refered to be as secured one.
I want to fetch the facebook friends profile picture.I also give the access_token for it.
I search a lot on net but didn't got any good solution.
my code is as follow:
- (IBAction)advancedButtonPressed:(id)sender {
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
//NSString *key = #"xxxxxx";
NSString *key = #"xxxxxx";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
NSLog(#"facebook account =%#",self.facebookAccount);
ACAccountCredential *fbCredential = [self.facebookAccount credential];
accessToken = [fbCredential oauthToken];
NSLog(#"Facebook Access Token: %#", accessToken);
[self get];
} else {
//Fail gracefully...
NSLog(#"error getting permission %#",e);
}
}];
}
-(void)fr
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends?fields=id,name,picture,first_name,last_name,gender&access_token=BAAFcRQZCZAUeUBAICacM2q1V5UzRHee6xHGnbEdu19v6CZBIEDJmTwHBKtMZBwtVuFiEeuXqt4yKeSkeI17QZBGaZCeszBfOKdbZAfR4E9RN2nFqHalKPXZBga96WQCU8CSNG4ZCJCK1V7JIbqZAPRgNl6mjjO4Ns1CEaLpbXUYtum1CXbNqTtT82YpVVKoZCmMEBpqHfwYMx1OKu9RZBsjPZA6DlhKA1uGyU32EGJ8QOQZASJVQZDZD"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error) {
if(!error)
{
list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Dictionary contains data: %#", list );
if([list objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
nameLabel.text = [list objectForKey:#"username"];
});
}
else{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
}
But i always got the error like this:
error = {
code = 190;
message = "Malformed access token BAAFcRQZCZAUeUBAICacM2q1V5UzRHee6xHGnbEdu19v6CZBIEDJmTwHBKtMZBwtVuFiEeuXqt4yKeSkeI17QZBGaZCeszBfOKdbZAfR4E9RN2nFqHalKPXZBga96WQCU8CSNG4ZCJCK1V7JIbqZAPRgNl6mjjO4Ns1CEaLpbXUYtum1CXbNqTtT82YpVVKoZCmMEBpqHfwYMx1OKu9RZBsjPZA6DlhKA1uGyU32EGJ8QOQZASJVQZDZD?access_token=BAAFcRQZCZAUeUBAHBZBSdTL9wWFDOVthxj78bBJlrNEkPiKHdxZA1HaRmO9dtBTJdsZCtZCu2vaE5ByZAdK7Ox30BpIR0KTg0ZC6pi1IOE0KnZCZBSxqbycG0C6Ws5Ct4ferL3G0VU1wIfDypKekFM3zB4r5gAiUREQ66Yuz2Fu2mp5NGqZCBE1p357H41P2lKOAQN9EZAmu4q3SRtjMuVIw4dtdC00l4RhMuDWTOIUQlO54bgZDZD";
type = OAuthException;
};
}
I can't able to solve this. Help me!
If you're using an SLRequest, it will auto append the access token for you, and you also should not have any request params in the URL itself. Instead, you should do something like:
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:#{#"fields":#"id,name,picture,first_name,last_name,gender"}];
You can also use this instead of using SLRequest.It is also
NSURL *meurl = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/me?access_token=%#",fbAccessToken]];
NSURLRequest *req = [[NSURLRequest alloc]initWithURL:meurl];
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *userDataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
Brief backstory, our previous developer used ASIHTTPRequest to make POST requests and retrieve data from our webservice. For reasons unknown this portion of our app stopped working. Seemed like good enough time to future proof and go with AFNetworking. REST webservice runs on the CakePHP framework.
In short I am not receiving the request response string using AFNetworking.
I know the webservice works because I am able to successfully post data and receive the proper response using curl:
curl -d "data[Model][field0]=field0value&data[Model][field1]=field1value" https://example.com/api/class/function.plist
Per the previous developer's instructions I came up with the following.
#import "AFHTTPRequestOperation.h"
…
- (IBAction)loginButtonPressed {
NSURL *url = [NSURL URLWithString:#"https://example.com/api/class/function.plist"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:[usernameTextField text] forHTTPHeaderField:#"data[User][email]"];
[request setValue:[passwordTextField text] forHTTPHeaderField:#"data[User][password]"];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"operation hasAcceptableStatusCode: %d", [operation.response statusCode]);
NSLog(#"response string: %# ", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
[operation start];
}
output:
operation hasAcceptableStatusCode: 200
response string: a blank plist file
attempted solution 1:
AFNetworking Post Request
the proposed solution uses a function of AFHTTPRequestOperation called operationWithRequest. However, when I attempt to use said solution I get a warning "Class method '+operationWithRequest:completion:' not found (return type defaults to 'id'"
attempted solution 2: NSURLConnection. output: I'm able to print the success log messaged but not the response string.
*update - returns blank plist.
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *httpBodyData = #"data[User][email]=username#example.com&data[User][password]=awesomepassword";
[httpBodyData dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[NSData dataWithContentsOfFile:httpBodyData]];
NSHTTPURLResponse __autoreleasing *response;
NSError __autoreleasing *error;
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
// *update - returns blank plist
NSData *responseData = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"responseData %#",str);
if (error == nil && response.statusCode == 200) {
// Process response
NSLog(#"success");//returns success code of 200 but blank
NSLog(#"resp %#", response );
} else {
// Process error
NSLog(#"error");
}
These are the essential (stripping out conditions I've made for my own use) lines that ended up satisfying my request to the web service. Thanks for the suggestions #8vius and #mattt !
- (IBAction)loginButtonPressed {
NSURL *baseURL = [NSURL URLWithString:#"https://www.example.com/api/class"];
//build normal NSMutableURLRequest objects
//make sure to setHTTPMethod to "POST".
//from https://github.com/AFNetworking/AFNetworking
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
[httpClient defaultValueForHeader:#"Accept"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[usernameTextField text], kUsernameField,
[passwordTextField text], kPasswordField,
nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"https://www.example.com/api/class/function" parameters:params];
//Add your request object to an AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc]
initWithRequest:request] autorelease];
//"Why don't I get JSON / XML / Property List in my HTTP client callbacks?"
//see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
//mattt's suggestion http://stackoverflow.com/a/9931815/1004227 -
//-still didn't prevent me from receiving plist data
//[httpClient registerHTTPOperationClass:
// [AFPropertyListParameterEncoding class]];
[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];
[httpClient release];
}
Use AFHTTPClient -postPath:parameters:success:failure:, passing your parameters (nested dictionaries/arrays are fine). If you're expecting a plist back, be sure to have the client register AFPropertyListRequestOperation.
In any case, setValue:forHTTPHeaderField: is not what you want here. HTTP headers are for specifying information about the request itself; data is part of the request body. AFHTTPClient automatically converts parameters into either a query string for GET requests or an HTTP body for POST, et al.