iOS Question Share to social media functionality - Help with inline objC

henrywood

Active Member
Licensed User
Hey !

I am trying to integrate social sharing functionality in my app through Objective C.

Could someone validate the methology - in particular the Objective C code ?

I would like to get an event in B4i when the user has completed sharing.

UPDATED: 09-05-2015: THIS VERSION DOES NOT WORK - PLEASE SEE POST #101 FOR A WORKING VERSION:
https://www.b4x.com/android/forum/t...elp-with-inline-objc.52849/page-6#post-336177

A BIG THANK YOU TO ALL WHO HELPED ME WITH THIS CODE !

Here is my code:

B4X:
'Code module

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'Public variables can be accessed from all modules.

End Sub


#If OBJC

- (IBAction)shareToSocialMedia:(NSString *)txt (NSString *)url: (NSString *)image
{
   //NSString *text = @"How to add Facebook and Twitter sharing to an iOS app";
   NSString *text = txt;
   //NSURL *url = [NSURL URLWithString:@"http://roadfiresoftware.com/2014/02/how-to-add-facebook-and-twitter-sharing-to-an-ios-app/"];
   NSURL *url = [NSURL URLWithString:url];
   //UIImage *image = [UIImage imageNamed:@"roadfire-icon-square-200"];
   UIImage *image = [UIImage imageNamed:image];

   UIActivityViewController *controller =
   [[UIActivityViewController alloc]
   initWithActivityItems:@[text, url, image]
   applicationActivities:nil];

  controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
  UIActivityTypeMessage,
  UIActivityTypeMail,
  UIActivityTypePrint,
  UIActivityTypeCopyToPasteboard,
  UIActivityTypeAssignToContact,
  UIActivityTypeSaveToCameraRoll,
  UIActivityTypeAddToReadingList,
  UIActivityTypePostToFlickr,
  UIActivityTypePostToVimeo,
  UIActivityTypePostToTencentWeibo,
  UIActivityTypeAirDrop];

   [self presentViewController:controller animated:YES completion:^{
     [self sharedone];
   }];
}

- (void)sharedone:
{
   int status = 1;
   [B4IObjectWrapper raiseEvent:self :@"onsharingdone:" :@[@((int)status)]];
   //[B4IObjectWrapper raiseEventFromDifferentThread:self :@"onsharingdone:" :@[@((int)status)]];

}

#end if

Sub onSharingDone(Status As Int)
   Log("onSharingDone: Status = " & Status)
End Sub

Sub ShareToSocialMedia(txt As String, theURL As String, imageFile As String)

   Dim NativeMe As NativeObject = Me
   NativeMe.RunMethod("shareToSocialMedia:", Array As Object(txt, theURL, imageFile))

End Sub
 
Last edited:

Pendrush

Well-Known Member
Licensed User
This is a way better

B4X:
 [popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height,0,SBview.Height)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
B4X:
Sub Process_Globals
  Private myPage As Page
End Sub


#IF OBJC

#define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortrait)||([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortraitUpsideDown))?[[UIScreen mainScreen] bounds].size.width :[[UIScreen mainScreen] bounds].size.height)

#define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortrait)||([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortraitUpsideDown))?[[UIScreen mainScreen] bounds].size.height :[[UIScreen mainScreen] bounds].size.width)

- (void)share2SocialMedia:(NSString *)txt :(NSString *)theurl :(NSString *)theimg :(UIView *)SBview
{
  //NSString *text = @"How to add Facebook and Twitter sharing to an iOS app";
  NSString *text = txt;
  //NSURL *url = [NSURL URLWithString:@"http://roadfiresoftware.com/2014/02/how-to-add-facebook-and-twitter-sharing-to-an-ios-app/"];
  NSURL *url = [NSURL URLWithString:theurl];
  //UIImage *image = [UIImage imageNamed:@"roadfire-icon-square-200"];
  UIImage *image;

  if([theimg hasPrefix:@"http://"] || [theimg hasPrefix:@"https://"] ) {
  image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:theimg]]];
  } else {
  image = [UIImage imageNamed:theimg];
  }

  UIActivityViewController *controller =
  [[UIActivityViewController alloc]
  initWithActivityItems:@[text, url, image]
  applicationActivities:nil];

  controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
  UIActivityTypeMessage,
  UIActivityTypeMail,
  UIActivityTypePrint,
  UIActivityTypeCopyToPasteboard,
  UIActivityTypeAssignToContact,
  UIActivityTypeSaveToCameraRoll,
  UIActivityTypeAddToReadingList,
  UIActivityTypePostToFlickr,
  UIActivityTypePostToVimeo,
  UIActivityTypePostToTencentWeibo,
  UIActivityTypeAirDrop];

  [controller setCompletionHandler:^(NSString*activityType, BOOL completed) {

  // Raise the event for B4i
  if (completed) {
  [self.bi raiseEvent:nil event:@"activity_completed::" params:@[@((BOOL)completed),(activityType)]];
  } else {

  NSString *activity = @"";
  [self.bi raiseEvent:nil event:@"activity_completed::" params:@[@((BOOL)completed),(activity)]];
  }
  }];

  //if iPhone
  if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
  [(self._mypage).object presentViewController:controller animated:YES completion:nil];

  } else { //if iPad
  // Change Rect to position Popover
  UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:controller];
  UIWindow *window = [[UIApplication sharedApplication] keyWindow];
  UIView *topView = window.rootViewController.view;
  [popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height, 0, SBview.Height)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  }
}

#End If



Sub activity_completed(status As Boolean, T As String)

  'If Main.DEBUG Then
  '  Utils.Log_("onSharingDone: Status = " & status & " - Type: " & T & " - Will look for callback: ShareModule_SharingCompleted in " & myPage.Title)
  'End If

' If SubExists(myPage, "ShareModule_SharingCompleted", 2) = True Then
' CallSub3(myPage, "ShareModule_SharingCompleted", status, T)
' End If

End Sub

Sub ShareToSocialMedia(p As Page, txt As String, theURL As String, imageFileOrURL As String, shareButton As Button)

  myPage = p
  Dim v As View = shareButton

  Dim NativeMe As NativeObject = Me
  NativeMe.RunMethod("share2SocialMedia::::", Array As Object(txt, theURL, imageFileOrURL, v))

End Sub


This code give output as on images
IMG_0231.JPG IMG_0232.JPG
The more is button down,m the more is popup away from button
image 2 - first button click
image 1 - second button click

I will now test your code, and post results.
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Yes, my is better, but something is still wrong.
The more button is down, pop-up share get more away from button, same distance is on portrait and in landscape.
With button.top=0 share start in half of button height.
As I move button down, pop-up share get more and more distance from button.
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Also.. when I comment line in designer AutoScaleAll, there is change, but also popup get more away from button as button.top get higher.
For some reason coordinate Y not calculated right and I don't know why.
Coordinate X work as expected in CGRectMake.
 
Upvote 0

henrywood

Active Member
Licensed User
Shouldn't it be like this instead:
B4X:
[popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height, SCREEN_WIDTH/2, SCREEN_HEIGHT/4)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Nope. to much down and too much right.
For some reason coordinate Y not calculated right and I don't know why.
Coordinate X work as expected in CGRectMake.
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
For some reason
B4X:
[popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height+65, 0, 0)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
this work as expected, probably height of nav bar?
 
Upvote 0

henrywood

Active Member
Licensed User
what about:

B4X:
[popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height,
((SCREEN_WIDTH - (SBview.Left + SBview.Width))/2) , ((SCREEN_HEIGHT - (SBview.Top + SBview.Height))))inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
 
Upvote 0

henrywood

Active Member
Licensed User
Maybe try this:

B4X:
#IF OBJC

#define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortrait)||([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortraitUpsideDown))?[[UIScreen mainScreen] bounds].size.width :[[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortrait)||([UIApplication sharedApplication].statusBarOrientation ==UIInterfaceOrientationPortraitUpsideDown))?[[UIScreen mainScreen] bounds].size.height :[[UIScreen mainScreen] bounds].size.width)

- (void)share2SocialMedia:(NSString *)txt :(NSString *)theurl :(NSString *)theimg :(UIView *)SBview
{
  //NSString *text = @"How to add Facebook and Twitter sharing to an iOS app";
  NSString *text = txt;
  //NSURL *url = [NSURL URLWithString:@"http://roadfiresoftware.com/2014/02/how-to-add-facebook-and-twitter-sharing-to-an-ios-app/"];
  NSURL *url = [NSURL URLWithString:theurl];
  //UIImage *image = [UIImage imageNamed:@"roadfire-icon-square-200"];
  UIImage *image;

  if([theimg hasPrefix:@"http://"] || [theimg hasPrefix:@"https://"] ) {
  image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:theimg]]];
  } else {
  image = [UIImage imageNamed:theimg];
  }

  UIActivityViewController *controller =
  [[UIActivityViewController alloc]
  initWithActivityItems:@[text, url, image]
  applicationActivities:nil];

  controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
  UIActivityTypeMessage,
  UIActivityTypeMail,
  UIActivityTypePrint,
  UIActivityTypeCopyToPasteboard,
  UIActivityTypeAssignToContact,
  UIActivityTypeSaveToCameraRoll,
  UIActivityTypeAddToReadingList,
  UIActivityTypePostToFlickr,
  UIActivityTypePostToVimeo,
  UIActivityTypePostToTencentWeibo,
  UIActivityTypeAirDrop];

  [controller setCompletionHandler:^(NSString*activityType, BOOL completed) {

  // Raise the event for B4i
  if (completed) {
     [self.bi raiseEvent:nil event:@"activity_completed::" params:@[@((BOOL)completed),(activityType)]];
  } else {

   NSString *activity = @"";
     [self.bi raiseEvent:nil event:@"activity_completed::" params:@[@((BOOL)completed),(activity)]];
  }
  }];

  //if iPhone
  if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
     [(self._mypage).object presentViewController:controller animated:YES completion:nil];

  } else { //if iPad
  // Change Rect to position Popover
     UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:controller];
     UIWindow *window = [[UIApplication sharedApplication] keyWindow];
     UIView *topView = window.rootViewController.view;
     UINavigationController navCtl = window.rootViewController.navigationController;
     CGFloat navBarHeight = navCtl.navigationBar.frame.size.height;
     CGFloat statusBarHeight = navCtl.statusBar.frame.size.height;
     CGFloat extra = 0;

     if ([UIApplication sharedApplication].statusBarHidden == NO)
     {
          extra += statusBarHeight 
     }
     if (navCtl.navigationBarHidden == NO)
     {
          extra += navBarHeight 
     }


     //[popup presentPopoverFromRect:CGRectMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/4, 0, 0)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
     //[popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height,0,SBview.Height)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
   [popup presentPopoverFromRect:CGRectMake(SBview.Left + SBview.Width/2, SBview.Top+SBview.Height+extra, 0, 0)inView:topView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  }
}

#End If
 
Last edited:
Upvote 0

Pendrush

Well-Known Member
Licensed User
if navbar is hidden
B4X:
    NavControl.NavigationBarVisible = False
Then we need to add +20 instead of +64
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
error: property 'navigationController' not found on object of type 'b4i_modshare *'
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
^
1 error generated.
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
A lot of things changed... Please check code in Main also in Module.
Working as expected with and without NavBar, also working on iPhone as on iPad.
 

Attachments

  • share_test.zip
    10 KB · Views: 167
Upvote 0

henrywood

Active Member
Licensed User
Tried to edit the code in post #75

Could you please try my version - It gets the height of navigationBar and statusBar in objc and checks the status of the bars as well when it calculates the offset to be added (see post 75)
 
Upvote 0
Top