Sharing content in mobile apps is one of the most important features in terms of app usability and goes beyond the concept of sharing on social media. For example, if you receive a PDF document via email and you want to open it inside a PDF viewer app like Adobe Reader, you are actually sharing the document from the mail client with the PDF viewer. Similarly, you can share files on your devices, such as pictures and videos, in a WhatsApp chat.
What you are doing is asking the operating system to open another app, which is open enough to receive contents from other apps. In a mobile app that works with data, a common scenario is to receive a document via web API, display the document in-app, and have the option to send it via email to some recipients. So, at a higher level, by sharing, we generally mean sharing content with another app.
Sharing content in Xamarin.Forms is made easy by the Share class offered by the Xamarin.Essentials library. This class exposes a static method called RequestAsync, which receives an argument that can be of the following types,
- string, for sharing plain text.
- ShareTextRequest, for sharing URIs or text.
- ShareFileRequest, for sharing files.
Working with the first two is not covered in this chapter, but we will focus on the third one. The ShareFileRequest class points to the local pathname of a file. In the current example, the PDF document is stored as an embedded resource, so an additional step is required to get the file from the resources, copy it into the app’s directory, and then point to the obtained pathname. This is accomplished by the following method, called ShareAsync:
private async Task ShareAsync()
{
var fileStream = typeof(App).GetTypeInfo().Assembly.
GetManifestResourceStream("WorkingWithDocuments.SampleDoc.pdf");
var cacheFile = Path.Combine(FileSystem.CacheDirectory, "SampleDoc.pdf");
using (var file = new FileStream(cacheFile, FileMode.Create, FileAccess.Write))
{
fileStream.CopyTo(file);
}
var request = new ShareFileRequest();
request.Title = "Share document";
request.File = new ShareFile(cacheFile);
await Share.RequestAsync(request);
}
As in the first example about loading the document, the first line gets the file stored inside the embedded resources as a Stream. The cacheFile variable combines the path for the app’s cache directory with the file name into one pathname. The using block creates an instance of the FileStream class pointing to the original file’s stream, creating a copy in the target directory. The using block ensures the stream resources are disposed after usage. The ShareFileRequest object can point to the local pathname via the File property. The Title property allows for specifying the title for the sharing user interface, if supported by the OS. The ShareAsync method is invoked by the Clicked event handler for the ShareButton as follows,
private async void ShareButton_Clicked(object sender, EventArgs e)
{
await ShareAsync();
}
If you now run the app and click Share after opening the document, you will get a result similar to the following figure,
The result will almost certainly vary on your device because it depends on how many and what apps you have installed to support PDF documents. (In my case, for iOS I’m using the simulator, which has no PDF apps installed, and therefore, it only shows device options.) You will just need to select an app enabled to receive PDF documents, and the file will be shared using the system interface, without the need to write platform-specific code—which is an incredible benefit. The app that receives the document will then know how to handle it. For example, if you select an email client for sharing, the document will be automatically added as an attachment to a new email message.