Post text and URLs with TwitterKit 2.7 iOS SDK - ios

I just upgrade TwitterKit in my APP to 2.7 and could not post a tweet like before. Instead, I got an error after calling method sendTwitterRequest:completion:
"Error Domain=TwitterAPIErrorDomain Code=32 "Request failed: unauthorized (401)" UserInfo={NSLocalizedFailureReason=Twitter API error : Could not authenticate you. (code 32), TWTRNetworkingStatusCode=401, NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: unauthorized (401)}"
I did some research but got no luck. However, I accidentally found out that if I delete the ">>" in my "status" content string, everything is fine! Anyone has a clue why this happened? What if I need insert ">" in my tweet? Any clues would be appreciated!
NSDictionary *message = #{#"status": #"My tweet >> https://www.google.com"};
NSError *updateRequestError = nil;
NSURLRequest *updateRequest = [myAPIClient URLRequestWithMethod:#"POST" URL:#"https://api.twitter.com/1.1/statuses/update.json" parameters:message error:&updateRequestError];
if (updateRequestError) {
return;
}
[myAPIClient sendTwitterRequest:updateRequest completion:^(NSURLResponse* response, NSData* data, NSError* updateConnectionError){
if (!updateConnectionError) {
} else {
NSLog(#"error = %#", updateRequestError");
}
}];

Related

Get error while fetching user details from Twitter SDK after few logins

I am doing following code for get user details from Twitter. But, after few hours, I get error and I cannot get user details at that moment. Next day. I am able to get those details and after few logins, again I get error:
TWTRAPIClient *client = [TWTRAPIClient clientWithCurrentUser];
[client loadUserWithID:userID completion:^(TWTRUser *user, NSError *error) {
if(error)
{
completionBlock(nil, error);
}
else
{
NSDictionary *dicUser = #{ kTWTRIdStr : user.userID,
kTWTRScreenName : user.screenName,
kTWTRNameParam : user.name,
kTWTRProfilePicURL : user.profileImageURL
};
completionBlock(dicUser, nil);
}
}];
I am getting following error:
Error: Error Domain=TwitterAPIErrorDomain Code=99 "Request failed:
forbidden (403)" UserInfo={NSLocalizedFailureReason=Twitter API error
: Unable to verify your credentials (code 99),
TWTRNetworkingStatusCode=403,
NSErrorFailingURLKey=https://api.twitter.com/oauth2/token,
NSLocalizedDescription=Request failed: forbidden (403)}

How to do Access Token Request in Fitbit API Integration - iOS?

I did OAuth2 by using OAuth2 - https://github.com/trongdth/OAuth2-for-iOS ,
I successfully logged in and got response
{
"kOAuth_AccessToken" = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NDIzODY2NzEsInNjb3BlcyI6Indsb2Mgd3BybyB3bnV0IHdzbGUgd3NldCB3d2VpIHdociB3YWN0IHdzb2MiLCJzdWIiOiIzRFJQQzYiLCJhdWQiOiIyMjlROVEiLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4iLCJpYXQiOjE0NDIzODMwNzF9.5vTYvUAuvMflnOw_7cc1nZoighhtUx4RU26-Q7SewzQ";
"kOAuth_AuthorizeURL" = "https://www.fitbit.com/oauth2/authorize";
"kOAuth_Callback" = "http://oauth-callback/fitbit";
"kOAuth_ClientId" = string;
"kOAuth_ExpiredDate" = "";
"kOAuth_RefreshToken" = 97ad2a073f40f21974c8d27cdb74523047f39e98cd2adcfd6f6cc3eb92522d53;
"kOAuth_Scope" = "activity heartrate location nutrition profile settings sleep social weight";
"kOAuth_Secret" = string;
"kOAuth_TokenURL" = "https://api.fitbit.com/oauth2/token";
}
Here - how can I get code URI parameter value in the callback URI?
According to Fitbit doc's ---
Access Token Request:-
When a user authorizes your application in the Authorization Code Grant flow, your application must exchange the authorization code for an access token. The code is only valid for 10 minutes.
Authorization Header:-
The Authorization header should be set to Basic followed by a space and a Base64 encoded string of your application's client id and secret concatenated with a colon.
I did this by making use of AFNetworking lib, Please have a look on code (header)-
-(AFHTTPSessionManager *)getSessionManager {
if (!self.sessionManager){
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = nil;
NSURL *url = [NSURL URLWithString:FITBIT_BASE_URL];
self.sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:url sessionConfiguration:sessionConfiguration];
}
// [self.sessionManager.requestSerializer setValue:Appdelegate.fitbitAuthorizationString forHTTPHeaderField:#"Authorization"];
[self.sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:Appdelegate.fitbitOAuthClientId password:Appdelegate.fitbitOAuthClientSecret];
self.sessionManager.responseSerializer = [JSONResponseSerializerWithData serializer];
self.sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
return self.sessionManager;
}
and requested token access - code (parameter's) is
NSDictionary *tempParamsDict = #{#"client_id":[JsonUtil stringFromKey:#"kOAuth_ClientId" inDictionary:dictResponse], #"grant_type":#"authorization_code", #"redirect_uri":[JsonUtil stringFromKey:#"kOAuth_Callback" inDictionary:dictResponse], #"code":#""};
My request is
[dP postJsonContentWithUrl:#"oauth2/token" parameters:tempParamsDict completion:^(BOOL success, id responseObject, NSError *error) {
// NSLog(#"%#", responseObject);
if (success) {
NSLog(#"Response: %#", responseObject);
}
else {
NSLog(#"%#", error.localizedDescription);
/*
You got 404 response ,The 404 or Not Found error message is a HTTP standard response code indicating that the client was able to communicate with the server, but the server could not find what was requested.
Make sure that you have valid url, try to put your link in the browser and see if it is correct, if the url you requested have special headers
*/
}
}];
I am getting - Request failed: not found (404) error.
What have I missed and How can I proceed further to get token and access Fitbit APIs?
Update
That was happening due to access code so I tried to access code, now I am getting this error
description of error->_userInfo:
{
NSErrorFailingURLKey = "https://api.fitbit.com/oauth2/token.json";
NSErrorFailingURLStringKey = "https://api.fitbit.com/oauth2/token.json";
NSLocalizedDescription = cancelled;
}
Thanks a lot in advance
Instead of NSURLSession use NSURLConnection to request data from Fitbit APIs.

stackmob ios datastore http 401 error

I'm using the iOS DataStore API to upload data to StackMob. I get this error when I try to use my smclient initialized with my public key.
HTTP Code=401 "The operation couldn’t be completed. (HTTP error 401.)" UserInfo=0xa14dac0 {error=Insufficient authorization}
Sample code
[[self.smclient dataStore] createObject:eventDictObj
inSchema:#"EventSchema"
onSuccess:^(NSDictionary *object, NSString *schema)
{
NSLog(#"Created online event : %#", object);
successBlock();
}
onFailure:^(NSError *error, NSDictionary* object, NSString *schema)
{
failedBlock(error);
}];
And smclient is initialized as follows
self.smclient = [[SMClient alloc] initWithAPIVersion:#"0" publicKey:#"xxxxxxxxxx"];
For this use case I don't need to use the logged in user credentials to create this entry in StackMob
Make sure that the permissions are set to Open on your stack mob database.

iOS HTTP request - getting the error response message

This is my bit of code doing a GET request to a REST api.
Im not sure how to get back the message if I get an error:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *URL = [NSURL URLWithString:urlString];
[request setURL:URL];
[request setHTTPMethod:#"GET"];
NSError *err = nil;
NSHTTPURLResponse *res = nil;
NSData *retData = [NSURLConnection sendSynchronousRequest:request returningResponse:&res error:&err];
if (err) // This part is never called.
{
NSLog(#"Error: %#", err);
}
else
{
if (res.statusCode != 200)
{
// show the user the status message
NSLog(#"Error: %#", res); // This part is called
}
else
{
}
}
I want to get the error message if it was not successful. But the if (err) block is never called. err is still null, although the statuscode is 400.
And if successful I will get back a json response.
In the code above I get back a statusCode of 400
The error block is not called because the error object is created only if a system level error occurs. This does not happen because the request is sent correctly and the server sends a response. If you are in control of the server, you should probably make it return status code 200 and include an app level status code in the response, that would tell your app that the entered credentials are incorrect.
Edit:
To get status message you can use
+ (NSString *)localizedStringForStatusCode:(NSInteger)statusCode
This is a class method of the NSHTTPURLResponse class.
if (res.statusCode != 200)
{
// show the user the status message
NSLog(#"Error: %#", [NSHTTPURLResponse localizedStringForStatusCode: res.statusCode]); // This part is called
}
Take a look at the NSError class reference:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/Reference/Reference.html
You can try to log the error message from the localizedDescription.
you are receiving this status code because- The Web server (running the Web site) thinks that the data stream sent by the client (e.g. your Web browser or our CheckUpDown robot) was 'malformed' i.e. did not respect the HTTP protocol completely. So the Web server was unable to understand the request and process it
to log above problem in respect to ios visit this link
If you read the documentation of sendSynchronousRequest...
error
Out parameter used if an error occurs while processing the request. May be NULL.
this mean that erro will be a valid NSError object in case there is a problem to resolve the request, like a malformed URL.
If the request can be resolved error will be NULL and according with HTTP protocol and depending to the server that you are trying to connect, the NSHTTPURLResponse object will contain all the information about the request.
In general is an error think that every status code different than 200 is an error, for example for a REST based API 204 mean empty data, and in this case the request is finished successfully but the requested resource is just empty data, and this is not an error.
So about your question, is absolutely fine that error is NULL most of the time, if is not mean that there is an issue before reach the target server, in general you have to consider both, error and according to the server that you are trying to talk the status code maps, in most of cases the REST pattern

Simple RestKit login without using JSON

It's been two days that I'm looking for a simple code for RestKit API for logging into a website without using JSON. Here is the code that I wrote so far:
- (void)login
{
[RKClient clientWithBaseURLString:#"http://Mywebsite.com/login.php"];
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObject:#"user" forKey:#"username"];
[params setObject:#"pass" forKey:#"password"];
[params setObject:#"login" forKey:#"type"];
[[RKClient sharedClient] post:#"/login" params:params delegate:self];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
NSLog(#"HTTP status code: %d", response.statusCode);
NSLog(#"HTTP status message: %#", [response localizedStatusCodeString]);
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSRange range = [[error localizedDescription] rangeOfString:#"-1012"];
if (range.length > 0){
//Do whatever here to handle authentication failures
}
RKLogError(#"Hit error: %#", error);
}
Here is the log that I receive:
2012-09-08 21:44:14.633 RestKitTest[889:fb03] I restkit:RKLog.m:33 RestKit initialized...
2012-09-08 21:44:15.010 RestKitTest[889:fb03] I restkit.network.reachability:RKReachabilityObserver.m:369 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x6c5a560 host=0.0.0.0 isReachabilityDetermined=YES isMonitoringLocalWiFi=NO reachabilityFlags=-R -----l->
2012-09-08 21:44:21.021 RestKitTest[889:fb03] I restkit.network:RKRequest.m:676 Status Code: 404
2012-09-08 21:44:21.036 RestKitTest[889:fb03] HTTP status code: 404
2012-09-08 21:44:21.090 RestKitTest[889:fb03] HTTP status message: not found
Any idea how I can fix this issue would be appreciated.
I'd say it 404s because you set baseURL as http://Mywebsite.com/login.php yet you POST as post:#"/login". Do you really want to access http://Mywebsite.com/login.php/login?
The baseURL should be set to a common prefix to all your backend calls, in your case http://Mywebsite.com, the resource itself should be posted as post:#"/login.php". The resource name and baseURL are concatenated before the request is sent.
You'll need to provide info on what login.php is doing. I don't see why it should 404 if the script url resolves correctly.
Also, if that PHP script does a redirect on success, you should use the RKClient method post:usingBlock: and inside that block do request.followRedirect = NO;. That way you'll get the correct status code, if you are returning one.
If may also help to log more of the response:
NSLog(#"Header fields: %#", response.allHeaderFields);
NSLog(#"Body: %#", response.bodyAsString);

Resources