FAQ
Common Sharing Services issues and solutions
Why doesn't text appear in my Facebook share?
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 only
if (SocialShareComposer.IsComposerAvailable(SocialShareComposerType.Facebook))
{
var imageItem = ShareItem.Screenshot();
var urlItem = ShareItem.URL(URLString.URLWithPath("https://yourgame.com"));
// Text will be ignored by Facebook
SharingServices.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
// Good: Specific use case with fallback
if (MailComposer.CanSendMail())
{
SharingServices.ShowMailComposer(
toRecipients: new[] { "[email protected]" },
subject: "Support Request",
body: "Describe your issue.",
callback: null
);
}
else
{
SharingServices.ShowShareSheet(
callback: null,
ShareItem.Text("Support request")
);
}How can I detect if the user actually shared the content?
Detection varies by platform:
iOS: Result callbacks reliably report share status:
SharingServices.ShowShareSheet(
callback: (result) =>
{
if (result.ResultCode == ShareSheetResultCode.Done)
{
Debug.Log("User completed sharing on iOS");
Debug.Log("Reward the user for sharing.");
}
},
ShareItem.Text("Share content")
);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.
Solution: Always check before showing:
if (MailComposer.CanSendMail())
{
SharingServices.ShowMailComposer(
toRecipients: new[] { "[email protected]" },
subject: "Support Request",
body: "Describe your issue.",
callback: null
);
}
else
{
ShowMessage("Please configure an email account in Settings");
// Offer alternative sharing method
SharingServices.ShowShareSheet(
callback: null,
ShareItem.Text("Support request")
); // Fallback
}Device Setup:
iOS: Settings → Mail → Accounts → Add Account
Android: Settings → Accounts → Add Account → Email
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:
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
}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:
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
);
}How do I share high-resolution screenshots without quality loss?
Use PNG format for lossless compression:
public void ShareHighQualityScreenshot()
{
// Screenshot() captures current screen automatically
var screenshot = ShareItem.Screenshot();
SharingServices.ShowShareSheet(
callback: (result) => Debug.Log($"Screenshot shared: {result.ResultCode}"),
screenshot
);
}For custom images, use PNG encoding:
Texture2D highResTexture = GetHighResTexture();
var imageItem = ShareItem.Image(
highResTexture,
TextureEncodingFormat.PNG, // Lossless
"highres.png"
);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:
public void SharePDF()
{
// Load your PDF data
byte[] pdfData = GetPDFData();
var fileItem = ShareItem.File(
pdfData,
"application/pdf",
"document.pdf"
);
SharingServices.ShowShareSheet(
callback: (result) => Debug.Log($"PDF shared: {result.ResultCode}"),
fileItem
);
}
byte[] GetPDFData()
{
// Your PDF loading logic
return System.IO.File.ReadAllBytes(Application.persistentDataPath + "/doc.pdf");
}Common MIME types:
PDF:
application/pdfText:
text/plainJSON:
application/jsonZIP:
application/zipCSV:
text/csv
Why does my social composer say platform is unavailable?
SocialShareComposer.IsComposerAvailable() returns false when:
The app is not installed on the device
The user is not logged into the app
The platform doesn't support sharing via the iOS/Android sharing API
Solution: Always check availability and provide fallback:
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
}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:
void TrackSharing(string composerType, object resultCode)
{
Debug.Log($"Sharing via {composerType}: {resultCode}");
// Send to analytics: composer type, result code, content type
}
// Track specific composer
SharingServices.ShowSocialShareComposer(
SocialShareComposerType.Twitter,
callback: (result) => TrackSharing("Twitter", result.ResultCode),
ShareItem.Text("Share text")
);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:
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) => Debug.Log($"Email result: {result.ResultCode}"),
compressedImage
);
}
Texture2D CaptureScreenshot()
{
// Your screenshot capture logic
return ScreenCapture.CaptureScreenshotAsTexture();
}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:
SharingServices.ShowMessageComposer(
recipients: new[] { "+1234567890", "+0987654321" },
subject: null,
body: "Join my game!",
callback: (result) => Debug.Log($"Message result: {result.ResultCode}")
);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:
public void ShareWithErrorHandling()
{
// Check capabilities first
if (!MailComposer.CanSendMail())
{
ShowMessage("Email not available. Please configure an email account.");
return;
}
SharingServices.ShowMailComposer(
toRecipients: new[] { "[email protected]" },
subject: "Support Request",
body: "Describe your issue here",
callback: (result) =>
{
switch (result.ResultCode)
{
case MailComposerResultCode.Sent:
ShowMessage("Thank you! Your email was sent.");
break;
case MailComposerResultCode.Saved:
ShowMessage("Email saved as draft");
break;
case MailComposerResultCode.Cancelled:
Debug.Log("User cancelled email");
break;
case MailComposerResultCode.Failed:
ShowMessage("Email failed to send. Please try again.");
// Offer alternative (ShareSheet)
OfferAlternativeSharing();
break;
}
}
);
}
void ShowMessage(string message)
{
Debug.Log($"[User Message] {message}");
// Show in-game message UI
}
void OfferAlternativeSharing()
{
// Fallback to ShareSheet
SharingServices.ShowShareSheet(
callback: (result) => Debug.Log($"ShareSheet fallback: {result.ResultCode}"),
ShareItem.Text("Support request")
);
}Can I share animated GIFs?
Yes, using the GIF conversion method:
public void ShareAnimatedGif()
{
string gifPath = Application.persistentDataPath + "/animation.gif";
SharingServices.ConvertGifToShareItem(
gifPath,
onSuccess: (shareItem) =>
{
Debug.Log("GIF converted successfully");
SharingServices.ShowShareSheet(
callback: (result) => Debug.Log($"GIF shared: {result.ResultCode}"),
shareItem
);
},
onError: (error) =>
{
Debug.LogError($"GIF conversion failed: {error.Description}");
ShowMessage("Could not share GIF. Please try a different format.");
}
);
}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:
Compare capability checking (
CanSendMail(),IsComposerAvailable())Verify ShareItem creation (correct MIME types, valid data)
Check callback implementation (correct result code handling)
Confirm you're testing on device, not in Editor
Validate image sizes (not exceeding platform limits)
Ensure proper result code comparisons in callbacks
Last updated
Was this helpful?