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 3D Touch 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:
UIApplicationShortcutItems UIApplicationShortcutItemIconType UIApplicationShortcutIconTypeAdd UIApplicationShortcutItemSubtitle UIApplicationShortcutItemTitle Declaratie toevoegen UIApplicationShortcutItemType nl.kembit.expenseclaim.ios.000
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 35x35 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.
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(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 use 3D Touch and 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!