I am trying to open facebook app via AppLinks url , it opens user profile/page but does not show button "back to referer app" , I am providing "referer_app_link" data ,
I have generated JSON by this reference http://applinks.org/documentation/#applinknavigationprotocol
NSDictionary *dict = #{
#"target_url" : #"fb://profile/USER_ID",
#"referer_app_link" : #{
#"target_url" : #"MY WEBSITE",
#"url" : #"CALLBACK URL",
#"app_name" : #"MY APP NAME",
#"app_store_id" : #"MY APP STORE ID"
}
};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
jsonString = [jsonString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *stringUrl = [NSString stringWithFormat:#"fb://applinks?al_applink_data=%#",jsonString];
NSLog(#"String url is %#",stringUrl);
NSURL *url = [NSURL URLWithString:stringUrl];
if([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
} else {
NSLog(#"Cant open %#",url);
}
any ideas ? is Facebook supposed to have "back button" at all ?
my url scheme is set up correctly ...
Update:
NSDictionary contains all valid values , I dont want to publish them at the moment , but url , name , store id ... etc all are valid
Update #2:
Since iOS 9 , this is done by iOS System automatically.
applink is not wired into the FB friend profile page if you simply use the FB Custom URL to link into FB.APP or to safari it will not go back to your app automatically.
The alternative to this is to use the FB IOS SDK and Pick and display the remote user within your app as follows: (code from HelloFacebook sample app (comes with the SDK)
- (IBAction)pickFriendsClick:(UIButton *)sender {
FBFriendPickerViewController *friendPickerController = [[FBFriendPickerViewController alloc] init];
friendPickerController.title = #"Pick Friends";
[friendPickerController loadData];
// Use the modal wrapper method to display the picker.
[friendPickerController presentModallyFromViewController:self animated:YES handler:
^(FBViewController *innerSender, BOOL donePressed) {
if (!donePressed) {
return;
}
NSString *message;
if (friendPickerController.selection.count == 0) {
message = #"<No Friends Selected>";
} else {
NSMutableString *text = [[NSMutableString alloc] init];
// we pick up the users from the selection, and create a string that we use to update the text view
// at the bottom of the display; note that self.selection is a property inherited from our base class
for (id<FBGraphUser> user in friendPickerController.selection) {
if ([text length]) {
[text appendString:#", "];
}
[text appendString:user.name];
}
message = text;
}
[[[UIAlertView alloc] initWithTitle:#"You Picked:"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]
show];
}];
}
Note - the sample currently just picked the name property from the FBGraphUser Class instance ....
user will have other properties birthday, sex etc, just lookup header file within the SDK or look up FB documentation.
Related
I am working on google maps integration I am trying to display google navigation at present I am using the following code. I am trying to display like google navigation based on location what I pass through the api
NSURL *url=[[NSURL alloc] initWithString:[NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&alternateroutes=false&sensor=true" ,12.920631,77.670494,8.3075,77.2218]];
NSURLResponse *res;
NSError *err;NSURL *url=[[NSURL alloc] initWithString:[NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&alternateroutes=false&sensor=true" ,12.920631,77.670494,8.3075,77.2218]];
NSURLResponse *res;
NSError *err;
NSData *data=[NSURLConnection sendSynchronousRequest:[[NSURLRequest alloc] initWithURL:url] returningResponse:&res error:&err];
if(data)
{
NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if(dic)
{
NSArray *routes=dic[#"routes"];
NSArray *legs=routes[0][#"legs"];
NSArray *steps=legs[0][#"steps"];
NSLog(#"the legs are:%#",steps);
NSMutableArray *textsteps=[[NSMutableArray alloc] init];
NSMutableArray *latlong=[[NSMutableArray alloc]init];
for(int i=0; i< [steps count]; i++){
NSString *html=steps[i][#"html_instructions"];
[latlong addObject:steps[i][#"end_location"]];
NSLog(#"the data:%#",steps[i][#"end_location"]);
[textsteps addObject:html];
encodedPath = [[[steps objectAtIndex:i] valueForKey:#"polyline"] valueForKey:#"points"];
[self polylineWithEncodedString:encodedPath];
polyline.strokeColor = [UIColor redColor];
polyline.strokeWidth = 2.f;
polyline.map = mapView;
NSLog(#"the encoded patg:%#",encodedPath);
GMSMarker *marker1 = [[GMSMarker alloc]init];
marker1.map = mapView;
NSLog(#"Direction path");
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"" message:#"Connection Error" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"", nil];
[alert show];
}
I am expecting an output like
You want to show same direction, time and everything as Google Maps do. Google Maps SDK of iOS will draw a path for you on maps.
You can use the Google Direction API to get and request for direction between source and destination. You can use GMSPolyline to draw it.
But other things, like where to take a turn, whats time is left to reach the destination and other things, you need to manage manually. If you want to show same as Google, you need to make URL and open in WebView.
You can see URLSchema documentation for more detail.
Hoping you are expecting like this code
if ([[UIApplication sharedApplication] canOpenURL:
[NSURL URLWithString:#"comgooglemaps://"]]) {
[[UIApplication sharedApplication] openURL:
[NSURL URLWithString:#"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic"]];
} else {
NSLog(#"Can't use comgooglemaps://");
}
I am having some trouble in sharing videos with airdrop. So, i am using the AssetLibrary like this :
else if (conformsToVideo) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Asset Loaded" message:#"Video One Loaded"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
self.mediaAsset = [AVAsset assetWithURL:[info objectForKey:UIImagePickerControllerMediaURL]];
UIActivityViewController * controller = [[UIActivityViewController alloc] initWithActivityItems:#[self.mediaAsset] applicationActivities:nil];
[self presentViewController:controller animated:YES completion:nil];
}
Maybe this is just not the way to do it, I don't know and I didn't find any tutorial about it so if you have one, I will gladly take it.
Now my problem is that when i select a video everything works fine until the UIActivityViewController pops out , i don't have any error but I can't use airdrop (nor any other service BTW) the only thing I can do is press the Cancel button of the UIAVController.
I am using iOS 8.3.
Thanks for your help
Ok, eventually I found an answer, maybe not the best but I put it there in case it helps someone cause I didn't find much on sharing video with airdrop :
NSURL * path = [info objectForKey:UIImagePickerControllerReferenceURL];
BOOL conformsToVideo = (UTTypeConformsTo((__bridge_retained CFStringRef) mediaType, kUTTypeAudiovisualContent));
if (conformsToVideo) {
[self.library assetForURL:path
resultBlock:^(ALAsset *asset) {
ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
NSString* outputDirectory = [NSString stringWithFormat:#"%#", NSTemporaryDirectory()];
NSString* pathToCopy = [outputDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", assetRepresentation.filename]];
NSUInteger size = (NSUInteger)assetRepresentation.size;
NSMutableData* data = [NSMutableData dataWithLength:size];
NSUInteger bytesRead = [assetRepresentation getBytes:data.mutableBytes fromOffset:0 length:size error:nil];
NSURL * url = nil;
if ([data writeToFile:pathToCopy atomically:YES])
{
NSLog(#"Ok");
url = [NSURL fileURLWithPath:pathToCopy];
UIActivityViewController * controller = [[UIActivityViewController alloc] initWithActivityItems:#[url] applicationActivities:nil];
[self presentViewController:controller animated:YES completion:nil];
}
} failureBlock:^(NSError *error) {
NSLog(#"Failure to use the ALAsset");
}
];
}
I found the solution using this question : Share a video from asset library with AirDrop fails
I am merely adding the previous steps to the code given there, hope it can be useful.
I tried to integrate Facebook/Google+ in my app. I can do that by the inbuilt Facebook framework, Google Plus framework, Google open source framework, in iOS app by getting the details from the account added in settings app of the device. I can also do it by opening the Safari browser and redirect to my app after login to Facebook and Goolge+. so, I need without redirect the Safari browser.
Using new Google+ SDK, user will not have to reenter the password in safari or any browser.
Take a look on this:
https://developers.google.com/+/mobile/ios/sign-in
If the user has the native Google or Google+ mobile app installed then user will not have to re-enter their Google credentials to authorize your app.
OR
Try with GTMOAuth2ViewControllerTouch
- (id)initWithScope:(NSString *)scope
clientID:(NSString *)clientID
clientSecret:(NSString *)clientSecret
keychainItemName:(NSString *)keychainItemName
completionHandler:(GTMOAuth2ViewControllerCompletionHandler)handler
Plenty of references available online.
Google Drive iOS SDK: Display Cancel Login Button
Don't use Google-Plus, use GoogleSignIn.
Google just posted this solution:
Comment #109 on issue 900 by fa...#google.com: iOS SDK SignIn don't
leave app [Apple appstore rejection]
https://code.google.com/p/google-plus-platform/issues/detail?id=900
Hello everyone,
I’m delighted to announce an update to this issue. Today, we launched
version 2.0 of Google Sign In, featuring full built-in support for
Sign In via WebView. We hope that this update will at last remedy the
problem of App Store rejections due to use of our SDK.
Full documentation is here:
https://developers.google.com/identity/sign-in/ios
We’ve written a migration guide from G+ Sign In here:
https://developers.google.com/identity/sign-in/ios/quick-migration-guide
You can use the below code to sign in via Google+ using Webview:
Initialize UIWebview:
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%#&redirect_uri=%#&scope=%#",client_id,callbakc,scope];
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[webView setDelegate:self];
[self.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
Implementation of delegate methods:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
// [indicator startAnimating];
if ([[[request URL] host] isEqualToString:#"localhost"]) {
// Extract oauth_verifier from URL query
NSString* verifier = nil;
NSArray* urlParams = [[[request URL] query] componentsSeparatedByString:#"&"];
for (NSString* param in urlParams) {
NSArray* keyValue = [param componentsSeparatedByString:#"="];
NSString* key = [keyValue objectAtIndex:0];
if ([key isEqualToString:#"code"]) {
verifier = [keyValue objectAtIndex:1];
break;
}
}
if (verifier) {
NSString *authToken = [NSString stringWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&grant_type=authorization_code", verifier,client_id,secret,callbakc];
//Use Token to Login
} else {
// ERROR!
}
[webView removeFromSuperview];
webView = nil;
return NO;
}
return YES;
}
Use Scocial.framework
https://developer.apple.com/library/ios/documentation/Social/Reference/Social_Framework/
__block ACAccount * facebookAccount;
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
NSDictionary *emailReadPermisson = #{
ACFacebookAppIdKey : #"YOUR_API_KEY",
ACFacebookPermissionsKey : #[#"email"],
ACFacebookAudienceKey : ACFacebookAudienceEveryone,
};
NSDictionary *publishWritePermisson = #{
ACFacebookAppIdKey : #"YOUR_API_KEY",
ACFacebookPermissionsKey : #[#"publish_actions"],
ACFacebookAudienceKey : ACFacebookAudienceEveryone
};
ACAccountType *facebookAccountType = [accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
//Request for Read permission
[accountStore requestAccessToAccountsWithType:facebookAccountType options:emailReadPermisson completion:^(BOOL granted, NSError *error) {if(granted){ // Enter your code}];
I am new to UIActivityViewController and perhaps I am missing a basic understanding. What I am trying to do is attached a csv, xml and vcard file to activity controller and show dropbox, google drive etc options. I have downloaded and installed dropbox, google drive etc apps on my iPhone.
Now when I launch UIActivityViewController all I see are default message and email app in my acitivity controller. How can I have other apps show up on their too? Do I need to install each and every apps individual SDKs and somehow incorporate them in my app?
This is what I wold like to see
but this is what I see instead.
Here's the code that I have tried so far
-(IBAction) dropBoxAction
{
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask ,YES);
NSString* documentsPath = [paths objectAtIndex:0];
//CSV
NSMutableString *fileNameStr = [NSMutableString stringWithFormat:#"test_CSV_Backup.csv"];
NSString* csvDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr];
NSData *csvData = [NSData dataWithContentsOfFile:csvDataFileStr];
//EXCEL
NSMutableString *fileNameStr2 = [NSMutableString stringWithFormat:#"test_EXCEL_Backup.xml"];
NSString* excelDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr2];
NSData *excelData = [NSData dataWithContentsOfFile:excelDataFileStr];
//VCARD
NSMutableString *fileNameStr3 = [NSMutableString stringWithFormat:#"test_VCARD_Backup.vcf"];
NSString* vcardDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr3];
NSData *vcardData = [NSData dataWithContentsOfFile:vcardDataFileStr];
//adding them all together
NSMutableArray *sharingItems = [NSMutableArray new];
[sharingItems addObject:csvData];
[sharingItems addObject:excelData];
[sharingItems addObject:vcardData];
UIActivity *activity = [[UIActivity alloc] init];
NSArray *applicationActivities = #[activity];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:applicationActivities];
[self presentViewController:activityController animated:YES completion:nil];
}
As #rmaddy said, you should use UIDocumentInteractionController to replace UIActivityViewController, just like this:
UIDocumentInteractionController *dc = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileNameStr]];
[dc presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES];
For anyone interested in future, here's the code all in one place. Do rate it up if this helps.
In your *.h file add this
#interface v1BackupComplete : UIViewController <UIDocumentInteractionControllerDelegate>
{
UIDocumentInteractionController *docController;
}
In your *.m file add this
/************************
* Dropbox ACTION
************************/
-(IBAction) dropBoxAction2
{
NSLog(#"dropBoxAction2 ...");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask ,YES);
NSString* documentsPath = [paths objectAtIndex:0];
NSMutableString *fileNameStr3 = [NSMutableString stringWithFormat:#"test_VCARD_Backup.vcf"];
NSString* vcardDataFileStr = [documentsPath stringByAppendingPathComponent:fileNameStr3];
NSURL *fileURL = [NSURL fileURLWithPath:vcardDataFileStr];
docController = [self setupControllerWithURL:fileURL
usingDelegate:self];
bool didShow = [docController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];
NSLog(#"didShow %d ...", didShow);
if (!didShow)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ERROR"
message:#"Sorry. The appropriate apps are not found on this device."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
}
#pragma mark - UIDocumentInteractionControllerDelegate
- (UIDocumentInteractionController *) setupControllerWithURL:(NSURL *)fileURL
usingDelegate:(id <UIDocumentInteractionControllerDelegate>) interactionDelegate {
UIDocumentInteractionController *interactionController =
[UIDocumentInteractionController interactionControllerWithURL:fileURL];
interactionController.delegate = interactionDelegate;
return interactionController;
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
UIActivityViewController only shows standard built-in activities plus any custom activities you pass as applicationActivities.
For what you are doing, you don't want UIActivityViewController. You want a UIDocumentInteractionController. If you just want to display existing apps that can open the file, use one of the presentOpenInMenuFrom... methods.
But note that is to be used for just a single file, not three.
Passing three files makes no sense in this context.
I have used your code here to open with dropbox and only after I have used presentPreview method (bellow) It was worked for me.
The pdf was shown as preview and then on the preview share button click (top right) the dropbox option ("open in dropbox") did the job. As it works in the mail app in the attachment preview.
[interactionController presentPreviewAnimated:YES];
When i tried to open with presentOpenInMenuFromRect it was crashed on selecting "open in dropbox".
I would like to post a feed on facebook by using fallback share. It should contain an image and a message. I have tried soo much by changing the params
NSMutableDictionary *postParams =
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"http://www.abc.com",#"link",
self.produtObj.productImageURL, #"picture",
self.produtObj.productName, #"name",
self.produtObj.productDescription, #"message",
nil];
[FBRequestConnection
startWithGraphPath:#"me/feed"
parameters:postParams
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSString *alertText;
if (error) {
alertText = [NSString stringWithFormat:
#"error: domain = %#, code = %d",
error.domain, error.code];
} else {
alertText = [NSString stringWithFormat:
#"Posted action, id: %#",
[result objectForKey:#"id"]];
}
// Show the result in an alert
[[[UIAlertView alloc] initWithTitle:#"Result"
message:alertText
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil]
show];
}];
With this code, the feed is displayed in a box and clicking on it is taking me to the link spcified. I just want to have an image thumbnail with the story for it not inside the box. Please help me. This is my first question in SOF. So please forgive me for my mistakes.
Thanks in advance. :)
I really prefer to use the UIActivityItemViewConroller for pushing stuff up to facebook.
The user needs to be logged into facebook on their device. You can do that through settings in the Facebook section.
I make the new controller like this for my stuff:
NSMutableArray *stuff = [[NSMutableArray alloc]init];
NSString *textstring = #"Now is the time for all good men to come to the aid of their country. Lorum Ipsum etc";
UIImage *pic = [UIImage imageNamed:#"Icon-Small-50"];//A local image
NSString *URL = #"http://nwc.co/images/nwc-icon-200.gif";//A link to an image
[stuff addObject:textstring];
[stuff addObject:pic];
[stuff addObject:URL];
UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:stuff applicationActivities:nil];
[self.navigationController presentViewController:vc animated:YES completion:^{
//do something here when they are done
}];
If you run the above, you'll notice that the text, the local image, and a link to the online image all appear on the post.
And you can exclude other activities, if you don't want to confuse people when the activity icons pop up:
vc.excludedActivityTypes = #[UIActivityTypePrint, UIActivityTypePostToTwitter, UIActivityTypePostToWeibo, UIActivityTypeMail, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll];