Updating MGTwitterEngine to New Twitter API v1.1 - iphone

I am currently updating my app to .json from xml for Twitters new API v1.1. I currently have .json working and can log on, get me timelines, mentions, but when trying to get direct messages, lists, or user info it seems its looking for "cookies" but it is not stored.
This is the error message received by twitter when trying to make a simple GET user/show call:
Twitter request failed: 08AD12D3-0044-49AB-8D3D-4E61D8398550 with error:Error Domain=HTTP
Code=400 "The operation couldn’t be completed. (HTTP error 400.)" UserInfo=0xce90540
{response=<NSHTTPURLResponse: 0xce94bd0> { URL:
https://api.twitter.com/1.1/users/show.json?screen_name=FreeAppl3 } { status code: 400,
headers {
"Content-Encoding" = gzip;
"Content-Type" = "application/json; charset=utf-8";
Date = "Fri, 14 Jun 2013 09:25:40 UTC";
Server = tfe;
"Set-Cookie" = "guest_id=v1%3A137120194019582695; Domain=.twitter.com; Path=/;
Expires=Sun, 14-Jun-2015 09:25:40 UTC";
"Strict-Transport-Security" = "max-age=631138519";
"Transfer-Encoding" = Identity;
} }, body={"errors":[{"message":"Bad Authentication data","code":215}]}hjD4nzoeOUaTQ1Q%3D}
When I call [twitterEngine isAuthorized]; is returns YES and if I check for my access token string, I receive what was stored on initial login. I have searched and searched as to what is happening or how to fix the issues, but am simply stuck and any help would be greatly appreciated.
Twitter API - https://dev.twitter.com/docs/api/1.1/get/users/show
Twitter Error Codes - https://dev.twitter.com/docs/error-codes-responses

refer FHSTwitterEngine you can use newly FHSTwitterEngine and if you request this method without autenticating, the users status is removed... you need to send consumer key and token along with screen_name..
In FHSTwitterEngine
//get username pass to method. In Dictionary you can get all info
NSString *username = [[FHSTwitterEngine sharedEngine]loggedInUsername];
NSDictionary *data=[[FHSTwitterEngine sharedEngine]getUserProfile:username];
// method to get all user info
-(id)getUserProfile:(NSString *)username
{
if (username.length == 0) {
return getBadRequestError();
}
NSURL *baseURL = [NSURL URLWithString:url_users_show];
OAMutableURLRequest *request = [OAMutableURLRequest requestWithURL:baseURL consumer:self.consumer token:self.accessToken];
OARequestParameter *usernameP = [OARequestParameter requestParameterWithName:#"screen_name" value:username];
NSArray *params = [NSArray arrayWithObjects:usernameP, nil];
id userShowReturn = [self sendGETRequest:request withParameters:params];
return userShowReturn;
}

Related

Salesforce rest api INVALID_SESSION_ID

I'm trying to connect my asp.net REST api to salesforce. I'm succesfully going through authentification, but when I start to send POST requests, I'm getting an error
{"errorCode":"INVALID_SESSION_ID","message":"Session expired or invalid"}
Here is my POST request:
//SFServerUrl = "https://na17.salesforce.com/services/";
//url = "data/v28.0/sobjects/Account";
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postBody);
HttpWebRequest request = WebRequest.Create(Globals.SFServerUrl + url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = postBytes.Length;
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
HttpCookie cookie = HttpContext.Current.Request.Cookies[Globals.SFCookie];
var ticket = FormsAuthentication.Decrypt(cookie.Value);
string authToken = ticket.UserData;
request.Headers.Add("Authorization", "Bearer " + authToken);
postStream.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
tempString = Encoding.ASCII.GetString(buf, 0, count);
sb.Append(tempString);
}
}
while (count > 0);
return new Tuple<bool, string>(true, sb.ToString());
When I'm trying to send GET request - I recieve 200 response.
Also, I've tried to send a POST Request with the same token from Simple Rest Client and it get's 200 response. I tried to change my "Authorization : Bearer" Header to "Authorization : Oauth", but nothing changed. I also tried to catch this error, get refresh token and send a request again with refreshed token, but nothing changed. Please, help me with this.
Using workbench I was able to POST the following JSON to /services/data/v29.0/sobjects/Account and create a new Account.
{
"Name" : "Express Logistics and Transport"
}
Raw Response
HTTP/1.1 201 Created
Date: Sun, 07 Sep 2014 21:32:06 GMT
Set-Cookie: BrowserId=_HC-bzpTQABC1237vFu2hA;Path=/;Domain=.salesforce.com;Expires=Thu, 06-Nov-2014 21:32:06 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Sforce-Limit-Info: api-usage=209/15000
Location: /services/data/v29.0/sobjects/Account/0010000000000001AAA
Content-Type: application/json;charset=UTF-8
Content-Encoding: gzip
Transfer-Encoding: chunked
{
"id" : "0010000000000001AAA",
"success" : true,
"errors" : [ ]
}
Things to check:
Your URL. It appears to be missing the leading /services
Is SFServerUrl the same Salesforce pod/server that the Session Id was issued to? If the Session Id came from another pod then it would be invalid on na17.
How did you create the Session Id? If you used OAuth, what scopes did you request?
Is the Session Id coming out of the cookie valid?
Has something else using the same Session Id called logout and invalidated the session?
Incidentally, the Salesforce StackExchange site is a great place to ask Salesforce specific questions.
See also:
Using REST API Resources - Create a Record
The problem was that I added Headers after Content. When I switched these lines of code everything worked.

Delete Object in Restkit .20 did not take JSON Values

I have an API which is used to delete a record in server DB. I used to construct the API with the request ID .It was working with CURL, but in Restkit it seems to give an error.
The Curl is:
curl -d '{eve:{mod_policy:"current"}}' -X DELETE -H Content-Type:application/json https://myurl.com/eve/eve_id?token=my_aut_token\&apikey=myapi_key.
I checked with POST & PATCH. It takes the JSON as a correct form.
My RestKit Code Sample:
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:#{ #"modPolicy" : #"mod_policy"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Event class] rootKeyPath:#"eve"];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Events class]];
[responseMapping addAttributeMappingsFromDictionary:#{
#"data" : #"data",
#"status":#"status"
}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:nil keyPath:#"" statusCodes:[NSIndexSet indexSetWithIndex:200]];
[objectManager addRequestDescriptor:requestDescriptor];
[objectManager addResponseDescriptor:responseDescriptor];
NSString * urlPath = [NSString stringWithFormat:#"/eve/%#?token=%#&apikey=%#",eventID,loginToken,apiKey];
[objectManager deleteObject:hubEve path:urlPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *result)
{
DLog(#" response code is %d",operation.HTTPRequestOperation.response.statusCode);
Events * _event = [result firstObject];
DLog(#"status %#",_event.status);
if([_eventt.status isEqualToString:#"success"])
{
DLog("Move Next");
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
DLog("error %#",error);
}];
Some log details, if I send As DeleteObject in request:
request.body=(null) //Restkit Log
Or if I send as post Object/Patch Object
request.body={"eve":{"mod_policy":"all"}} //Restkit Log
Request mapping is explicitly not performed for DELETE requests. RestKit expects that when deleting you will be using the system to add parameters into the URL. You will need to plan some other method by which to delete. This could be using the RestKit mapping operation to create the payload data and then using the methods to create the URL request and setting the body data explicitly.
RESTKit does not support DELETE request with request.body parameter
natively because HTTP 1.1 doesn't support DELETE request with
request.body. There is a work around to set request.body explicitly but
its complex.
The request works well with cURL but not with HTTP, maybe because cURL
does not send DELETE request with request.body as DELETE but upgrades it
to PUT, we are not sure though.

Xmpp gtalk authentication with google access token

I am using xmpp framework to integrate gtalk in my application. I have successfully authenticated user using OAuth 2.0. Now i want to use the access token and user email to authenticate xmpp stream. I know that the authentication call get sent xmppStreamDidConnect method using this method authenticateWithPassword. This requires a password, i want to get it done using the google access token. Any help?
Yes you can do it please follow the steps:
Register your app on google developer console.
Generate access token with following scope:
https://www.googleapis.com/auth/googletalk
start authentication as following:
(BOOL)start:(NSError **)errPtr
{
XMPPLogTrace();
// From RFC 4616 - PLAIN SASL Mechanism:
// [authzid] UTF8NUL authcid UTF8NUL passwd
//
// authzid: authorization identity
// authcid: authentication identity (username)
// passwd : password for authcid
NSString *accessToken = #"ACCESS-TOKEN-STRING-FROM Google";//TODO: assign your generated access token
NSLog(#"stream supports: %#",xmppStream.supportedAuthenticationMechanisms);
NSString *payload = [NSString stringWithFormat:#"\0%#\0%#", xmppStream.hostName, accessToken];
NSLog(#"payload = %#",payload);
NSString *base64 = [[payload dataUsingEncoding:NSUTF8StringEncoding] xmpp_base64Encoded];
NSXMLElement *auth = [NSXMLElement elementWithName:#"auth" xmlns:#"urn:ietf:params:xml:ns:xmpp-sasl"];
[auth addAttributeWithName:#"mechanism" stringValue:#"X-OAUTH2"];
[auth addAttributeWithName:#"auth:service" stringValue:#"oauth2"];
[auth addAttributeWithName:#"xmlns:auth" stringValue:#"https://www.google.com/talk/protocol/auth"];
[auth setStringValue:base64];
[xmppStream sendAuthElement:auth];
return YES;
}
Everything should work as expected, please comment.

Send HTTPBody data with restkit

I'm using a firefox tool call "Poster" to check that my web service is working. When I POST the request I send a JSON object in the content to send (also call HTTP body data).
When I press the POST button the result is fine.
Now I want to do exactly the same with RestKit in objective-c:
NSString *squery = #"{\"Sort\":\"Relevance\",\"DaysToSearch\":0,\"WorkType\":\"\",\"PageSize\":20,\"LastRunCount\":0,\"IndustryCodes\":[\"\"],\"AccountId\":27,\"Experience\":\"\",\"GetResultCount\":0,\"Keywords\":\"iOS\",\"PageIndex\":0,\"DistanceFromLocation\":\"250\",\"SalaryType\":\"\",\"JobQueryId\":\"\",\"JobTitleCodes\":[\"\"]}";
RKObjectLoader *objectLoader = [[RKObjectManager sharedManager] objectLoaderWithResourcePath:url delegate:performJobQueryHandler];
objectLoader.method = RKRequestMethodPOST;
objectLoader.objectMapping = s.jobQueryDataMapper;
objectLoader.HTTPBody = [squery dataUsingEncoding:NSUTF8StringEncoding];
objectLoader.serializationMIMEType = RKMIMETypeJSON;
[objectLoader send];
As a result I get: "An non-fault exception is occured."
In the FireFox extension "Poster" if I use a different mine-type than "application/json", let say "application/x-www-form-urlencoded" I get the same error: "An non-fault exception is occured."
Is something wrong with objectLoader.serializationMIMEType = RKMIMETypeJSON; ???
Martin Magakian
Ok I think I find out.
I activated RestKit debug with
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
And I get:
2012-02-14 11:55:48 [4048:207] T restkit.network:RKRequest.m:318 Prepared POST URLRequest '<NSMutableURLRequest http://servicestest.foo.com/jobservice/jobservice.svc/json/jobquery>'. HTTP Headers: {
Accept = "application/json";
"Content-Type" = "application/x-www-form-urlencoded";
}. HTTP Body: Sort=Relevance&DaysToSearch=0&WorkType=&SalaryType=&LastRunCount=0&IndustryCodes[]=&Experience=&AccountId=0&GetResultCount=0&PageIndex=0&DistanceFromLocation=250&PageSize=20&JobQueryId=&JobTitleCodes[]=.
So I think using RKObjectLoader object don't care about objectLoader.serializationMIMEType = RKMIMETypeJSON; because the Content-Type remain "Content-Type" = "application/x-www-form-urlencoded"; instead of "Content-Type" = "application/json";
Do you think it's a bug or the normal behavior ?

ASIHTTPRequest Returning HTML instead of JSON

I am using ASIHTTPRequest to contact an API the problem is that it is returning html instead of JSON and i have no idea why. Everything has been working great for weeks and i can't seem to figure out what has broken..
What's strange is doing exactly the same request with a browser or postie returns the correct JSON response, but when i do the request via ASIHTTPRequest these are the response headers i get:
"Cache-Control" = "private, max-age=0, must-revalidate";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Type" = "text/html; charset=utf-8";
Date = "Tue, 05 Jul 2011 21:11:10 GMT";
Etag = "\"e467792713ac4124f055c1719f4ea6c2\"";
Server = "nginx/0.7.65";
Status = "200 OK";
"Transfer-Encoding" = Identity;
"X-Runtime" = 1;
And the html (which should be json)..
<div id="universal_meta" logged_in_user_id="removed" style="display:none"></div>
<div id="meta" screen="projects" logged_in_as="removed"></div>
<h1>9 projects with 50 open issues</h1>
<ul class="biglinks progressbars">
etc...
Here is the code used to do the request..
NSURL *url = [NSURL URLWithString:path];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
if(secure){
[request setUsername:self.username];
[request setPassword:self.password];
}
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[request setDownloadDestinationPath:destination];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
I have triple checked all of the login details/url, everything is correct, i would really appreciate any help with this one as i am completely lost.
--
Update:
Lighthouse have acknowledged a bug regarding headers on their side. Waiting on a solution from them.
Did you check that the headers sent using your browser are also the same as when you send the request by code?
Especially did you try to add the "Accept" header to your request to define that you accept the json Content-Type?
[request addRequestHeader:#"Accept" value:#"application/json"];
Try using a tool like wireshark or charlesproxy to compare the working requests from your browser/postie, and compare them to the non-working requests from ASIHTTPRequest - once you spot what's different it should be easy to fix.
AliSoftware's suggestion is one of the most likely differences you'll see, but it's possible there are other things too.