I want to post my status on twitter. I want to add an image, but I dont want a share dialogue.
Instead I'd like an interface like Instagram, where the user just selects twitter and presses 'share', so it's easy.
Here is my running code so far:
// Create an instance of the Tweet Sheet
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:
SLServiceTypeTwitter];
// Sets the completion handler. Note that we don't know which thread the
// block will be called on, so we need to ensure that any required UI
// updates occur on the main queue
tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) {
switch(result) {
// This means the user cancelled without sending the Tweet
case SLComposeViewControllerResultCancelled:
break;
// This means the user hit 'Send'
case SLComposeViewControllerResultDone:
break;
}
};
// Set the initial body of the Tweet
[tweetSheet setInitialText:#"Socia"];
// Adds an image to the Tweet. For demo purposes, assume we have an
// image named 'larry.png' that we wish to attach
if (![tweetSheet addImage:[UIImage imageNamed:#"icon120x120.png"]]) {
NSLog(#"Unable to add the image!");
}
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:#"http://stackoverflow.com/questions/ask?title="]]){
NSLog(#"Unable to add the URL!");
}
// Presents the Tweet Sheet to the user
[self presentViewController:tweetSheet animated:NO completion:^{
NSLog(#"Tweet sheet has been presented.");
}];
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
//use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
//create this request
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:#"https://api.twitter.com"#"/1.1/statuses/update_with_media.json"] parameters: [NSDictionary dictionaryWithObject:message forKey:#"status"]];
UIImage *imageToPost = [UIImage imageNamed:#"image.jpg"];
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0f);//set the compression quality
[postRequest addMultipartData:imageData withName:#"media" type:#"image/jpeg" filename:#"image.jpg"];
//set account and same as above code
....
....
The above is from this link and this code worked for me.
Here you can find how to post Twitter's updates with media here.
Related
We are not allowed to use native mail functionality for sending emails.
Hence our native iPad app integrated MSGraph SDK for sending mails along with an attachment. MSGraphSDK used to verify the work user by getting authentication credentials.
NSArray *scopes = [kScopes componentsSeparatedByString:#","];
[self.authProvider connectToGraphWithClientId:kClientId scopes:scopes completion:^(NSError *error) {
if (!error) {
NSLog(#"Authentication successful.");
[self sendMailWithAttachments];
}
}];
From next time onwards, it will directly send the mails without asking work credentials.
[MSGraphClient setAuthenticationProvider:self.authProvider.authProvider];
self.graphClient = [MSGraphClient client];
MSGraphMessage *message = [self getSampleMessage];
MSGraphUserSendMailRequestBuilder *requestBuilder = [[self.graphClient me]sendMailWithMessage:message saveToSentItems:true];
MSGraphUserSendMailRequest *mailRequest = [requestBuilder request];
[mailRequest executeWithCompletion:^(NSDictionary *response, NSError *error) {
if(!error){
}
}];
MSGraph SDK used to direct the authenticated page automatically if users are not authenticated or users authentication was not successful.
Now problem here is, users are trying to authenticate themselves and sending mails on first few times successfully. After that a month later or more, they trying to send the mails using this app. Unfortunately it does not respond anything.
Try Below Code:
NSString *titleEmail = #"Your title";
NSString *msgBody = #"PFA";
NSArray *toRecipents = [NSArray arrayWithObject:#"xyz#gmail.com"];
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData(pdfData, self.view.bounds, nil);
UIGraphicsBeginPDFPage();
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndPDFContext();
MFMailComposeViewController *mailComposeVC = [[MFMailComposeViewController alloc] init];
mailComposeVC.mailComposeDelegate = self;
[mailComposeVC setSubject:titleEmail];
[mailComposeVC setMessageBody:msgBody isHTML:NO];
[mailComposeVC addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"MY.pdf"];
[mailComposeVC setToRecipients:toRecipents];
[self presentViewController:mailComposeVC animated:YES completion:NULL];
I want to upload image to Twitter.
I wrote code as
- (void)postImage:(UIImage *)image withStatus:(NSString *)status
{
NSLog(#"Share on Twitter");
ACAccountType *twitterType =
[self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
SLRequestHandler requestHandler =
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData) {
NSInteger statusCode = urlResponse.statusCode;
if (statusCode >= 200 && statusCode < 300) {
NSDictionary *postResponseData =
[NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:NULL];
NSLog(#"[SUCCESS!] Created Tweet with ID: %#", postResponseData[#"id_str"]);
}
else {
NSLog(#"[ERROR] Server responded: status code %d %#", statusCode,
[NSHTTPURLResponse localizedStringForStatusCode:statusCode]);
}
}
else {
NSLog(#"[ERROR] An error occurred while posting: %#", [error localizedDescription]);
}
};
ACAccountStoreRequestAccessCompletionHandler accountStoreHandler =
^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:twitterType];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com"
#"/1.1/statuses/update_with_media.json"];
NSDictionary *params = #{#"status" : status};
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:url
parameters:params];
NSData *imageData = UIImageJPEGRepresentation(image, 1.f);
[request addMultipartData:imageData
withName:#"media[]"
type:#"image/jpeg"
filename:#"image.jpg"];
[request setAccount:[accounts lastObject]];
[request performRequestWithHandler:requestHandler];
}
else {
NSLog(#"[ERROR] An error occurred while asking for user authorization: %#",
[error localizedDescription]);
}
};
[self.accountStore requestAccessToAccountsWithType:twitterType
options:NULL
completion:accountStoreHandler];
}
I am getting error as
The operation couldn’t be completed. (com.apple.accounts error 6.)
You should use the SLComposeViewController class. In order to do this, a number of steps should be performed in sequence. Firstly, the application may optionally check to verify whether a message can be sent to the specified social network service. This essentially equates to checking if a valid social network account has been configured on the device and is achieved using the isAvailableForServiceType: class method, passing through as an argument the type of service required from the following options:
SLServiceTypeFacebook
SLServiceTypeTwitter
SLServiceTypeSinaWeibo
The following code, for example, verifies that Twitter service is available to the application:
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
// Device is able to send a Twitter message
}
This method call is optional and, in the event that an account for the specified social network has yet to be set up, the composer will simply take the user to the device’s Settings application where a Twitter account may be configured.
The next step is to create an instance of the SLComposeViewController class and supply an optional completion handler to be called when the composer screen is either cancelled by the user or used to send a message. Next, a range of methods may be called on the instance to initialize the object with the content of the message, including the initial text of the message, an image attachment and a URL:
setInitialText: - Sets the initial text of the message on the SLComposeViewController instance.
addImage: - Adds image files as attachments to the message.
addURL: - Adds a URL to the message. The method automatically handles the URL shortening.
Each of the above methods returns a Boolean result indicating whether the addition of content was successful.
Finally, when the message is ready to be presented to the user, the SLComposeViewController object is presented modally by calling the presentViewController: method of the parent view controller:
SLComposeViewController *composeController = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[composeController setInitialText:#"Just found this great website"];
[composeController addImage:postImage.image];
[composeController addURL: [NSURL URLWithString:
#"http://www.website.com"]];
[self presentViewController:composeController
animated:YES completion:nil];
Once called, this method will present the composer view to the user primed with any text, image and URL contents pre-configured via the method calls. Once displayed, the user has the option to modify the text of the message, cancel the message, add location data or send the message. If a completion handler has been configured it will be called and passed a value indicating the action that was taken by the user within the composer view. Possible values are:
SLComposeViewControllerResultCancelled – The user cancelled the composition session by touching the Cancel button.
SLComposeViewControllerResultDone – The user sent the composed message by touching the Send button.
I didn't have this problem with fb SDK 3.2, but after I upgraded it in SDK 3.5.1 friend inviter has some strange problem, when I select one friend it choose the selected one and the one under it. Also when I am trying to scroll downward it restarts the table and brings me back on the tables top.
Here is my method:
-(IBAction)secondClick:(id)sender
{
NSDictionary *params = [[NSDictionary alloc] initWithObjectsAndKeys:nil];
[FBWebDialogs
presentRequestsDialogModallyWithSession:nil
message:#"Learn how to make your iOS apps social."
title:#"Test"
parameters:params
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// Error launching the dialog or sending the request.
NSLog(#"Error sending request.");
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User clicked the "x" icon
NSLog(#"User canceled request.");
} else {
// Handle the send request callback
NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
if (![urlParams valueForKey:#"request"]) {
// User clicked the Cancel button
NSLog(#"User canceled request.");
} else {
// User clicked the Send button
NSString *requestID = [urlParams valueForKey:#"request"];
NSLog(#"Request ID: %#", requestID);
}
}
}
}];
From what i have come to know is that facebook has fixed this issue and is going to make the fix live soon.
An alternate solution to this is to make your own custom UI.
1. Get Friends List - [self startConnectionWithGraphPath:#"me/friends" parameters:params method:#"GET" completionSelector:#selector(callback)]
Download pictures using url #"https://graph.facebook.com/fbid/picture"
Implement a table view similar to facebook's request ui showing list of friends along with their profile pics.
Use 'to' param to direct the request to the selected user(s). NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: #"286400088", #"to", nil];
This way you won't need to show facebook ui to select friends. Al though the UI will still appear after user selects friends from your custom UI, but that'd be just to tap 'send'.
One way is to use the Facebook friendPicker
https://developers.facebook.com/ios/friendpicker-ui-control/
And then take the facebook id's result of that and put them into the requestdialog just like Nitin said.
I'll post my friendPicker code:
- (IBAction)inviteFriendsClicked:(id)sender {
// Initialize the friend picker
FBFriendPickerViewController *friendPickerController =
[[FBFriendPickerViewController alloc] init];
// Set the friend picker title
friendPickerController.title = #"Välj vänner";
// TODO: Set up the delegate to handle picker callbacks, ex: Done/Cancel button
// Load the friend data
[friendPickerController loadData];
// Show the picker modally
[friendPickerController presentModallyFromViewController:self
animated:YES
handler:
^(FBViewController *sender, BOOL donePressed) {
if(donePressed) {
NSString *userString;
userString = #"";
int *counter = 0;
for (id<FBGraphUser> user in friendPickerController.selection) {
NSLog(user.id);
NSMutableArray *userArray = [[NSMutableArray alloc] init];
[userArray addObject:user.id];
if(counter == 0){
userString = user.id;
}else{
userString = [NSString stringWithFormat:#"%#%#%#", userString, #",", user.id];
}
counter++;
}
if(counter != 0){
[self requestDialog: userString]; // Display the requests dialog and send the id-string with it
}
// NSLog(#"Selected friends: %#", friendPickerController.selection);
}
}];
}
I'm trying to share using Twitter Framework on iOS 5
The user will select which account to use, so the app will share using the account selected.
But whem share pass to performRequestWithHandler nothing happen an the error return null
My code:
for (int i = 0; i < [_accountsArray count]; i++) {
//searching for a selected account
if ([[[_accountsArray objectAtIndex:i] username] isEqualToString:[self getUserName]]) {
actualUser = [_accountsArray objectAtIndex:i];
TWRequest *sendTweet = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"]
parameters:nil
requestMethod:TWRequestMethodPOST];
[sendTweet addMultiPartData:[text dataUsingEncoding:NSUTF8StringEncoding] withName:#"status" type:#"multipart/form-data"];
ACAccountStore *account = [[ACAccountStore alloc] init];
[sendTweet setAccount:[account.accounts objectAtIndex:i]];
NSLog(#"%#",sendTweet.account);
[sendTweet performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"responseData: %#\n", responseData);
NSLog(#"urlResponse: %#\n", urlResponse);
NSLog(#"error: %#",error);
}];
}
}
anyone can help me?
Thanks
Sending tweets in iOS is extremely easy now. Last night I updated my app to no longer use the old technique and instead use the new SLComposeViewController technique. Below is a snippet of code I have in my application that allows the user send a tweet with the attached image. Basically the exact same code can be used to post to facebook. Try using this code instead. It should also allow the user to choose what account they send the tweet from (I also believe this "default account" sending setting is buried in the settings of the phone someplace).
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[mySLComposerSheet setInitialText:#"Sample Tweet Text"];
//Add the image the user is working with
[mySLComposerSheet addImage:self.workingImage];
//Add a URL if desired
//[mySLComposerSheet addURL:[NSURL URLWithString:#"http://google.com"]];
//Pop up the post to the user so they can edit and submit
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
//Handle the event
[mySLComposerSheet setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
case SLComposeViewControllerResultCancelled:
NSLog(#"Tweet Canceled");
case SLComposeViewControllerResultDone:
NSLog(#"Tweet Done");
break;
default:
break;
}
}];
} else {
//Can't send tweets, show error
NSLog(#"User doesn't have twitter setup");
}
Once a user has tweeted something, I need to differentiate which twitter account he used. Lets consider that the user would have 1 or several accounts configured on the phone.
I need tho know this after the tweet is successful, so the proper place would be the callback. I tried to fetch the accounts using ACAccountStore but it provides an array with all the accounts set up on the phone, not a clue about the last account used (not even the order of the array).
Does anyone knows if TWTweetComposeViewController remembers this account and, how to fetch it?
Thanks
My code:
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:#"initial text"];
[tweetSheet addImage:[UIImage imageNamed:image]];
// Callback
tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {
// if tweet was successful
if(result == TWTweetComposeViewControllerResultDone) {
// Get the accounts
account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
// if access granted I populate the array
if (granted == YES) {
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
ACAccount *account1 = [arrayOfAccounts objectAtIndex:0];
ACAccount *account2 = [arrayOfAccounts objectAtIndex:1];
NSString *username1 = account1.username;
NSString *username2 = account2.username;
// Always same order
NSLog(userName1);
NSLog(userName2);
}
}];
[self furtherMethodsInCaseOfSuccessfulTweet];
} else if(result == TWTweetComposeViewControllerResultCancelled) {
NSLog(#"twit canceled");
}
[self dismissViewControllerAnimated:YES completion:nil];
};
[self presentModalViewController:tweetSheet animated:YES];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"No tweet is possible on this device" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
}
I found a way.
Instead looking for the username on the insctance of TWTweetComposeViewController , lets use GET users/lookup to qwery the names gathered by ACAccountStore.
http://api.twitter.com/1/users/lookup.xml?screen_name=username1,username2
(use json instead xml)
Parsing the results we can get the date/time of the last tweet of the users ("status" tag), and voila, we have the last account used.
In additiom, you can test the qwery results on the console.
Thanks to #theSeanCook