fluttercommunity / plus_plugins

Flutter Community Plus Plugins
BSD 3-Clause "New" or "Revised" License
1.52k stars 891 forks source link

[Question] [share_plus]: Unable to share image with proper title #3031

Open JasonBennett41 opened 2 weeks ago

JasonBennett41 commented 2 weeks ago

What is your question?

Hello, I am trying to figure out how to share an image from my application along with a title to be displayed. I am attempting to get this to work on iOS first, and have not tested on Android yet. I understand via scraping around the internet that there are limitations with sharing to some apps, particularly meta-developed ones. However, to me there definitely appear to be issues with the plugin itself.

For the purpose of this inquiry, I will be testing on the plugin example itself, to ensure all issues have to do with the functionality of the plugin and not my own app.

For starters, I just need to be able to display a title, along with the image preview within the iOS share sheet. Of course, right now any 'text' or 'subject' parameters will not be displayed along with the image preview, and it will instead display 'Plain Text and 1 Document'.

Other scenarios:

Along with the issues relating to the share sheet, sharing itself seems to be less than intuitive. I will test this on a few basic social apps that should provide a decent look at what's going on

Text with image shared:

Image with no text shared:

So, aside from small matters like the ability to position the text optimally, and gmail ignoring the subject parameter, the real issue is just displaying a proper title in the share sheet, and ensuring the 'Plain Text' is not also passed to apps that do not want it, like Instagram. It seems to me there should be a separate parameter to specify the title, and inclusion of the abilty to customize what data is passed based on the share target. I suppose this may not be possible with the current iteration of the share sheet, I am no expert.

At the very least, I need to be able to share an image with a title so that it doesn't display ugly 'Plain Text and 1 Document'.

I have found that this is definitely possible while an AI image generation app called 'Dream', and I've recorded that to show. It seems they are able to add a title and still share their image properly to instagram.

I also tested on Duolingo, which has their own custom share view, but also allows users to use the iOS share sheet. It works for them too, with title, image, text, link. They've even used their app icon as the preview image for the share which looks even more professional. I'll include a video of this as well.

To put a point on my question, it certainly seems to be possible to develop a professional sharing functionality. If the consensus is that this plugin is doing the most it can due to limitations outside its control, what specifically are those limitations and why are these other apps able to figure it out?

I am going to, of course, continue to delve into this matter. I sure hope I'm not being an ass and am just using the plugin incorrectly, but since the example has the same issue with ugly non-title I was compelled to ask for guidance. I will update with any relevant findings.

Dream: https://github.com/fluttercommunity/plus_plugins/assets/141113522/e28397b2-fbdc-4758-a4fd-506c18bb2ac1

Duolingo https://github.com/fluttercommunity/plus_plugins/assets/141113522/edd5a1ed-2fde-471d-935f-21a587704106

Checklist before submitting a question

JasonBennett41 commented 1 week ago

Okay, it's taken a while to figure out what's going on here... I have no experience with method channels and am clueless about obj c or swift. It actually seems to be primarily a documentation issue. It is not made clear how the parameters are intended to be used.

For starters, I found that the issue with no title being displayed is because 'subject' parameter should be used for this purpose instead of 'text'. This can be confusing because 'text' can also end up displaying in the title area, but if 'subject' is provided it is set as the metadata title and the code block is exited:

 if ([_subject length] > 0) {
    metadata.title = _subject;
  } else if ([_text length] > 0) {
    metadata.title = _text;
  }

The documentation does not do a good job of explaining this, in fact I am of the opinion that it makes it seem like a parameter intended only for email sharing... The only mentions of it amount to:

'The share method also takes an optional subject that will be used when sharing to email.' 'Optionally, you can pass subject, text and sharePositionOrigin.'

Also note that if you provide 'text' parameter along with a file, it will not display a title but instead 'Plain Text & 1 Document'. This is because text is treated more similarly to an image than a subject. For each shared file, the code iterates through to create a SharePlusData object. It does the same thing for text:

  for (int i = 0; i < [paths count]; i++) {
    NSString *path = paths[i];
    NSString *mimeType = mimeTypes[i];
    [items addObject:[[SharePlusData alloc] initWithFile:path
                                                mimeType:mimeType
                                                 subject:subject]];
  }
  if (text != nil) {
    NSObject *data = [[SharePlusData alloc] initWithSubject:subject text:text];
    [items addObject:data];
  }
@interface SharePlusData : NSObject <UIActivityItemSource>

@property(readonly, nonatomic, copy) NSString *subject;
@property(readonly, nonatomic, copy) NSString *text;
@property(readonly, nonatomic, copy) NSString *path;
@property(readonly, nonatomic, copy) NSString *mimeType;

- (instancetype)initWithSubject:(NSString *)subject
                           text:(NSString *)text NS_DESIGNATED_INITIALIZER;

- (instancetype)initWithFile:(NSString *)path
                    mimeType:(NSString *)mimeType NS_DESIGNATED_INITIALIZER;

- (instancetype)initWithFile:(NSString *)path
                    mimeType:(NSString *)mimeType
                     subject:(NSString *)subject NS_DESIGNATED_INITIALIZER;

- (instancetype)init
    __attribute__((unavailable("Use initWithSubject:text: instead")));

@end

I'm not sure about this, but I suspect that Duolingo for example circumvents this sharing of multiple files (image file & text file) and consequent non-title by making the text a UIActivityItemProvider instead of a UIActivityItemSource, or something like that.

Ensuring text is not provided along with the image does indeed make sharing to Instagram work properly, I will attach screenshots of the difference.

I believe that the example requires a simple edit to work properly as currently the title will never display properly due to parameters being provided as empty strings instead of null values.

I did not investigate uri parameter.

Hope this writeup helps somebody 🎉

Things I think would be nice additions to this package:

working well --

instagram_good

not working well --

instagram_bad