I've to integrated the FB SDK 3.1 in my ios application.
I successfully share an image on my wall, but i'm not able to set the "via [appname]" (it takes by default "via ios"). I've already put in my info.plist file the appid value.
I'm also not able to make the sharing work for ios5 (it replies with Error 400).
Following there's the code i use:
- (void)viewDidLoad{
appDelegate = [[UIApplication sharedApplication]delegate];
if (!appDelegate.session.isOpen) {
appDelegate.session = [[FBSession alloc] init];
if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
}];
}
}
and when i have to share, i call this method:
- (IBAction)fbShare:(id)sender {
if (appDelegate.session.isOpen) {
BOOL displayedNativeDialog = [FBNativeDialogs presentShareDialogModallyFrom:self
initialText:textView.text
image:img
url:nil
handler:nil];
if (!displayedNativeDialog) {
[self performPublishAction:^{
[FBRequestConnection startForUploadPhoto:img
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
}];
}];}
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
appDelegate.session = [[FBSession alloc] init];
}
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
}];}
}
- (void) performPublishAction:(void (^)(void)) action {
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
[FBSession.activeSession reauthorizeWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
action();
}
else{
}
}];
} else {
action();
}}
Any hint?
Thanks a lot,
erica
I successfully share an image on my wall, but i'm not able to set the "via [appname]" (it takes by default "via ios"). I've already put in my info.plist file the appid value.
Most likely you've not set the Facebook app name. I'd recommend looking it at https://developers.facebook.com/apps admin panel
Related
I want to download a file when clicking on a button in my AngularJS app which runs on Tomcat with a Java Spring backend but nothing is happening. The method in the backend is called and everything seems to have worked....but my browser doesn't download anything.
What am I missing?
Here's the AngularJS code, which logs Export-Response:[object Object]:
exportProjects() {
let filteredProjectIds = [];
for (let i in this.filteredProjects) {
for (let x = 0, l = this.filteredProjects[i].length; x < l; x++) {
if (!this.isOldProjectsBundle(this.filteredProjects[i][x])) {
filteredProjectIds.push(this.filteredProjects[i][x].id);
}
}
}
this.$http.get('/profiles/projectWordExport?filteredProjects=' + filteredProjectIds.join(",")).then(response => {
console.log("Export-Response:" + response);
return response;
});
}
This is the Java code being called (it's really being called, already debugged it, no errors occuring):
#RequestMapping(value = "/projectWordExport", method = RequestMethod.GET)
public void getProjectsWord(HttpServletRequest request, HttpServletResponse response, #RequestParam String filteredProjects) throws Exception {
//Load project objects from input string or load all projects if input empty
List<Project> projects = new java.util.ArrayList<>();
if (filteredProjects.isEmpty()) {
projects = projectRepository.findAll();
} else {
String[] pIds = filteredProjects.split(",");
for (String pId : pIds) {
projects.add(projectRepository.findById(Long.parseLong(pId)));
}
}
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setHeader("Content-disposition", "attachment;filename=Projektexport.docx");
try {
SaveToZipFile saver = new SaveToZipFile(printer.printProjects(this.prepareProjectExport(projects)));
saver.save(response.getOutputStream());
response.flushBuffer();
} catch (NullPointerException e) {
response.setStatus(500);
response.sendError(500, "Fehler beim exportieren des Tests aufgetreten");
}
}
Put this in #RequestMapping annotation
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
I am trying Vision kit for iOS 11. I can use Vision and I can find boundbox values face. But I don't know how can I draw a rectangle using this points. I hope so my question is clear.
Hope you were able to use VNDetectFaceRectanglesRequest and able to detect faces. To show rectangle boxes there are lots of ways to achieve it. But simplest one would be using CAShapeLayer to draw layer on top your image for each face you detected.
Consider you have VNDetectFaceRectanglesRequest like below
let request = VNDetectFaceRectanglesRequest { [unowned self] request, error in
if let error = error {
// somthing is not working as expected
}
else {
// we got some face detected
self.handleFaces(with: request)
}
}
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
do {
try handler.perform([request])
}
catch {
// catch exception if any
}
You can implement a simple method called handleFace for each face detected and use VNFaceObservation property to draw a CAShapeLayer.
func handleFaces(with request: VNRequest) {
imageView.layer.sublayers?.forEach { layer in
layer.removeFromSuperlayer()
}
guard let observations = request.results as? [VNFaceObservation] else {
return
}
observations.forEach { observation in
let boundingBox = observation.boundingBox
let size = CGSize(width: boundingBox.width * imageView.bounds.width,
height: boundingBox.height * imageView.bounds.height)
let origin = CGPoint(x: boundingBox.minX * imageView.bounds.width,
y: (1 - observation.boundingBox.minY) * imageView.bounds.height - size.height)
let layer = CAShapeLayer()
layer.frame = CGRect(origin: origin, size: size)
layer.borderColor = UIColor.red.cgColor
layer.borderWidth = 2
imageView.layer.addSublayer(layer)
}
}
More info can be found here in Github repo iOS-11-by-Examples
Here is easy and simple way to draw boxes.
let faceRequest = VNDetectFaceRectanglesRequest(completionHandler:self.faceDetection)
func faceDetection (request: VNRequest, error: Error?) {
guard let observations = request.results as? [VNFaceObservation]
else { print("unexpected result type from VNFaceObservation")
return }
guard observations.first != nil else {
return
}
// Show the pre-processed image
DispatchQueue.main.async {
self.resultImageView.subviews.forEach({ (subview) in
subview.removeFromSuperview()
})
for face in observations
{
let view = self.CreateBoxView(withColor: UIColor.red)
view.frame = self.transformRect(fromRect: face.boundingBox, toViewRect: self.analyzedImageView)
self.analyzedImageView.image = self.originalImageView.image
self.resultImageView.addSubview(view)
}
}
}
//MARK - Instance Methods
func boxView(withColor : UIColor) -> UIView {
let view = UIView()
view.layer.borderColor = withColor.cgColor
view.layer.borderWidth = 2.0
view.backgroundColor = UIColor.clear
return view
}
//Convert Vision Frame to UIKit Frame
func transformRect(fromRect: CGRect , toViewRect :UIView) -> CGRect {
var toRect = CGRect()
toRect.size.width = fromRect.size.width * toViewRect.frame.size.width
toRect.size.height = fromRect.size.height * toViewRect.frame.size.height
toRect.origin.y = (toViewRect.frame.height) - (toViewRect.frame.height * fromRect.origin.y )
toRect.origin.y = toRect.origin.y - toRect.size.height
toRect.origin.x = fromRect.origin.x * toViewRect.frame.size.width
return toRect
}
I am having issues dismissing my modal view after the app has returned from the facebook login. I have followed the facebook tutorial and made some liberties to the code as I did not want to use the app delegate. I'l post some code snippets
I am using two classes. One class is my initial view that pops up if a user had been logged in called DayViewController and then my modal view that pops up if a user isn't logged in. LoginViewController.
Should also be noted that I am using storyboards and I built my app so that DayViewController has a nav bar embeded in it and that is then embeded in the tab bar. I think my issue is in the facebook tutorial they use some code to get the view that is currently displayed and then dismiss that...I haven't been able to implement that.
DayViewController Class--
ViewDidLoad
- (void)viewDidLoad
{
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
[self openSession];
}else {
[self showLoginView];
}
[super viewDidLoad];
}
showLoginView
- (void)showLoginView{
UIViewController *topViewController = [self.navigationController topViewController];
UIViewController *modalViewController = [topViewController presentedViewController];
if (![modalViewController isKindOfClass:[LoginViewController class]]) {
LoginViewController *lvc = [self.storyboard instantiateViewControllerWithIdentifier:#"loginView"];
[self presentViewController:lvc animated:NO completion:nil];
} else {
LoginViewController *loginVC = [[LoginViewController alloc] init];
[loginVC loginFailed];
}
}
sessionStateChanged
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
UIViewController *topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"loginView"];
//LoginViewController *lvc = [self.storyboard instantiateViewControllerWithIdentifier:#"loginView"];
if ([[topViewController presentedViewController]
isKindOfClass:[LoginViewController class]]) {
[self dismissViewControllerAnimated:NO completion:nil];
}else{
}
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
//[self.navController popToRootViewControllerAnimated:NO];
[FBSession.activeSession closeAndClearTokenInformation];
[self showLoginView];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
NSLog(#"Error");
[alertView show];
}
}
Default OpenSession
- (void)openSession{
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler: ^(FBSession *session,FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
LoginViewController Class---
Nothing dramatic in this class, only a sign-in button that throws the facebook states through the openSession function
- (IBAction)signInButton:(id)sender {
[self.loginActivityIndicator startAnimating];
dvc = [[DayViewController alloc] init];
[dvc openSession];
//[self dismissViewControllerAnimated:YES completion:Nil];
}
Id like to be able to track if the user shared by facebook, twitter, etc, but it seems there's no way to know which method was selected. Is there?
You can use Activity Types in setCompletionHandler
UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
if([activityType isEqualToString: UIActivityTypeMail]){
NSLog(#"Mail");
}
if([activityType isEqualToString: UIActivityTypePostToFacebook]){
NSLog(#"Facebook");
}
}];
[self presentViewController:activityVC animated:TRUE completion:nil];
Built-in activity types for which the system has built-in support for.
NSString *const UIActivityTypePostToFacebook;
NSString *const UIActivityTypePostToTwitter;
NSString *const UIActivityTypePostToWeibo;
NSString *const UIActivityTypeMessage;
NSString *const UIActivityTypeMail;
NSString *const UIActivityTypePrint;
NSString *const UIActivityTypeCopyToPasteboard;
NSString *const UIActivityTypeAssignToContact;
NSString *const UIActivityTypeSaveToCameraRoll;
Edited for iOS 8
Please note that this will generate a compiler warning in iOS 8, you need to use the setCompletionWithItemsHandler method instead of the setCompletionHandler method.
Replace:
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
with:
[activityVC setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
In Swift 4:
activityViewController.completionWithItemsHandler = { activity, success, items, error in
if !success{
print("cancelled")
return
}
if activity == .postToTwitter {
print("twitter")
}
if activity == .mail {
print("mail")
}
}
swift 3
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: [screenCapture], applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivityType.print, UIActivityType.postToWeibo, UIActivityType.copyToPasteboard, UIActivityType.addToReadingList, UIActivityType.postToVimeo]
activityViewController.completionWithItemsHandler = { activity, success, items, error in
if !success{
print("cancelled")
return
}
if activity == UIActivityType.postToFacebook {
print("facebook")
}
if activity == UIActivityType.mail {
print("mail")
}
}
self.present(activityViewController, animated: true, completion: nil)
You can use this lib https://github.com/rdougan/RDActivityViewController to identify which activity has been touched and return custom data by activity just by implementing its protocol.
Like This:
- (NSArray *)activityViewController:(NSArray *)activityViewController itemsForActivityType:(NSString *)activityType
{
if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
return #[#"Twitter text"];
} else if ([activityType isEqualToString:UIActivityTypeMessage]) {
return #[#"Message text"];
} else if ([activityType isEqualToString:UIActivityTypeMail]) {
return #[#"Mail text"];
} else if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
return #[#"Facebook text"];
} else {
return #[#"Default text"];
}
}
I hope I have helped you!
Hi, I have already uploaded a sqlite3 file to icloud. Now I want to download this file to my APP's Document folder. After I pressed the download button, it will show the success information. But in fact, there is no sqlite file in the documents folder or maybe the file is broken. Could someone help me?
-(IBAction)downloadPressed:(id)sender
{
if(![self downloadFileIfNotAvailable:self.icloudURL])
{
[self displayAlert:#"Warning!!" withmessage:#"failed to restore"];
}else{
[self displayAlert:#"Congratulations" withmessage:#"restore sccuessfully"];
}
}
-(BOOL)downloadFileIfNotAvailable:(NSURL *)file
{
NSNumber* isIniCloud = nil;
NSError* err;
if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
// If the item is in iCloud, see if it is downloaded.
if ([isIniCloud boolValue]) {
NSFileManager* fm = [NSFileManager defaultManager];
if([fm removeItemAtPath:self.filePath error:&err])
{
if (![fm startDownloadingUbiquitousItemAtURL:file error:nil]) {
return NO;
}else{
return YES;
}
}
}
return NO;
}
return NO;
}