Gerald Versluis: 3D Touch your Xamarin(.Forms) app: apply pressure to icon area

Now that I have got a new iPhone 7 that supports 3D Touch it’s about time to have a play with that!

In case you have missed it, 3D Touch (or Force Touch) is a concept that Apple introduced with the iPhone 6s (Plus) and iOS 9. It lets you press the screen a bit harder which enables you, as a developer, to act on it.

Already incorporated in iOS you can now use it to show the user some previews of content without navigating to it, but mostly it is used in some shortcut menu on the iOS main screen. When you 3D Touch an app icon you’ll probably see some menu options to navigate to somewhere in the app directly. With the introduction of iOS 10 it also shows you the widget associated with your app, we will look at that as well in a following post.

This menu is really easy to implement in your own Xamarin (and Xamarin.Forms!) app, that is what we will be looking at in this post!

The possibilities

You can use the 3D Touch for you app icon in a few ways. The first and foremost is just to show a static menu which acts as a shortcut menu. When the user clicks one it automatically focusses the search field or goes to the right tab or screen. It can also be used more dynamically, for instance to show some recent played songs on your favourite music app. You can either use the default icons that Apple supplies for you, but you can also use your own icons. This is known as the Quick Actions and is what we will be looking at in this post.

Other features that can be done now are Peek and Pop and Pressure Sensitivity. The first allows you to show some kind of preview of content. Think of a Facebook post which you give a little pressure and you get a preview of the linked content behind it. If you press further you will navigate to the full content.

The Pressure Sensitivity provides you with information about how hard the user is pressing the screen. With this information you could draw a thicker line while drawing for instance.

In-depth documentation of all you can do with this can be found in the Xamarin documentation

Configuring your Quick Actions

The first thing you need to do to implement this is think about what menu options you would like to show. You can do anything you want! But it’s probably best if it does something meaningful.

For an app I’ve been building at our company to file expense claims I wanted to implement this. The interface is a list of previous claims and a button to add a new one. So I thought to myself: “why not add a new claim right from the app icon?”. So I wanted to create a Quick Action to go to the new screen immediately.

The first thing you need to do is specify your actions in the info.plist file like this:

<key>UIApplicationShortcutItems</key>
<array>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeAdd</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string></string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Declaratie toevoegen</string>
        <key>UIApplicationShortcutItemType</key>
        <string>nl.kembit.expenseclaim.ios.000</string>
    </dict>
</array>

There are a few things going on here, I will go over them by the key names:

  • With the UIApplicationShortcutItemIconType you can set the icon for your action. There is a whole list of built-in options you can use, as found here. These will cover the most scenarios. However if you want to use a custom icon, replace this with the UIApplicationShortcutItemIconFile key and set the string value to the filename in your resources without the extension. So if you have a ‘myawesomeicon.png’ in your resources, set the string value to ‘myawesomeicon’. Also keep in mind that the file needs to be a PNG, square 35×35 pixels, single color.
    Note that you still need to add the UIApplicationShortcutItemIconType key as it is required. However when you add the UIApplicationShortcutItemIconFile the IconType key will be ignored.
  • UIApplicationShortcutItemSubtitle is an optional key. If you put something here it will be shown in a smaller font below the UIApplicationShortcutItemTitle key value. The subtitle key isn’t used a lot by popular apps.
  • With the UIApplicationShortcutItemTitle key you specify the caption of your action. Keep this short and meaningful, i.e. ‘Add this’, ‘Search’, etc. FYI for the non Dutch speakers, this one says: “Add expense claim”
  • Last but not least there is the UIApplicationShortcutItemType key. This one is also required and identifies the option that the user has chosen. It can be anything as long as it is unique. A common pattern is the app ID with a suffix, incrementing number

With adding this in our info.plist and deploying it we can already see our action popping up. It just doesn’t do anything yet.

Our Quick Actions menu
Our Quick Actions menu

If you want to test this kind of behaviour you’re going to either need a MacBook pro with 3D touch on the touch pad or a iPhone that supports it. Although the Simulator does have menu options to simulate a deep press they don’t seem to be implemented.

Implementing the Quick Action in code

So now our menu is ready, let’s implement some logic in it. If you are using Xamarin.Forms you have to go in you iOS project since this is very specific iOS stuff.

Although not strictly necessary, you probably want to put your shortcut identifiers in some static class for easier use. So create a ‘ShortcutIdentifier’ static class in you iOS project and implement it something like this:

public static class ShortcutIdentifier
{
    public const string First = "com.company.appname.000";
    public const string Second = "com.company.appname.001";
    public const string Third = "com.company.appname.002";
    public const string Fourth = "com.company.appname.003";
}

Of course the names could be more meaningful.. In my case it would look like this:

public static class ShortcutIdentifier
{
    public const string AddExpenseClaim = "nl.kembit.expenseclaim.ios.000";
}

Just make sure the string values correspond with the ones in your info.plist file.

From here there are a few ways to go about this, which is mainly dependent on how your architecture looks like and what action you are after to implement. I have implemented my functionality with the MessagingCenter. Although I’m not a big fan of using it a lot, it did the trick for what I was trying to do without having to overhaul a lot of things. For more info on how to (not) use is, check out this article by Adam Pedley.

But first things first, I opened up my AppDelegate.cs because that is the main entry point for our app so there we have to determine if our user has tapped a shortcut.

First we’ll add a couple of things that aren’t there yet.

[Register("AppDelegate")]
public partial class AppDelegate : FormsApplicationDelegate
{
    public bool HandleShortcutItem(UIApplicationShortcutItem shortcutItem)
    {
        var handled = false;

        // Anything to process?
        if (shortcutItem == null) return false;

        // Take action based on the shortcut type
        switch (shortcutItem.Type)
        {
            case ShortcutIdentifier.AddExpenseClaim:
                MessagingCenter.Send(App.Instance, "GoToNewExpenseClaim");
                handled = true;
                break;
        }

        // Return results
        return handled;
    }

    public override void PerformActionForShortcutItem(UIApplication application, UIApplicationShortcutItem shortcutItem, UIOperationHandler completionHandler)
    {
        // Perform action
        completionHandler(HandleShortcutItem(shortcutItem));
    }

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        // ... There probably is some stuff in here already
    }
}

With the comments in place it should be pretty straight forward.

Basically we override the PerformActionForShortcutItem to get notified when a Quick Action needs to be handled and we can supply a method to handle it.
Within that method we check which shortcut it was with the static class we made earlier and handle it accordingly. In my case I will send out a message.

Now in the PageModel of my main screen I subscribe to the message…

MessagingCenter.Subscribe<App>(this, "GoToNewExpenseClaim", NavigateToNewItemFromShortcut);

And handle what it should do

private async void NavigateToNewItemFromShortcut(App app)
{
    // Pop everything first so we don't get the same page multiple times on the stack
    await CoreMethods.PopToRoot(false);

    // Execute the new command
    NewItemCommand.Execute(null);
}

There is some FreshMvvm stuff in here because that is the framework I used for this app. Basically it pops any other pages so we don’t get any weird navigationstack behaviour and then we execute the command for adding a new claim which was already there.

And that is it! When I now launch from the Quick Action menu I get the add new item screen immediately like I wanted to and gained a few precious milliseconds today!

Let me know what you think or what you like to see. I plan to add a widget after this next.

Also I’d love to see some good original uses for the Quick Actions and deep press functionality. So hit me up on Twitter!

Details

Xamarin: Xamarin Dev Days Continue to Roll Out!

With Xamarin Dev Days now in more than 100 cities, we’re putting the fastest route to mobile app success in the hands of thousands of developers around the world. Xamarin Dev Days are free events packed with sessions, live demos, and an engaging environment to build your very own cloud-based Xamarin.Forms application with Xamarin and […]

The post Xamarin Dev Days Continue to Roll Out! appeared first on Xamarin Blog.

Details

Xamarin: Mobile Leaders Podcast | Enterprise Mobility Trends with Maribel Lopez: Where Are Things Headed?

Today we’re excited to launch a new podcast focused on helping you achieve success with your mobile initiatives faster. On the Mobile Leaders Podcast, we’ll gather different perspectives and experiences from industry analysts and veterans, plus mobile leaders from organizations both big and small. In today’s episode, Xamarin’s Steve Hall and I discuss the latest […]

The post Mobile Leaders Podcast | Enterprise Mobility Trends with Maribel Lopez: Where Are Things Headed? appeared first on Xamarin Blog.

Details

Xamarin: Easier App Debugging with Xamarin Studio Run Configurations

When building apps, we often want to run our application under varying conditions. Whether this is something simple like altering environmental variables, or something a bit more complex like changing the startup Activity or service for an Android app, changing your project’s settings to switch between configurations can be tedious, especially if you change between […]

The post Easier App Debugging with Xamarin Studio Run Configurations appeared first on Xamarin Blog.

Details

Xamarin: Xamarin and Visual Studio at Future Decoded

Don’t miss the Visual Studio and Xamarin teams at this year’s Future Decoded event at London’s ExCeL center. Day One is the “business day,” where organizations can find out how embracing the power of digital transformation can propel them into a brighter future, while Day Two is for the technical crowd, with a focus is […]

The post Xamarin and Visual Studio at Future Decoded appeared first on Xamarin Blog.

Details

Daniel Cazzulino: Leveraging Azure Functions for MIT AppInventor Web Interactions

I’m contributing a few hours a week on Fridays to tutor kids on programming and a bit of electronics,
in what we call a “Geeks’ School” (or Escuela de Geeks). I’m always
exploring ways to make it more interesting for kids (12-16yo) to learn programming. I found out that
given that the cellphone (mostly Androids here in Argentina) is their primary computing device, they
were instantly hooked to the MIT AppInventor 2 platform.

We’re actually using Thunkable,
a fork of the original MIT AI2 that provides a nicer Material Design UI and sleeker looking client/companion
app for the device. Kids have even interacted via chat directly with the site owners, which was a blast!

One of the kids wanted to build a translating app that would:

  1. Accept spoken spanish input
  2. Recognize the text and send it to a web api for translation
  3. Get the translated text and have the app speak it out loud

The speech recognition and
text-to-speech parts were very
straightforward involving just a couple built-in blocks with simple input-output connectors:

speech recognition block and text-to-speech

Plugging a Web component in-between the recognized (Spanish in this case) text in
when speech.After Getting Text and the call to call tts.Speak proved quite
challenging. To be clear, invoking web services by issuing POSTs and GETs is as easy
as anything else: just drop the non-visual Web component
on the designer and just call it from the blocks view. That’s the easy part. But the
key thing in invoking web services is processing its output, of course 😉

Most web APIs nowadays return plain JSON, and a quick search around
the web for how to parse
and consume JSON from an app
yielded some very scary looking
massive amount of blocks for something that is just a couple lines of code in any modern
programming language.

Azure Functions to the rescue

So I remembered the Build Conference introduction of Azure Functions
and chatting with the team at their booth, as well as
Scott’s great introduction to Serverless Computing and
this seemed like the perfect opportunity to give it a shot.

In short, what I wanted was a way to get a single JSON property value from the response of
Google’s translate API. The request looks like the following:

https://www.googleapis.com/language/translate/v2?q=hola&target=en&format=text&source=es&key={YOUR_API_KEY} 

And the response:

{
    "data": {
        "translations": [
            {
                "translatedText": "Hello"
            }
        ]
    }
}

It takes literally ONE line of code to retrieve the translatedText using Json.NET:

var result = JObject.Parse(json).SelectToken("data.translations[0].translatedText")

So I went to http://functions.azure.com (love the customized subdomain, as opposed to
navigating the seemingly endless features of Azure in the portal) and created a new
“Function app”.

NOTE: the “function app” is the actual Web API ‘site lite’ that will host the
actual function (or functions). So if you name it like your function, i.e.
parsejson then define the parsejson function, the resulting URL will look
slightly awkward: https://parsejson.azurewebsites.net/api/parsejson

In my case I went for stringify for the function app name, and json for the
function name, which results in a nice looking url https://stringify.azurewebsites.net/api/json

I started directly with from the Or create your own custom function link at the bottom
of the wizard, and chose the HttpTrigger - C# template. Then I wrote the code in a
window without any intellisense (I hope that changes soon ;)) but it was dead-simple. The
whole function that takes POSTed JSON bodies and a “q=[JSON PATH]” argument
for stringifying it is:

#r "Newtonsoft.Json"

using System.Net;
using Newtonsoft.Json.Linq;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var query = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "q", true) == 0)
        .Value;

    var json = await req.Content.ReadAsStringAsync();

    return string.IsNullOrEmpty(json) || string.IsNullOrEmpty(query) ?
        req.CreateResponse(HttpStatusCode.OK, "") :
        req.CreateResponse(HttpStatusCode.OK, JObject.Parse(json).SelectToken(query).ToString());
}

And of course you can try it out simply from curl:

curl -k -X POST -d "{"data":{"translations":[{"translatedText":"Hello"}]}}" https://stringify.azurewebsites.net/api/json?q=data.translations[0].translatedText

A whole speech to text translation app in less than 20 blocks

And with that, suddenly, interacting with the Web from MIT AppInventor2 or Thunkable is super
straight-forward. The whole program is easy to grasp by any 12yo+ kid:

  1. When the button is clicked, start listening for speech:
    Listen for speech
  2. When speech is recognized, ship it off for translation:
    Translate recognized speech
  3. When translation JSON comes back, ship it off for “stringifying”:
    Parse JSON
  4. When the simple string comes back from “stringify”, speak it out loud:
    Parse JSON

It would have taken that many blocks or more just to parse the JSON response
from the translation Web API. A massive improvement by just using a little bit
of serverless computing to aid in teaching 🙂

For other teachers leveraging MIT AppInventor for the Web, here’s the “documentation”:

  1. Set the stringify Web component’s URL to https://stringify.azurewebsites.net/api/json
  2. Append the path of the JSON value to retrieve as the query string parameter, like ?q=data.translations[0].translatedText
  3. Use a POST Text call passing in the JSON to parse.

NOTE: if you are dealing with a single JSON web response format, the URL of the
stringify Web component can be set statically in the Designer pane and never changed
from blocks, as shown in the above translation example.

I look forward to using Azure Functions a whole lot more. For one, I think I’ll expand the
stringify Azure Fuction app to include an xml and possibly html functions
receiving an XPath expression as the ?q= query string parameter.

Details