I use TwitterKit to send tweet, use this code.
TWTRComposer *twitterComposer = [[TWTRComposer alloc] init];
[twitterComposer setText:string];
[twitterComposer setURL:[NSURL URLWithString:url]];
[twitterComposer setImage:image];
[twitterComposer showFromViewController:viewController completion:^(TWTRComposerResult result) {
if (result == TWTRComposerResultDone) {
}else {
}
}];
but crash in code
[twitterComposer showFromViewController:viewController completion:^(TWTRComposerResult result) {
I had get Twitter login session
use SLComposerViewController the same to crash
crash info :
Application tried to present a nil modal view controller on target <>
in ios 10.0.2
I can't find any answer in https://twittercommunity.com
check session before call TWTRComposer.Otherwise app will crash.
try this:
[[Twitter sharedInstance] logInWithCompletion:^(TWTRSession * _Nullable session, NSError * _Nullable error) {
if (session) {
TWTRComposer *composer = [[TWTRComposer alloc] init];
[composer setText:#"just setting up my Fabric"];
[composer setImage:[UIImage imageNamed:#"fabric"]];
[composer setURL:[NSURL URLWithString:#"http://www.toshow.com"]];
[composer showFromViewController:[UIApplication sharedApplication].keyWindow.rootViewController completion:^(TWTRComposerResult result) {
}];
} else {
[CustomToast makeToast:#"get session failed"];
}
}];
Related
I am working on Facebook App invitation, If I am already logged in to the Facebook the App dialog appears without any problem but if I am not logged in it doesn't but the control goes to didCompleteWithResults delegate with nil results dict. Please help if possible
-(IBAction)InviteFBFriends:(id)sender
{
if (![FBSDKAccessToken currentAccessToken])
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"public_profile",#"email", #"user_photos"] fromViewController:viewController handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
// Process error
} else if (result.isCancelled) {
// Handle cancellations
} else if([FBSDKAccessToken currentAccessToken]){
[self InviteFBFriends:nil];
}
}];
return;
}
//FOR SENDING INVITATIONS TO FRIENDS
FBSDKAppInviteContent *content =[[FBSDKAppInviteContent alloc] init];
content.appLinkURL = [NSURL URLWithString:myAppLinkURL];
FBSDKAppInviteDialog *fBSDKAppInviteDialog = [[FBSDKAppInviteDialog alloc] init];
fBSDKAppInviteDialog.delegate = self;
fBSDKAppInviteDialog.content = content;
[fBSDKAppInviteDialog show];
}
- (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didCompleteWithResults:(NSDictionary *)results{
NSLog(#"%#",results);
}
- (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error{
NSLog(#"%#",error);
}
i would recommend performing this method as the following, because there is delay occurs of this block method, besides you should check your response token instead of currentAccessToken
-(IBAction)InviteFBFriends:(id)sender {
if (![FBSDKAccessToken currentAccessToken]) {
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"public_profile",#"email", #"user_photos"] fromViewController:viewController handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
// Process error
} else if (result.isCancelled) {
// Handle cancellations
} else if(result.token){
[self showInvitationsToFriends];
}
}];
}
}
- (void)showInvitationsToFriends {
//FOR SENDING INVITATIONS TO FRIENDS
FBSDKAppInviteContent *content =[[FBSDKAppInviteContent alloc] init];
content.appLinkURL = [NSURL URLWithString:myAppLinkURL];
[FBSDKAppInviteDialog showFromViewController:self withContent:content delegate:self];
}
I am new to the concept of POSTing to twitter. I've looked here in order to understand how GET something from twitter. But I can't find any example about how to POST something to twitter.
how do I tell twitter that userXYZ is posting a tweet? How about the text body of the tweet itself.
Again, I'm very new to the concept.
You can easily find those in API Documentation. I think you are looking for this.
Also there are some question already asked in SO. You can also check this.
Using Twitter SDK import #import<Twitter/Twitter.h> in your .h or .m file
if ([TWTweetComposeViewController canSendTweet])
{
NSURL* aURL = [NSURL URLWithString:#"your image Url"];
NSData* data = [[NSData alloc] initWithContentsOfURL:aURL];
UIImage *img1 = [UIImage imageWithData:data];
// Initialize Tweet Compose View Controller
TWTweetComposeViewController *vc = [[TWTweetComposeViewController alloc] init];
// Settin The Initial Text
[vc setInitialText:#"Setting The Initial Text"];
[vc addImage:img1];
// Adding a URL
strWEBTwitter = #"Pass Your URL here"
[vc addURL:[NSURL URLWithString:strWEBTwitter]];
// Setting a Completing Handler
[vc setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
[self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Result : %d", result);
if (result == TWTweetComposeViewControllerResultDone)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Message" message:#"Thanks for sharing." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil]; [alertView show];
}
else if (result == TWTweetComposeViewControllerResultCancelled)
{
NSLog(#"Cancle")
}
}];
// Display Tweet Compose View Controller Modally
[self presentViewController:vc animated:YES completion:nil];
} else
{
// Show Alert View When The Application Cannot Send Tweets
NSString *message = #"There are no Twitter accounts configured. You can add or create a Twitter account in Settings.";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"No Twitter Accounts" message:message delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"Cancel",nil];
[alertView show];
}
Thanks Rashad. This is what I am using now. It works.
- (void)testPost {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
if (accounts.count)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:#"check Check CHECK" forKey:#"status"];
NSString *retweetString = [NSString stringWithFormat:#"https://api.twitter.com/1.1/statuses/update.json"];
NSURL *retweetURL = [NSURL URLWithString:retweetString];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:retweetURL parameters:dict];
request.account = [accounts objectAtIndex:0];
[request performRequestWithHandler:^(NSData *responseData1, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (responseData1)
{
NSError *error1 = nil;
id response = [NSJSONSerialization JSONObjectWithData:responseData1 options:NSJSONReadingMutableLeaves error:&error1];
NSLog(#"%#", response);
}
}];
}
}
}];
}
1) I have found the Twitter rush sample code from this link Twitter with OAuth
for the integration.
I have added consumer key and secret key. But it never authorizes the app.
2) And if I use share kit it gives the error that there was a problem requesting access from twitter.
3) If I use social framework then it will give alert if user hasn't added his/her account in settings.
I need that user shouldn't go outside the app for twitter login.
Does anyone have any idea on what would be the best way to integrate with twitter?
Please help.
I Hope This will help you . . .
1.Add following classes to your project
GTMOAuthAuthentication.h/m
GTMOAuthSignIn.h/m
GTMHTTPFetcher.h/m
GTMOAuthViewControllerTouch.h/m
GTMOAuthViewTouch.xib
2 . Add following frameworks
Security.framework and SystemConfiguration.framework.
3 .set -ObjC build option for the application target's "Other Linker Flags".
4 . Then it's time for some coding .
import GTMOAuthAuthentication.h and GTMOAuthViewControllerTouch.h
- (void)signInWithTwitter
{
NSURL *requestURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/request_token"];
NSURL *accessURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/access_token"];
NSURL *authorizeURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/authorize"];
NSString *scope = #"http://api.twitter.com/";
GTMOAuthAuthentication *auth = [self authForTwitter];
[auth setCallback:#"http://www.noop.com/OAuthCallback"];
GTMOAuthViewControllerTouch *viewController;
viewController = [[GTMOAuthViewControllerTouch alloc] initWithScope:scope
language:nil
requestTokenURL:requestURL
authorizeTokenURL:authorizeURL
accessTokenURL:accessURL
authentication:auth
appServiceName:#"AppName : Twitter"
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[appDelegate.navigationController pushViewController:viewController animated:YES];
}
- (GTMOAuthAuthentication *)authForTwitter {
GTMOAuthAuthentication *auth = [[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
consumerKey:TWITTER_CONSUMER_KEY
privateKey:TWITTER_CONSUMER_SECRET];
[auth setServiceProvider:#"Twitter"];
return auth;
}
- (void)viewController:(GTMOAuthViewControllerTouch *)viewController finishedWithAuth:(GTMOAuthAuthentication *)auth error:(NSError *)error {
if(error)
{
//handle error
}
else
{
// do stuff as per your app.
}
}
NOte : if you get error message like "failed to validate oauth signature and token" then check you system time is correct or not .
If you want that user shouldn't go outside you can use ACAccountStore Account.Framework and Social.framework for iOS 6,
NSUrl *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/users/show.json"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:twittername,#"screen_name",nil];
account = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
NSArray *twitterAccounts = [account accountsWithAccountType:twitterAccountType];
// Runing on iOS 6
if (NSClassFromString(#"SLComposeViewController") && [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
[account requestAccessToAccountsWithType:twitterAccountType options:NULL completion:^(BOOL granted, NSError *error)
{
if (granted)
{
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.preparedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
// [self loadData:data];
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
NSLog(#"data:%#",newStr);
}
});
}];
});
}
}];
}
else if (NSClassFromString(#"TWTweetComposeViewController") && [TWTweetComposeViewController canSendTweet]) // Runing on iOS 5
{
[account requestAccessToAccountsWithType:twitterAccountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted)
{
TWRequest *request = [[TWRequest alloc] initWithURL:url parameters:params requestMethod:TWRequestMethodGET];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.signedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"data:%#",newStr); }
});
}];
});
}
}];
}
}
You have to retain ACAccountStore: in .h
#property (nonatomic, strong) ACAccountStore *account;
I'm trying to add a Facebook login to my app with the Facebook SDK for iOS.
Because the request to Facebook's servers may take some time, I thought to use MBProgressHUD.
The problem is that both MBProgressHUD and FBRequest use blocks, so I'm expecting some strange behavior.
This is the code i used:
MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Loading";
HUD.minSize = CGSizeMake(135.f, 135.f);
[HUD showAnimated:YES whileExecutingBlock:^{
[FBSession openActiveSessionWithReadPermissions:#[#"email"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if (error) {
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"error"]];
HUD.mode = MBProgressHUDModeCustomView;
HUD.detailsLabelText = error.localizedFailureReason;
HUD.labelText = #"Error";
}
if (state == FBSessionStateClosedLoginFailed) {
[FBSession.activeSession closeAndClearTokenInformation];
}
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
//Save User's Data
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]];
HUD.mode = MBProgressHUDModeCustomView;
HUD.labelText = #"Logged in";
} else {
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"error"]];
HUD.mode = MBProgressHUDModeCustomView;
HUD.detailsLabelText = #"An error occurred, please retry later";
HUD.labelText = #"Error";
}
}];
}
}];
sleep(2);
} completionBlock:^{
//Return to previous page
}];
The problem is that when I push the button related to this method, I see the progress HUD for less than a second, then I'm brought back to the previous page.
What I'd like to see is the HUD displayed during all the process.
Can someone tell me how to do it?
Thanks
The problem is that showAnimated:whileExecutingBlock: closes the HUD right after the block completes. The facebook authentication method executes code in the background and returns immediately. Instead, try just showing the HUD, and hiding it in the Facebook completion blocks.
-(void)yourMethodThatLogsIntoFacebook {
MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Loading";
HUD.minSize = CGSizeMake(135.f, 135.f);
[HUD show:YES];
[FBSession :#[#"email"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if (error) {
[self updateHud:HUD withImage:#"error" text:#"Error" detailText:error.localizedFailureReason];
}
if (state == FBSessionStateClosedLoginFailed) {
[FBSession.activeSession closeAndClearTokenInformation];
}
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
//Save User's Data
[self updateHud:HUD withImage:#"37x-Checkmark.png" text:#"Logged in" detailText:nil];
} else {
[self updateHud:HUD withImage:#"error" text:#"Error" detailText:#"An error occurred, please retry later"];
}
}];
}
}];
}
-(void)updateHud:(MBProgressHUD *)hud withImage:(NSString *)imageName text:(NSString *)text detailText:(NSString *)detailText {
hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
hud.mode = MBProgressHUDModeCustomView;
hud.labelText = text;
hud.detailText = detailText;
[hud hide:YES afterDelay:2.];
}
Similar to iOS 6 Social framework not going to settings or no alert but i am trying to use SLRequest:
I am trying to bring up the alert "No Facebook Account" when the user has not logged in to Facebook in the Settings. I have found that the alert appear AFTER you present the SLComposeViewController, rather than inside the if statement.
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
//setup controller and callback code
[self presentViewController:controller animated:YES completion:nil];
}
However, I am trying to use SLRequest and i dont want to present the SLComposeViewController, but instead, after checking the accounts, popup the alert. My code is here:
- (void)postImageFB
{
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
NSLog(#"can post");
} else {
NSLog(#"cant post");
}
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
NSLog(#"accounts: %i", [accountsArray count]);
// Is it possible to popup the alert here if accounts = 0?
NSDictionary *options = #{ ACFacebookAppIdKey: #"123456789", ACFacebookPermissionsKey: #[#"publish_stream"], ACFacebookAudienceKey: ACFacebookAudienceFriends };
[accountStore requestAccessToAccountsWithType:accountType options:options completion:^(BOOL granted, NSError *error) {
if(granted) {
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] > 0) {
ACAccount *facebookAccount = [accountsArray objectAtIndex:0];
NSDictionary *parameters = #{#"message": #"testing"};
SLRequest *facebookRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://graph.facebook.com/me/photos"]
parameters:parameters];
[facebookRequest addMultipartData: [self getImageDataFromPlistWithFilename:#"image1.png"]
withName:#"source"
type:#"multipart/form-data"
filename:#"TestImage"];
facebookRequest.account = facebookAccount;
[facebookRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (error) {
NSLog(#"%#",error.description);
} else {
NSLog(#"responedata:%#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
}
}];
}
}
}];
}
Ok, I have discovered that isAvailableForServiceType always returns true?
so started testing on the device.
I figured that using an invisible SLComposeViewController to bring up the Alert seems to be a suitable workaround:
if (![SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
controller.view.hidden = YES;
[self presentViewController:controller animated:NO completion:nil];
} else {
// Put posting code here: SLComposeViewController or SLRequest
}