Поделиться через


Implementing the share contract in my Windows 8 App

So I've blogged already about my first Windows 8 app and how I got the background task to update my live tiles. But for me one of the coolest things about Windows 8 App development is how amazingly easy it is to integrate with other apps. Some things which would have potentially taken some considerable time to design, write and debug are now pretty much instantaneous additions to your app thanks to the Windows 8 contracts. What I mean is that without the contract architecture the developer would need to a) decide which are the other apps with which they would share content, b) research the implementation interfaces etc... needed to share content with each of those apps and then c) come up with a code structure which let them re-use as much as possible while effectively doing the same thing for each client app. The same would be true for the search contract - the developer would need to research how to provide searcheable content to each "searcher" app etc...

 

But the contracts functionality in Windows 8 means this kind of thing is accomplished with a few short lines of code. My app implements the share contract (the search contract wouldn't make sense for this app). The only question is about how to or do we support popular sharing clients which don't yet have Windows 8 apps. For me at this time the answer is not to implement bespoke sharing for them, but to use the contract and have faith that the platforms popularity will drive the production of apps for all those clients - a good example here is Facebook which does not yet have a Windows 8 app, but I would be pretty hopeful that we will see on in 2013 and at that point all most sharing apps will be integrated with it to a certain degree.

How easy is it - it is this easy:

1) In the MainPage constructor I hooked into the DataTransferManager and gave it an event handler as follows:

 

Using Windows.ApplicationModel.DataTransfer;

DataTransferManager manager = DataTransferManager.GetForCurrentView();manager.DataRequested += manager_DataRequested;

 

2) The addition of the DataTransferManager now means that when the share charm is invoked by a user, the event will be passed to my page. So I just need to handle the event. The simplest event handler looks something like this :

 

 void manager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
 DataRequest request = args.Request;
 request.Data.Properties.Title = "Share contract example";
 request.Data.Properties.Description = "Sharing some text";
 request.Data.SetText("This is shared text");
} 

What I also found interesting, useful and nice as it's free is that the framework decides on the correct share client based on the format of the shared content. So in my initial implementation (above) my app shared very simple text, and so all possible share client apps were offerd as choices (Twitter clients included etc...) when I invoked sharing.  

 However, the app data is best represented as tables (as on the app UI) so I used formatted html for the content, and now, using the below method I am only offered one share client when invoke sharing; the e-mail client.

 

void manager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args){ DataRequest request = args.Request; request.Data.Properties.Title = string.Format("Irish Tides - {0}", CurrentPortTitle); request.Data.Properties.Description = "Sharing tide data"; TilePort sharePort = TilesQueue.ToArray().FirstOrDefault(p => p.ID.Equals(CurrentPortID)); string htmlMail = BuildHtml(CurrentPort); string htmlFormat = HtmlFormatHelper.CreateHtmlFormat(htmlMail); request.Data.SetHtmlFormat(htmlFormat);}

 

And this is what sharing from within the app using the e-mail client looks like: 

 

Gotchas

No real issues with this one, the share contract is really easy to implement, but I did notice a couple of things;

1) As I experimented with different content formats, I occasionally ended up sharing badly formed html and this seemed to break the sharing functionality right across Windows 8. Once it was broken it was broken for every app, they all showed the same symptoms - basically the share page seemed stuck in an infinite loop while trying to get data from the apps. Quickest cure was a restart and fix the content formatting (I know I should really find out the name of the service and just restart that).

2) When sharing plain text it seems that no formatting characters ('\t', '\n' etc...) are effective - even if the client ends up being a mail client which you know can usually handle them.

Comments

  • Anonymous
    March 04, 2013
    Hi, Nice write up on share contracts. Quick question: lets say you wanted to use the share contract to share a link to the app in the windows store. So say you're  playing a game and click the share charm...I want something like "hey Im playing <insert game name here> on Windows 8. You can download it here" I want the receiver of the email to be able to click and go right to the windows store. It seems to me that this isn't possible until After the app has been certified and there is a store link to it. Is that correct? thx

  • Anonymous
    March 04, 2013
    Hi Alex, Thanks for the comment. I think you could use the current app id (msdn.microsoft.com/.../windows.applicationmodel.store.currentapp.appid.aspx). This property does not exist until the app is certified and in the store. I haven't tried this but is seems to me if I used this in the share:  “apps.microsoft.com/.../app” +AppName” +’/’+ appid it would appear as: apps.microsoft.com/.../7d36b364-0523-4bcf-8c32-97d3f445f731 Worth a try?