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
Tested with online image and with image from assets, working fine if I click on Viber for example.
If click on CANCEL application just Force Close with error:
Error occurred on line: 50 (main)
*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]
Stack Trace: (
CoreFoundation <redacted> + 150
libobjc.A.dylib objc_exception_throw + 38
CoreFoundation <redacted> + 428
CoreFoundation <redacted> + 44
B4i Example __36-[b4i_modshare share2SocialMedia:::]_block_invoke + 240
UIKit <redacted> + 130
UIKit <redacted> + 580
UIKit <redacted> + 28
UIKit <redacted> + 42
UIKit <redacted> + 30
UIKit <redacted> + 1166
UIKit <redacted> + 150
UIKit <redacted> + 102
UIKit <redacted> + 308
UIKit <redacted> + 184
UIKit <redacted> + 66
QuartzCore <redacted> + 236
libdispatch.dylib <redacted> + 22
libdispatch.dylib _dispatch_main_queue_callback_4CF + 1330
CoreFoundation <redacted> + 8
CoreFoundation <redacted> + 1512
CoreFoundation CFRunLoopRunSpecific + 476
CoreFoundation CFRunLoopRunInMode + 106
GraphicsServices GSEventRunModal + 136
UIKit UIApplicationMain + 1440
B4i Example main + 108
libdyld.dylib <redacted> + 2
)

Line 50 is END SUB

B4X:
Sub Button1_Click

    Dim tmpPath As String
    tmpPath = File.DirAssets & "/image.png"
   
    modShare.ShareToSocialMedia(Page1, "aaaaa", "http://bing.com", tmpPath)
   
End Sub 'Line 50
 
Upvote 0

henrywood

Active Member
Licensed User
Hey !

Now I updated the code once again - See below

Let me know if that solves your problem ?

NEW 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.

   Private myPage As Page

End Sub

#IF OBJC
- (void)share2SocialMedia:(NSString *)txt :(NSString *)theurl :(NSString *)theimg
{
   //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) {

     // Dismiss the View ?
     //[(self._mypage).object dismissViewControllerAnimated:YES completion:nil];

     // 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)]];
     }
   }];

   [(self._mypage).object presentViewController:controller animated:YES completion:nil];
}

#End If

Sub activity_completed(status As Boolean, T As String)

   Log("onSharingDone: Status = " & status & " - Type: " & T)

End Sub

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

   myPage = p
   Dim NativeMe As NativeObject = Me
   NativeMe.RunMethod("share2SocialMedia:::", Array(txt, theURL, imageFile))

End Sub
 
Last edited:
Upvote 0

Pendrush

Well-Known Member
Licensed User
Errors again, on compile
error: missing '[' at start of message send expression
[self.bi raiseEvent:nil event:mad:"activity_completed::" params:mad:[@((BOOL)completed),(activity)]];
^
[
/Users/xxxxx/b4iBuild/UploadedProjects/adw3efn/B4iProject/b4i_modshare.m:101:97: error: expected ']'
[self.bi raiseEvent:nil event:mad:"activity_completed::" params:mad:[@((BOOL)completed),(activity)]];
^
/Users/xxxxx/b4iBuild/UploadedProjects/adw3efn/B4iProject/b4i_modshare.m:101:3: note: to match this '['
[self.bi raiseEvent:nil event:mad:"activity_completed::" params:mad:[@((BOOL)completed),(activity)]];
^
2 errors generated.
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Working example in attachment.
You can change code in OBJC, to allow more sharing options.
These are excluded for share in example:
B4X:
controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
    UIActivityTypePrint,
    UIActivityTypeCopyToPasteboard,
    UIActivityTypeAssignToContact,
    UIActivityTypeSaveToCameraRoll,
    UIActivityTypeAddToReadingList,
    UIActivityTypePostToTencentWeibo,];
 

Attachments

  • share.zip
    9.2 KB · Views: 195
Upvote 0

hanyelmehy

Active Member
Licensed User
i get this error when try code in post #31 (on iPhone OS 7)
B4X:
*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[2]
Stack Trace: (
  CoreFoundation       <redacted> + 154
  libobjc.A.dylib      objc_exception_throw + 38
  CoreFoundation       <redacted> + 418
  CoreFoundation       <redacted> + 44
  Picture and Words Proverbs          0x0007ce8d -[b4i_modshare share2SocialMedia:::] + 688
  CoreFoundation       <redacted> + 68
  CoreFoundation       <redacted> + 282
  Picture and Words Proverbs          0x000a7ec5 +[B4I runDynamicMethod:method:throwErrorIfMissing:args:] + 1928
  Picture and Words Proverbs          0x000bb2ed -[B4INativeObject RunMethod::] + 164
  Picture and Words Proverbs          0x0007c453 -[b4i_modshare _sharetosocialmedia::::] + 1206
Picture and Words Proverbs          0x0005e9b3 -[b4i_act2 _spage1_barbuttonclick:] + 1938
CoreFoundation       <redacted> + 68
CoreFoundation       <redacted> + 282
Picture and Words Proverbs          0x000a7ec5 +[B4I runDynamicMethod:method:throwErrorIfMissing:args:] + 1928
Picture and Words Proverbs          0x001d8d19 -[B4IShell runMethod:] + 496
Picture and Words Proverbs          0x001d7e8d -[B4IShell raiseEventImpl:method:args::] + 2060
Picture and Words Proverbs          0x001dace1 -[B4IShellBI raiseEvent:event:params:] + 1316
Picture and Words Proverbs          0x000a73a3 __33-[B4I raiseUIEvent:event:params:]_block_invoke + 74
libdispatch.dylib    <redacted> + 10
libdispatch.dylib    <redacted> + 22
libdispatch.dylib    <redacted> + 254
CoreFoundation       <redacted> + 8
CoreFoundation       <redacted> + 1300
CoreFoundation       CFRunLoopRunSpecific + 522
CoreFoundation       CFRunLoopRunInMode + 106
GraphicsServices     GSEventRunModal + 138
UIKit                UIApplicationMain + 1136
Picture and Words Proverbs          0x00045e65 main + 116
libdyld.dylib        <redacted> + 2
)

any suggestion
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
For my sharing I'm using modified version with only 2 options, Subject and TextForShare.

B4X:
Sub Process_Globals
    Private myPage As Page 'ignore

End Sub


#IF OBJC

//- (void)share2SocialMedia:(NSString *)subj :(NSString *)txt :(NSString *)theurl :(NSString *)theimg
- (void)share2SocialMedia:(NSString *)subj :(NSString *)txt
{
    NSString *subject = subj;
    NSString *text = txt;
    //NSURL *url = [NSURL URLWithString:theurl];
    //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]
    //initWithActivityItems:@[text, url, image]
    applicationActivities:nil];
    [controller setValue:subject forKey:@"subject"];

    controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
    UIActivityTypePrint,
    UIActivityTypeCopyToPasteboard,
    UIActivityTypeAssignToContact,
    UIActivityTypeSaveToCameraRoll,
    UIActivityTypeAddToReadingList,
    UIActivityTypePostToTencentWeibo,];

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

    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)]];
    }
    }];

    [(self._mypage).object presentViewController:controller animated:YES completion:nil];
}

#End If


Sub activity_completed(status As Boolean, T As String)
   
    'Log("onSharingDone: Status = " & status & " - Type: " & T)
   
End Sub


'Sub ShareToSocialMedia(p As Page, SubjectTxt As String, TxtForShare As String, TheURL As String, ImageFile As String)
Sub ShareToSocialMedia(p As Page, SubjectTxt As String, TxtForShare As String)

    myPage = p
    Dim NativeMe As NativeObject = Me
    NativeMe.RunMethod("share2SocialMedia::", Array(SubjectTxt, TxtForShare))
    'NativeMe.RunMethod("share2SocialMedia::::", Array(SubjectTxt, TxtForShare, TheURL, ImageFile))

End Sub
 
Upvote 0

hanyelmehy

Active Member
Licensed User
For my sharing I'm using modified version with only 2 options, Subject and TextForShare.

B4X:
Sub Process_Globals
    Private myPage As Page 'ignore

End Sub


#IF OBJC

//- (void)share2SocialMedia:(NSString *)subj :(NSString *)txt :(NSString *)theurl :(NSString *)theimg
- (void)share2SocialMedia:(NSString *)subj :(NSString *)txt
{
    NSString *subject = subj;
    NSString *text = txt;
    //NSURL *url = [NSURL URLWithString:theurl];
    //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]
    //initWithActivityItems:@[text, url, image]
    applicationActivities:nil];
    [controller setValue:subject forKey:@"subject"];

    controller.excludedActivityTypes = @[UIActivityTypePostToWeibo,
    UIActivityTypePrint,
    UIActivityTypeCopyToPasteboard,
    UIActivityTypeAssignToContact,
    UIActivityTypeSaveToCameraRoll,
    UIActivityTypeAddToReadingList,
    UIActivityTypePostToTencentWeibo,];

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

    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)]];
    }
    }];

    [(self._mypage).object presentViewController:controller animated:YES completion:nil];
}

#End If


Sub activity_completed(status As Boolean, T As String)
 
    'Log("onSharingDone: Status = " & status & " - Type: " & T)
 
End Sub


'Sub ShareToSocialMedia(p As Page, SubjectTxt As String, TxtForShare As String, TheURL As String, ImageFile As String)
Sub ShareToSocialMedia(p As Page, SubjectTxt As String, TxtForShare As String)

    myPage = p
    Dim NativeMe As NativeObject = Me
    NativeMe.RunMethod("share2SocialMedia::", Array(SubjectTxt, TxtForShare))
    'NativeMe.RunMethod("share2SocialMedia::::", Array(SubjectTxt, TxtForShare, TheURL, ImageFile))

End Sub
This work ,but i need to send image also
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Image path is not good for some reason on iOS 7. I don't have any iOS 7 device to test it. Maybe someone other can help. :(
 
Upvote 0
Top