I am using the following code for twitter sharing. Here i am checking if twitter native app installed in the device then i am opening the native app otherwise i am opening the webView for twitter sharing. Using the following code i am able to do twitter sharing, But the problem is After successful sharing the call back is not coming to my app, It is going to twitter app.
NSURL *instagramURL = [NSURL URLWithString:#"twitter://post?message=hello%20world"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
} else {
// Share this on Twitter
GenericWebViewController *gwvController=[[GenericWebViewController alloc] init];
[gwvController loadWithUrl:[NSURL URLWithString:#"https://twitter.com/intent/tweet?url=www.google.com&text=I%20am%20eating%20branston%20pickel%20right%20now&original_referer=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F9127808%2Fhow-do-you-include-hashtags-within-twitter-share-link-text"] navBarTitle:#"Twitter"];
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[self.navigationController pushViewController:gwvController animated:YES];
//WI-542:Showing the navigation bar in WebView when user user navigate from deal details.
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
How can i come back to my app after successful sharing.
You can not! Once you launch an external application, you can not go back to your application, unless the external application is specifically done this way (using a "callback" arg for instance), but very few "big name" (twitter, facebook,...) works this way
If you want to use Twitter and still don't exit from your app, use the Twitter frame work (https://developer.apple.com/library/ios/documentation/Twitter/Reference/TwitterFrameworkReference/_index.html )
It's a little bit more complex, but you'll gain the benefit of remaining in your app.
Related
I have recently build an app, but the last step is to post the data to Runkeeper website. My app have the view controller, it has the button to login and deauthorize. But when I using Oauth2 by open the safari to login the account for my app. When come back from the safari and reopen my app. I don't know how to check if I have got the authorization code. And also I want to exchange the access token to post my data to the Runkeeper website. But I am totally new to connect the app with API. I have see a lot of tutorial about the google API , youtube API, but the they are different with Runkeeper. This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"View did Load!");
kIDMOAuth2ClientId = #"....";
kIDMOAuth2ClientSecret = #"....";
kIDMOAuth2AuthorizationURL = #"https://runkeeper.com/apps/authorize";
kIDMOAuth2TokenURL = #"https://runkeeper.com/apps/token";
kIDMOAuth2AccountType = #"token";//authorization_code //Runkeeper API
kIDMOAuth2SuccessPagePrefix = #"Success";
kIDMOAuth2RedirectURL = #"Landice://";
kIDMOAuth2DeauthorizationURL = #"https://runkeeper.com/apps/de-authorize";
runkeeperButton *runkeeperString=[runkeeperButton getInstance];
NSLog(#"%#", runkeeperString.str);
if ((runkeeperString.str == NULL) || [runkeeperString.str isEqualToString:#"Authorize"]) {
buttonToggled = YES;
[loginandoutButton setTitle:#"Login & Authorize" forState:UIControlStateNormal];
NSLog(#"66666");
NSLog(#"%#", runkeeperString.str);
}else if ([runkeeperString.str isEqual:#"Deauthorize"]){
buttonToggled = NO;
[loginandoutButton setTitle:#"Deauthorize" forState:UIControlStateNormal];
NSLog(#"77777");
NSLog(#"%#", runkeeperString.str);
}
loginandoutButton.layer.cornerRadius = 10;
}
- (IBAction)toggleButton:(id)sender {
runkeeperButton *runkeeperString=[runkeeperButton getInstance];
// "Deauthorize" button clicked
if (!buttonToggled) {
[sender setTitle:#"Login & Authorize" forState:UIControlStateNormal];
buttonToggled = YES;
runkeeperString.str = #"Authorize";
}
// "Login & Authorize" button clicked
else {
[sender setTitle:#"Deauthorize" forState:UIControlStateNormal];
buttonToggled = NO;
runkeeperString.str = #"Deauthorize";
//[self requestOAuth2Access];
NSURL *url = [NSURL URLWithString:#"https://runkeeper.com/apps/authorize?response_type=code&client_id=[SOMETHING]&redirect_uri=landice://response&duration=permanent&scope=read"];
[[UIApplication sharedApplication] openURL:url];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
else if (![[UIApplication sharedApplication] canOpenURL:url]) {
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
}
}
My question is:
1. how to get the authorization code from safari and how to check if I have got it.
2. I heard that authorization code is not stable, so how to exchange the access token and how to check the access token is expired. If expired, how to get another one.
3. how to post data from core data by JSON to the Runkeeper website.
Thanks in Advance.
Do you have to open the site in Safari? I'm not sure it is even possible to get data back from another app like this, especially if it's not in an app group you define yourself (and you can only put your own apps into such a group). Basically Safari is sandboxed, just like your app. I don't see how the data that is loaded from a page can be given back to your app.
Instead, I would advice you to design your own small browser window in your app for this purpose, using WKWebView. Then you can skip the [[UIApplication sharedApplication] openURL:url] and instead open another view that loads the Runkeeper page. From there you should be able to access the data by evaluating java script (or inject your own script for this). I don't know Runkeeper myself, so I don't know how exactly you would do that, but I'm sure there is a way somehow.
This is more work, but would have the benefit that your users don't have to switch apps for the authorization.
Oh, and all this assumes you definitely have to load a page and can't use some API that Runkeeper provides. Maybe you could also just use an NSURLSessionDataTask to call the authorization and simply get the token from the NSHTTPURLResponse object on its return?
I would like to provide the option to share a picture to Facebook. When I have the FB app installed, I have no problem posting to my feed. However, when no app is installed, I get the following error:
-canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
Facebook says in the docs I don't need to do anything:
Now the SDK automatically checks for the native Facebook app. If it isn't installed, the SDK switches people to their default browser and opens the Feed Dialog. If someone wants to share an Open Graph story, the SDK opens the Web Share Dialog.
One hack I found to check is the following:
BOOL isInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"fbauth2:/"]];
if (isInstalled) {....}
Is there a better more 'correct' way?
The method I use to share that throws the error is the following:
- (void)showFBShare {
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
photo.image = self.shareImage;
photo.userGenerated = YES;
FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init];
content.photos = #[photo];
[FBSDKShareDialog showFromViewController:self
withContent:content
delegate:nil];
}
tl;dr: Instantiate and configure FBSDKShareDialog as dialog and set dialog.mode = FBSDKShareDialogModeNative or FBSDKShareDialogModeShareSheet. if [dialog canShow] then [dialog show].
FBSDK version used for testing solution:
- FBSDKCoreKit (4.12.0):
- FBSDKShareKit (4.12.0):
It does not seem like the method throws any exceptions when calling the showFromViewController method so a try / catch fix is ruled out. However if you instantiate the FBSDKShareDialog you can call the canShow method to check if the app is able to show the dialog in its current mode (in this case FBSDKShareDialogModeShareSheet).
Method description from source (FBSDKSharing.h:64):
#abstract A Boolean value that indicates whether the receiver can initiate a share.
#discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
required but not available. This method does not validate the content on the receiver, so this can be checked before
building up the content.
#see [FBSDKSharing validateWithError:]
#result YES if the receiver can share, otherwise NO.
- (BOOL)canShow;
Code example:
...
FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
dialog.fromViewController = self;
dialog.shareContent = content;
/**
* !important: Only mode FBSDKShareDialogModeNative and
* FBSDKShareDialogModeShareSheet do the appropriate checks.
* Otherwise canShow returns yes regardless.
*/
dialog.mode = FBSDKShareDialogModeShareSheet;
if ([dialog canShow]) {
[dialog show];
} else {
// handle exception case.
}
Issues when running on the simulator (from the docs):
iOS Simulator and Testing
If you are using Simulator to test sharing in your application, you will see errors if you try to share videos, Photos or Open Graph Actions. This is because you need Facebook for iOS installed which provides the Share Dialog. We do not support this for Simulator.
In the case of link shares, you do not need Facebook for iOS installed so this test case is possible. To test other Sharing scenarios, set up an actual test device with with Facebook for iOS installed.
As mentioned above, only link content is supported on the simulator. I.e.:
FBSDKShareLinkContent *linkContent = [[FBSDKShareLinkContent alloc] init];
linkContent.contentURL = [NSURL URLWithString:#"somelink"];
linkContent.quote = #"Very interesting, shareworthy link.";
[FBSDKShareDialog showFromViewController:self
withContent:linkContent
delegate:nil];
My iOS is 8.1.2 and I am using the UIActivityViewController for social sharing.
I click on a button and allow the UIActivityViewController to present
- (IBAction)UIActivityTypeButtonClick:(id)sender {
NSString* text=#"I am sharing this text";
NSArray* sharedArray=#[text];
UIActivityViewController * activityVC=[[UIActivityViewController alloc]initWithActivityItems:sharedArray applicationActivities:nil];
activityVC.excludedActivityTypes=#[];
[self presentViewController:activityVC animated:YES completion:nil];
}
I am getting this
I am getting Message, Twitter, Mail, WhatsApp and a More button.
On clicking More I get this.
Where is FACEBOOK. I have the facebook app in my iPhone and it is setup with my ID too in settings. But facebook never shows up here. Twitter does. Is this a bug or what? Please suggest
Thanks
I first saw this when Facebook updated their app on April 24th. Plain text sharing to Facebook isn't working as long as the Facebook app is installed. After you delete it, it's available again.
If you try to share a URL or an image together with the plain text, you will see Facebook as an option but the text field will be blank. The image or URL will attach without a problem.
I posted a sample project that reproduces this problem on github:
https://github.com/djr/UIActivityViewController-Facebook
This is not an answer, but it's pretty clear that the problem is caused by the Facebook app.
EDIT:
It's not ideal, but I created a workaround. Don't forget that you will need to attach an image or a URL for this to work.
Detect if the user has the Facebook app installed. If they do, then give them some type of informational message.
BOOL facebookIsInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"fb://"]];
BOOL isUserLoggedInWithFacebook = [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook];
if(isUserLoggedInWithFacebook && facebookIsInstalled)
{
// Explain that they have to copy and paste in order to share on Facebook
}
Create a subclass of UIActivityItemProvider and override
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
NSString *stringToShare = #"string to share";
if([activityType isEqualToString:UIActivityTypePostToFacebook] ||
[activityType isEqualToString:#"com.facebook.Facebook.ShareExtension"] ||
[activityType.lowercaseString rangeOfString:#"facebook"].length)
// Because who knows when they are going to change the activityType string?
{
// Automatically copy the text for them
[[UIPasteboard generalPasteboard] setString:stringToShare];
}
return stringToShare;
}
Tell the user that they have to paste into the Facebook text field in order to share.
Blame it on Facebook.
I confirm what djr reported - if you have the FB app text is no longer shared. I deleted the FB app and now sharing both text and image works.
Facebook would like you to use their SDK. They have blocked the ability to set initial text. (Not sure how.) Check out my answer in a similar post:
UIActivityViewController for Facebook not Showing Default Text
The desired solution (from Facebook) is to use their SDK.
NSString* text=#"I am sharing this text";
NSURL *myWebsite = [NSURL URLWithString:#"http://www.website.com/"];
// UIImage * myImage =[UIImage imageNamed:#"myImage.png"];
NSArray* sharedArray=#[text,myWebsite];
UIActivityViewController * activityVC=[[UIActivityViewController alloc]initWithActivityItems:sharedArray applicationActivities:nil];
NSArray *excludedActivities = #[];
activityVC.excludedActivityTypes=excludedActivities;
[self presentViewController:activityVC animated:YES completion:nil];
To show facebook sharing button you must add a image to the array of activity items... this may be a bug on apple side but i've not seen any open radar about this issue.
Also note on iOS 8.3 text can't be added to facebook for some reason. when adding text you only be presented to a blank textfield.
UIImage *image = [UIImage imageNamed:#"__some_image__file"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[image]
applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
Hi I am trying to share video using UIActivityViewController but it is not showing Email option. It is showing Facebook and Message option. But in native Photos app it is showing Email share option on same video. So please could anyone tell me why it is not showing Email option in my App. Here is my code:
NSURL* url=[NSURL URLWithString:#"asset url here"];
[self shareItems:[NSMutableArray arrayWithObjects:url,nil]];
- (IBAction)shareItems:(NSMutableArray*)shareItems {
UIActivityViewController *shareController =
[[UIActivityViewController alloc]
// actual items are prepared by UIActivityItemSource protocol methods below
initWithActivityItems: shareItems
applicationActivities :nil];
[self presentViewController: shareController animated: YES completion: nil];
}
The same code is working fine (Shows Email option) if Asset Url is of an image. Problem is in case of Video. I have tried on iPhone5 with iOS7.
I'm developing a PhoneGap Build application, but needed a way to prompt my user to open local files in Adobe Reader (inAppBrowser will not work for my situation). I found a 3rd party plugin for PhoneGap that does what I need. However it only does it for remote .pdf files. I have figured out how to alter the plugin code to work with local files on the iPad/iPhone but it seems to close my application when the user opens the pdf in Adobe Reader.
I know almost nothing about objective C, Xcode, etc.
Desired functionality is:
User navigates my app searching or browsing for files
Finds desired file
Selects file
User is presented with "open with" options of which one is Adobe reader
User selects Adobe, PDF opens
User returns to my app in location they left it
I have it all working except on step #6 above my app seems to be closed. If I press the home button twice app show up at the bottom of iPad but when selected app starts from closed state showing splash screen. I'd like it to be where the user left it.
I believe the relevant code is
NSURL *fileURL = [NSURL fileURLWithPath:localFile];
UIDocumentInteractionController *controller = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
[controller retain];
controller.delegate = self;
controller.UTI = uti;
CDVViewController* cont = (CDVViewController*)[ super viewController ];
//CGRect rect = CGRectMake(0, 0, cont.view.bounds.size.width, cont.view.bounds.size.height);
CGRect rect = CGRectMake(0, 0, 1024, 768);
[controller presentOpenInMenuFromRect:rect inView:cont.view animated:YES];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: #""];
[self writeJavascript: [pluginResult toSuccessCallbackString:callbackID]];
[callbackID release];
[path release];
[uti release];
Where this line
[controller presentOpenInMenuFromRect:rect inView:cont.view animated:YES];
prompts the user to select Adobe. Is there a parameter I can pass here to not have my application shut down once the user selects to open the pdf in Adobe?
Thanks!
The plugin I have altered in its original state can be found and discussed here:
http://www.tricedesigns.com/2012/08/15/open-with-in-ios-phonegap-apps/