Friday, 18 October 2013

Launching an Email Client from Windows 8 Store Apps – Language Comparison

Unlike in Windows Phone apps, there is not a dedicated task for composing email, instead, a general purpose launcher is used for launching URIs. To launch an email client, a mailto: type URI can be used. The launching itself is pretty much identical in C#, VB.Net, C++ and JavaScript; however the text needs escaping to cope with spaces, carriage returns etc and this is where the languages differ:

C#
In .Net for C# and VB.Net, the Uri class has a static method ‘EscapeUriString’ which takes care of escaping URI strings:

var email = string.Format(“mailto:{0}?subject={1}&body={2}”,
            “email@somedomain.com",
            "A Subject",
            “The email body”);

var cleaned = Uri.EscapeUriString(email);

// Email task
await Launcher.LaunchUriAsync(new Uri(cleaned, UriKind.Absolute));

VB.Net

Dim email = String.Format(SUPPORT_MAIL,
            “email@somedomain.com",
            "A Subject",
            “The email body”)

Dim cleaned = Uri.EscapeUriString(email)

            ' Email task
Await Launcher.LaunchUriAsync(New Uri(cleaned, UriKind.Absolute))

JavaScript
WinRT JavaScript Uri object doesn’t have the ‘EscapeUriString’ method, however it supports the standard JavaScript encodeURI method which does the same thing:

var email = "mailto:";
            email += "email@somedomain.com";
            email += "?subject=";
            email += "A Subject";
            email += "&body=";
            email += "The email body";

var cleaned = encodeURI(email);

// Email task
var uri = new Windows.Foundation.Uri(cleaned);
return Windows.System.Launcher.launchUriAsync(uri);

C++
WinRT JavaScript Uri object doesn’t have the ‘EscapeUriString’ method either and doesn’t have anything build in, so we need to write one ourselves.

String^ email = L"mailto:";
       email += "email@somedomain.com";
       email += L"?subject=";
       email += "A Subject";
       email += L"&body=";
       email += "The email body";

auto cleaned = encodeURI(email);

auto uri = ref new Uri(cleaned);
Launcher::LaunchUriAsync(uri);

I found the main bit of this enclode function on Stack Overflow (can’t find where now) and modified it to work with WinRT:

String^ encodeURI(String^ c)
{
    const std::string unreserved = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~!*()\\,/?:@=+$&";

    std::wstring  escaped=L"";
    for(size_t i=0; i<c->Length(); i++)
    {
       auto data = c->Data();

       if (unreserved.find_first_of(data[i]) != std::string::npos)
       {
           escaped.push_back(data[i]);
       }
       else
       {
           escaped.append(L"%");
           char buf[3];
           sprintf_s(buf, "%.2X", data[i]);

           auto s = std::string(buf);
           auto w = std::wstring(s.begin(), s.end());

           escaped.append(w);
       }
    }

    return ref new Platform::String(escaped.c_str());

}

No comments:

Post a Comment