Wednesday, March 02, 2011

WP7Clipboard - A clipboard API for #wp7dev

Background
  • Windows Phone 7 doesn't have an API for a Clipboard. (Actually, in the current version it doesn't even include a clipboard. - But, the ability to cut, copy and paste text will be added in the update coming later this month.)
  • I wrote an app, back in December 2010 (see video and please comment at http://www.wp7comp.com/scratch-pad/trackback/), that enables the cutting, copying and pasting of text and even sharing it between multiple applications. (Some people have the idea that you can't share data between apps on the device but I proved this isn't the case. Check the video or get it from the Marketplace to see/confirm that it doesn't use any unrestricted APIs or use a web service for storing/sharing the data.)
Short version
Head over to http://wp7clipboard.codeplex.com/ and get the code to see how I did this and use the library in your own applications.

Longer version
Constraints are good. They focus the mind and can provide structure where chaos can sometimes reign.
By their nature, mobile devices are very constrained. Many of these constraints are passed to (forced upon?) the applications that run on the devices.

Windows Phone 7 development has some potentially limiting constraints in this area:
  • No cut and paste support (currently)
  • No clipboard
  • No shared file system

There are 2 ways we can react to constraints:

  1. We can complain about them.
or
  1. We can work with them.

I opt for the later.
I knew there had to be a way to do this! Just because it seemed that everyone and their dog was complaining about a "lack of copy and paste" wasn't going to stop me.

"Cut and paste" is really only about copying and manipulating objects (strings in this case) in memory. Just because there isn't a UI for this doesn't mean we can't do it. We just need to build a UI.

Just because the platform doesn't provide a clipboard (functionality to store objects in persistent memory and make them available to all apps) doesn't mean we can't create the functionality ourselves. But this is where the fun begins...

All Silverlight based apps run inside a sandbox and can only create files inside "IsolatedStorage". There's no shared storage facility.

Rather than focus on what we don't have, let's think about what we can do.
Well, even in a Silverlight app we can use some of the XNA libraries.
Through the XNA APIs we can create and read images in the Pictures hub. (We can't delete them but we'll just have to live with that.)
After a little experimentation I discovered that the API will only allow us to save a valid JPEG file in to the pictures hub.
Never mind, there are ways of hiding information within pictures.
I had another idea in mind though. Due to something I worked on a long time ago, I know that the JPEG file format includes an end of file marker. I also know that almost all implementations of code to read JPEG format files ignores everything after the end of file marker. A quick check later and I verified that this is the case on WP7 too.

Yes, that's the secret, I include the data I wish to store in the "clipboard" inside a JPEG image file (the clipboard images littered through this post) after the end of file marker. Then, when I want to read from the "clipboard" I just get the most recent file from the users MediaLibrary and retrieve the extra data from the end of the file.

AFAIK only one person managed to correctly guess what I'd done.



Now you can do this in your apps too. I've encapsulated the functionality from ScratchPad into a separate library and made it open source at http://wp7clipboard.codeplex.com/
Originally this only supported text but I've started to add some functionality for processing (cutting and pasting) images too. It's still a beta but hopefuly some of you will find it useful, helpful or interesting.




A word of warning. Using this method creates files on the users phone which you can't programmtically delete. After sustained use, this will clutter up the users "saved pictures" folder and they will have to manually delete the files there. If you use this library/technique you may want to warn your users about this and give them the option to disable the functionality.

If possible I'd recommend sharing data between apps by synchronising it to a web based system. Connectivity issues aside that will probably make working with large amounts of data easier and provide backup/redundancy options.



I'd love any feedback you have on this.

3 comments:

  1. Anonymous9:35 am

    Well I thought you were doing it over the network but your solution is really interesting. That's what they call thinking out of the box - congrats.

    ReplyDelete
  2. @Miro The reason I released the ScratchPad app to the marketplace was to prove it wasn't using a web service. - The listed requirements don't include network access.

    I didn't want to go that route as it would limit the functionality by network connectivity which wouldn't provide a great user experience. (any apps using the "clipboard" would be on the device so having to go off device-when you don't have to-would be less than ideal.) I also didn't want to worry about security of data saved/sent/retrieved that way (on a public app/service) or scaling to support it.

    Glad you liked it.

    ReplyDelete

I get a lot of comment spam :( - moderation may take a while.