Facebook policy prohibits pre-filling share dialogs with text. As per Facebook's documentation, only images and URLs can be shared—text must be entered manually by the user.
Solution: For Facebook sharing, use images and URLs. Add text descriptions to your game's post-share screen instead of trying to pre-fill Facebook text.
// Facebook: Images and URLs onlyif(SocialShareComposer.IsComposerAvailable(SocialShareComposerType.Facebook)){varimageItem=ShareItem.Screenshot();varurlItem=ShareItem.URL(URLString.URLWithPath("https://yourgame.com")); // Text will be ignored by FacebookSharingServices.ShowSocialShareComposer(SocialShareComposerType.Facebook,callback:null,imageItem,urlItem);}
When should I use ShareSheet vs specific composers?
Use the decision tree:
Use Specific Composers (MailComposer, MessageComposer, SocialShareComposer) when:
You know the intended destination (email for support, SMS for invites, Facebook for achievements)
You want to pre-fill specific fields (email subject, message body)
You need platform-specific features (email attachments, HTML formatting)
Better user experience with targeted sharing flow
Use ShareSheet when:
Destination is unknown or varies by user preference
Specific composer is unavailable (fallback scenario)
Maximum flexibility for user choice
Quick general sharing without specific requirements
How can I detect if the user actually shared the content?
Detection varies by platform:
iOS: Result callbacks reliably report share status:
Android: Result detection is limited. Android's sharing system doesn't always report whether content was actually shared or just viewed. The callback may fire when the share sheet closes, regardless of whether sharing completed.
Best Practice: On Android, assume sharing succeeded when the result callback fires, or don't gate rewards strictly on confirmed sharing. iOS provides reliable confirmation.
Why doesn't MailComposer show on my device?
MailComposer requires configured email accounts on the device. If none are configured, MailComposer.CanSendMail() returns false.
Can I share both text and image to WhatsApp on iOS?
No. WhatsApp on iOS only accepts either text OR an image in a single share, not both. Android WhatsApp supports both simultaneously.
Solution: Prioritize image over text on iOS, or let user choose:
Why doesn't MessageComposer support subject on Android?
SMS (Short Message Service) doesn't have a subject field—only MMS (Multimedia Messaging Service) supports subjects on some platforms. Android SMS typically doesn't support subjects.
Solution: Check capability before setting subject:
How do I share high-resolution screenshots without quality loss?
Use PNG format for lossless compression:
For custom images, use PNG encoding:
Note: Some platforms (like Twitter, Facebook) may automatically compress images on their end. Essential Kit preserves quality up to the sharing point.
Can I customize the appearance of ShareSheet?
No. ShareSheet uses the native platform UI (UIActivityViewController on iOS, Intent.createChooser() on Android) which cannot be customized. The appearance is controlled by the OS.
What you can control:
Content shared (text, images, URLs)
Which apps are available (based on content type)
Excluded activity types (iOS only, advanced)
What you cannot control:
UI appearance, colors, layout
Button positions or labels
Available app order
How do I share files like PDFs or documents?
Use ShareItem.File() with appropriate MIME type:
Common MIME types:
PDF: application/pdf
Text: text/plain
JSON: application/json
ZIP: application/zip
CSV: text/csv
Why does my social composer say platform is unavailable?
The platform doesn't support sharing via the iOS/Android sharing API
Solution: Always check availability and provide fallback:
Can I share without showing any UI?
No. Native sharing APIs require user interaction and UI presentation for privacy and security reasons. Silent background sharing is not permitted by iOS or Android.
All sharing methods (ShowShareSheet, ShowMailComposer, ShowMessageComposer, ShowSocialShareComposer) display native UI that the user must interact with.
How do I track which platform users shared to?
Platform tracking is limited:
iOS ShareSheet: Result code indicates success/failure but not which app was selected.
Android ShareSheet: Similar limitations—result indicates closure but not destination app.
Specific Composers: You know the platform (Mail, SMS, Facebook, etc.) because you explicitly called that composer.
Best Practice: Track by composer type rather than destination app:
Why are my email attachments too large to send?
Email services have attachment size limits (typically 10-25MB depending on email provider).
Solution: Compress images before sharing:
File size tips:
Use JPEG for photos/screenshots (smaller than PNG)
Use PNG only when transparency is needed
Resize large textures before converting to ShareItem
Compress binary files before creating ShareItem
Can I pre-fill recipients in MessageComposer?
Yes, but user can always modify:
Note: Recipient field is pre-filled but not locked—user can add/remove recipients before sending. This is intentional for privacy reasons.
Does ShareSheet work in Unity Editor?
No. ShareSheet and all sharing composers require native platform APIs that are only available when built to iOS or Android devices.
Testing Workflow:
Build to physical device (iOS or Android)
Install and launch
Test sharing functionality on device
Monitor result callbacks
Editor Behavior: Calling sharing methods in Editor may show warnings or do nothing. Always test on devices.
How do I handle sharing errors gracefully?
Implement comprehensive error handling:
Can I share animated GIFs?
Yes, using the GIF conversion method:
Note: Not all platforms/apps support animated GIFs. Some may convert to static images.
Where can I confirm plugin behavior versus my implementation?
Run Assets/Plugins/VoxelBusters/EssentialKit/Examples/Scenes/SharingDemo.unity on a physical device. If the sample works but your implementation doesn't:
void ShareToWhatsApp(string text, Texture2D image)
{
if (!SocialShareComposer.IsComposerAvailable(SocialShareComposerType.WhatsApp))
{
return;
}
#if UNITY_IOS
// iOS: Choose image or text (image typically more valuable)
var imageItem = ShareItem.Image(image, TextureEncodingFormat.PNG, "share.png");
SharingServices.ShowSocialShareComposer(
SocialShareComposerType.WhatsApp,
callback: null,
imageItem
);
#elif UNITY_ANDROID
// Android: Both work
var textItem = ShareItem.Text(text);
var imageItem = ShareItem.Image(image, TextureEncodingFormat.PNG, "share.png");
SharingServices.ShowSocialShareComposer(
SocialShareComposerType.WhatsApp,
callback: null,
textItem,
imageItem
);
#endif
}
if (MessageComposer.CanSendText())
{
string subject = null;
if (MessageComposer.CanSendSubject())
{
subject = "Game Invitation";
Debug.Log("Subject supported on this platform");
}
else
{
Debug.Log("Subject not supported - using body only");
}
SharingServices.ShowMessageComposer(
recipients: null,
subject: subject,
body: "Join me in the game!",
callback: null
);
}
Texture2D highResTexture = GetHighResTexture();
var imageItem = ShareItem.Image(
highResTexture,
TextureEncodingFormat.PNG, // Lossless
"highres.png"
);
Texture2D GetHighResTexture()
{
// Return your captured texture here
return Texture2D.blackTexture;
}
public void SharePDF()
{
// Load your PDF data
byte[] pdfData = GetPDFData();
var fileItem = ShareItem.File(
pdfData,
"application/pdf",
"document.pdf"
);
SharingServices.ShowShareSheet(
callback: (result, error) =>
{
if (error != null)
{
Debug.LogError($"PDF share failed: {error.Description}");
return;
}
Debug.Log($"PDF shared: {result.ResultCode}");
},
shareItems: new[]
{
fileItem,
}
);
}
byte[] GetPDFData()
{
// Your PDF loading logic
return System.IO.File.ReadAllBytes(Application.persistentDataPath + "/doc.pdf");
}
if (SocialShareComposer.IsComposerAvailable(SocialShareComposerType.Twitter))
{
SharingServices.ShowSocialShareComposer(
SocialShareComposerType.Twitter,
callback: result => Debug.Log($"Twitter share: {result.ResultCode}"),
ShareItem.Text("Join me in the game!")
);
}
else
{
Debug.Log("Twitter unavailable, using ShareSheet fallback");
SharingServices.ShowShareSheet(
callback: result => Debug.Log($"ShareSheet fallback: {result.ResultCode}"),
ShareItem.Text("Join me in the game!")
); // Let user choose other apps
}
void ShareWithTracking()
{
// Track specific composer
SharingServices.ShowSocialShareComposer(
SocialShareComposerType.Twitter,
callback: (result, error) => TrackSharing("Twitter", result?.ResultCode, error),
ShareItem.Text("Share text")
);
}
void TrackSharing(string composerType, object resultCode, Error error)
{
if (error != null)
{
Debug.LogError($"Sharing via {composerType} failed: {error.Description}");
return;
}
Debug.Log($"Sharing via {composerType}: {resultCode}");
// Send to analytics: composer type, result code, content type
}
public void ShareCompressedScreenshot()
{
Texture2D screenshot = CaptureScreenshot();
// Use JPEG with quality setting for smaller file size
var compressedImage = ShareItem.Image(
screenshot,
TextureEncodingFormat.JPG, // JPEG compresses better than PNG
"screenshot.jpg"
);
SharingServices.ShowMailComposer(
toRecipients: new[] { "[email protected]" },
subject: "Screenshot",
body: "Compressed screenshot attached",
callback: (result, error) =>
{
if (error != null)
{
Debug.LogError($"Email result error: {error.Description}");
return;
}
Debug.Log($"Email result: {result.ResultCode}");
},
compressedImage
);
}
Texture2D CaptureScreenshot()
{
// Your screenshot capture logic
return ScreenCapture.CaptureScreenshotAsTexture();
}