Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development Knowledge Base

BlackBerry 10 - Leveraging Invocation Framework and QML for NFC

by BlackBerry Development Advisor ‎11-08-2012 10:30 AM - edited ‎11-09-2012 06:45 AM (5,640 Views)

Introduction

 

This article is part of a series intended to help developers wishing to exploit NFC in their BlackBerry® 10 applications. Readers of this article should have some pre-existing knowledge of the fundamental architecture of NFC systems and be familiar with C++. 

 

The approach taken in this article will be to build on our previous articles entitled “NFC on BlackBerry 10 - Reading and Writing Tags using native APIs” (which can be found here) and “NFC on BlackBerry 10 - peer to peer communication using SNEP” (which can be found here). If you haven’t already done so then this would be a good opportunity to read these articles since what follows depends on this pre-requisite knowledge. This article will not duplicate concepts that have already been covered in these previous articles but will focus on the differences.

 

In previous articles we have followed the development of a sample application called NFC Tool (available on GitHub® here) to illustrate the key learning points. NFC Tool utilized the BlackBerry 10 NFC APIs for C++ and illustrated an approach which gives developers complete control over the process and in particular, the user experience.

 

In this article we take NFC Tool and transform it to use the new BlackBerry® 10 Invocation Framework (IF) and NFC capabilities that are directly available from Cascades™ QML as opposed to C++. This new sample application is called NFC Tool Lite because it uses a much lighter-weight set of APIs from the Invocation Framework and much less C++ coding to provide many of the same NFC-based functions that NFC Tool has but which were implemented using a lower level set of APIs.

 

The Authors

  

This article was co-authored by Martin Woolley and John Murray both of whom work in the RIM Developer Relations team. Both Martin and John specialize in NFC applications development (amongst other things).

  

About the BlackBerry 10 Invocation Framework

 

So, what is this thing called the Invocation Framework and why ought you to know about it if you’re writing NFC capable applications? Figure 1 shows a very simplified conceptual view of IF. There are basically three components:

 

  1. The Invocation Framework itself which exposes APIs to applications that would wish to use it;
  2. An application that takes the role of registering with IF that it can perform some task on behalf of other applications;
  3. An application that requires some work to be performed, and takes on the role of requesting that IF find an application that can perform this task on its behalf.

 

if_overview.png

Figure 1 Overview of the Invocation Framework 

 

  

Ok, so that’s fairly straightforward. In this example the application on the left has obtained a document of type “.doc”. Rather than try to open this document and render it itself, or take a guess as to whether a suitable application that can perform this task is already installed on the device it asks the IF whether it knows of any suitable applications. Fortuitously, the application on the right has previously registered with the IF indicating that it has the capability to open “.doc” files. IF acts as an intermediary matching up requestors and providers of services.

 

As a result the application on the left is informed of the list of applications (yes, if more than one application indicates it is capable of opening a “.doc” then IF will supply that list to the requestor) from which it can select one through interaction with the user and pass a reference to the specific “.doc” file to be opened.

 

Right, how does this relate to NFC? How can an application that uses NFC exploit IF? The best way to see how this works is to look at the architecture of the NFC Tool sample application that we have developed which does not exploit IF and compare it with the architecture that our NFC Tool Lite application will have.

 

It’s not quite true to say that NFC Tool has absolutely no interaction with IF; you can see the first hint of it in some of the stanzas we had to add to the bar-descriptor.xml file to register that NFC Tool was interested in being notified of certain classes of NFC related events. The details of this will come later.

 

Architecture of NFC Tool

 

Let’s start by looking at the existing NFC Tool sample application. Figure 2 shows that whilst most of the UI related elements are handled through the Cascades and Qt® APIs the interaction with NFC is achieved through the BlackBerry Platform Services (BPS) APIs.

 

bps_architecture.png

Figure 2 NFC Tool Architecture

 

 

BPS accepts registrations and requests from NFC Tool and in return delivers events signifying events such as, say,

 

  • An NDEF Tag of Type XYZ has just been presented to the device
  • An ISO 14443-A target (tag or another NFC device) has been presented to the device

 

NFC Tool then  makes decisions as to whether to read and display the information or to interact with the target.

 

The important point to note is that NFC Tool uses the BPS directly to interact with the NFC target. This has consequences in that interaction with BPS has to take place on a separate event thread in order to prevent Qt events from blocking on waits in BPS. This is all part and parcel of the NFC Tool sample application and if you have read the articles on this you will be familiar with this model where much of the heavy lifting has to be done by the application itself.

 

The Invocation Framework, together with new capabilities that have been added to Cascades and QML, offer developers a new way to incorporate NFC functionality in their applications which does not require the direct use of the BPS APIs and in general should require significantly less C/C++ code to be written.  NFC Tool Lite illustrates this alternate approach and shall be discussed next. It should be noted that the two approaches remain valid but with each having its own set of pros and cons. We’ll close by discussing the factors that developers should use in deciding which of our two approaches to use for a given application. 

 

Architecture of NFC Tool Lite

 

Figure 3 below shows conceptually how NFC Tool Lite differs from its sibling NFC Tool. The key point to note is that NFC Tool Lite does not interact directly with BPS. Instead it communicates with the Invocation Framework

 

nfctoollite arch.png

Figure 3 Architecture of NFC Tool Lite

 

The IF performs the functions of locating other applications that understand how to interact with NFC as well as providing a channel across which data which has been, say, read from a tag, is presented to NFC Tool Lite. It also allows NFC Tool Lite to send NDEF formatted data that is, for example, destined for a tag or another peer-to-peer device.

 

In fact in this model NFC Tool Lite plays two roles in regards to the IF.

 

  1. In one role it acts as a client of the IF in that when it wants to write NDEF data to a tag or a peer-to-peer device the IF locates and establishes a channel to the helper application that can write data to the tag or device on its behalf.
  2. In the other role NFC Tool Lite actually acts as a helper application in its own right. It registers as a helper application with IF that understands how to receive and process NDEF messages that have been read from a tag by the NFC stack. So, when a tag is presented to the device it is notified and the NDEF message payload is delivered to it.

This fact that an application can play multiple roles simultaneously in regards to the IF is an important concept to grasp. It also simplifies enormously the logic in the application. Applications that exploit the Invocation Framework can use other applications to do the heavy lifting.

 

So, how much of NFC Tool has changed in its transition to become NFC Tool Lite? Let’s take a look now.

 

Changes between NFC Tool and NFC Tool Lite

 

Figure 4shows the changes between NFC Tool and its lighter sibling NFC Tool Lite. On the left is NFC Tool where the main changes have been:

 

  1. Removal of the NfcManager and NfcWorker classes – the IF is used to perform these tasks instead in NFC Tool Lite.
  2. The C/C++ classes that have backed the QML corresponding files have disappeared and much of the logic that was in them has been converted to JavaScript® within the associated QML files instead. The exception is the MainMenu class which is still used as the root of the menu structure.
  3. The other classes are unchanged in that they support the Eventlog screen with its underpinning DataModel.

  

src_before_after.png

Figure 4 Comparing NFC Tool files and NFC Tool Lite files

 

On the NFC Tool Lite side on the right you can see that it’s much lighter weight. The one addition is NdefFactory which is a class that will deliver NDEF Message data in the form of a QByteArray on demand for all of the NDEF Messages we want to construct to send via IF to the helper application to write to a tag or a peer-to-peer capable device.

  

The QML files in the project all still exist but many, in particular the ones that collect information from the user in order to have it written to a tag or peer-to-peer device, have been modified to accommodate the new model.

  

NFC Tool Lite Design and Implementation

  

Before we get into the NFC aspects of NFC Tool Lite , let’s review the basic design and implementation approach taken for this application. Figure 5 gives an overview of the basic flow between pages. Note that not all pages are shown.

 

ui_flow.png

 

Figure 5 NFC Tool Lite Interface Overview

 

You’ll notice that the list of functions that NFC Tool Lite offers is not quite the same as for NFC Tool. Some NFC functions are well suited to the “lite” approach and some are not. We’ll revisit this later in the article. The full list of functions available in NFC Tool Lite are:

  

  1. Read – Read an NFC tag
  2. Write URI – Write a tag with well known type “U”
  3. Write Smart Poster – Write a tag with well known type “Sp”
  4. Write Text – Write a tag with well known type “T”
  5. Write Custom – Write a tag with “external” TNF and a custom type value
  6. Send vCard (SNEP)
  7. About – Show the about page with information about NFC Tool

  

With NFC Tool Lite, a difference in the user experience arises in each of the functions that write information to a tag and also in the peer-to-peer function. Instead of writing information directly to the tag or peer-to-peer device as soon as it is presented in the NFC field, and showing the transfer taking place through an EventLog screen (the way we did it with NFC Tool), an “Action Item” is instead invoked through the user pressing a button labelled “Share” at the foot of the screen in the navigation bar. This causes the invocation framework to act on our behalf and ultimately, to have our request processed by another application. In our particular case that other application is a standard but otherwise hidden “helper application” which is part of the BlackBerry 10 OS and provided specifically for this purpose. We’ll talk more about how this is achieved and what is going on behind the scenes later.

  

Once selected, the NFC helper application displays itself with instructions on how to complete the operation such as presenting a tag or peer-to-peer NFC device.

  

Reading NFC Tags using Invocation Framework

 

The original version of NFC Tool which we released for BlackBerry 10 beta 1 did not use the Invocation Framework for tag reading. As described above, it used BPS API calls and events. But when we saw that this had become possible when BlackBerry 10 beta 2 was released, we liked it so much we couldn’t resist refactoring NFC Tool to use this new approach to read tags. As such the latest NFC Tool in GitHub implements this approach and the original article on reading and writing NFC tags on BlackBerry 10 was updated to show this. As such we’ve already explained how to use the invocation framework to make reading tags easier.

 

See http://supportforums.blackberry.com/t5/Native-Development/NFC-on-BlackBerry-10-Reading-and-Writing-T... 

 

Writing NFC Tags using Invocation Framework and QML

 

 

Let’s consider how to write a tag using the invocation framework and QML.

  

NFC Tool and NFC Tool Lite allow four different types of tag content to be written:

  

  • A URI Tag – this consists of a single URI such as http://www.rim.com
  • A Text Tag—this consists of a single string of readable text such as “Hello, NFC!”
  • A Smart Poster Tag – this consists of a URI, like in a URI tag, and one or more text annotations describing the URI that can be in different languages
  • A Custom Tag – this consists of a unique domain (usually a DNS domain like “my.domain.com”) that identifies the tag as being specific to this organization and a type ( like “myownrecord” ). Together these identify a unique namespace to prevent clashes with tags from other organizations. Lastly, an arbitrary payload completely determined by the use you wish to make of the tag.

  

In addition, peer-to-peer communication where an NDEF Message can be sent using SNEP can also be achieved using the same APIs from the Invocation Framework.

  

  • The example that was incorporated into NFC Tool originally was to send a vCard to another NFC capable device. This is incorporated into NFC Tool Lite but this time using the Invocation Framework.

   

A recipe for writing NFC tags using invocation framework and QML

  

All writing of NDEF Message data to tags or peer-to-peer NFC devices can be achieved through the same four steps driven from the user Interface in Cascades QML.

 

write_recipe.png

 

Figure 6 Recipe for Writing NFC Tags using IF and QML

 

Step 1 – Add an InvokeActionItem to a QML Page component

The pattern is identical for writing all the NDEF Message types we’ve come across at this time including the peer-to-peer vCard example so we’ll focus on the single example of writing a “Text” NDEF Message since that can be extrapolated trivially to the other cases.

 

	actions: [
        InvokeActionItem {
            id: sharedNdefData
	        ActionBar.placement: ActionBarPlacement.OnBar
            query {
                mimeType: "application/vnd.rim.nfc.ndef"
                invokeActionId: "bb.action.SHARE"
            }
            handler: InvokeHandler {
                id: shareHandler
                onInvoking: {
                    sharedNdefData.data = _ndefFactory.getNdefTextMessage("en", writeText.ndefText);
                    shareHandler.confirm();
                }
            }
        }
	]

 Figure 7 Adding an InvokeActionItem to a QML page

  

Figure 7 shows how this is achieved in the write_text.qml file that handles the case of writing a Text NDEF Message to a tag. The actual page itself is shown below in Figure 8.

 

Write Text.png

 

Figure 8 The Page used to write a tag using Invoke

 

The InvokeActionItemcontains an attribute called query. This represents the query that will be constructed by the IF in order to locate another application that will handle the writing of NDEF Messages to tags and peer-to-peer NFC devices for us.

 

The fact that we are interested in sending data to such an application is identified by the invokeActionId: "bb.action.SHARE" attribute. We intend to “share” data with another application which understands the data we will send as being of a specific MIME type. In particular as specified by the mimeType: "application/vnd.rim.nfc.ndef” attribute.

 

We’ve seen these MIME types before in the bar-descriptor.xml file. In that case we were registering that we were willing to accept data of this MIME type. In this case we’re searching ( “querying” ) for other applications that can help us handle this MIME type for NDEF Messages.

 

Step 2 – Provide an InvokeHandler for the InvokeActionItem

This is a handler in the write_text.qml file associated with the InvokeActionItem we just created. This is what launches the query and locates other registered applications that are prepared to handle NDEF Messages to be written to tags or peer-to-peer devices.

 

        InvokeActionItem {
         .......
            handler: InvokeHandler {
                id: shareHandler
                onInvoking: {
                    sharedNdefData.data = _ndefFactory.getNdefTextMessage("en", writeText.ndefText);
                    shareHandler.confirm();
                }
            }
        }

 Figure 9 InvokeActionItem and its InvokeHandler

 

We can see from Figure 9 that there is an event handler called onInvoking which is called by the invoke action item when it is ready to invoke the target. This results in the following page being displayed by the default NFC Helper application:

 

Sharing Page.png

Figure 10 NFC Helper application screen

 

Step 3 – Build an NDEF Message for the InvokeActionItem

 

We build NDEF Messages for various uses by using a class we wrote called NdefFactory. Here’s the signature and definition of the method that will build an NDEF Text Message using QtMobilitySubset. It must be declared as Q_INVOKABLE to allow it to be called from JavaScript in QML and as such has a QVariant as argument.

  

Q_INVOKABLE QByteArray getNdefTextMessage(const QVariant &text, const QVariant &text);
....
QByteArray NdefFactory::getNdefTextMessage(const QVariant &lang, const QVariant &text) {
    QString ndefLang = lang.toString();
    QString ndefText = text.toString();
    QtMobilitySubset::QNdefRecord ndefRecord = QtMobilitySubset::QNdefRecord();
    int langLength = (ndefLang.length() <= 63) ? ndefLang.length() : 63;
    QByteArray ndefPayload;
    ndefPayload[0] = langLength;
    ndefPayload.append(ndefLang.left(langLength)).append(ndefText.toUtf8());
    ndefRecord.setTypeNameFormat(QtMobilitySubset::QNdefRecord::NfcRtd);
    ndefRecord.setType(Settings::NfcRtdText);
    ndefRecord.setPayload(ndefPayload);
    QtMobilitySubset::QNdefMessage ndefMessage =     QtMobilitySubset::QndefMessage(ndefRecord);
	return ndefMessage.toByteArray();
}

 Figure 11 The Q_INVOKABLE function used to build a Text NDEF Message

  

Step 4 – Pass the NDEF Message to the InvokeActionItem

Back in the write_text.qml file the NDEF Message data is retrieved from the NdefFactory and the returned QByteArray is assigned to the “data” attribute of the InvokeActionItem associated with this event. In effect we’re passing the NDEF Message to the helper application.

 

Button {
...
    contextMenuHandler: ContextMenuHandler {
        onShowing: {
            sharedNdefData.data =
               _ndefFactory.getNdefTextMessage(writeText.ndefText);
        }
    }
}

 Figure 12 Context Menu Handler

 

Exactly the same process has been followed for all the other features in this application including writing of URI, Smart and Custom tags as well as sharing of vCard data across a SNEP connection.

 

Tying up Some Loose Ends

 

Now, at this point, you should be thinking to yourself; “This is cool and simple! I can perform many NFC operations without needing to handle the low level heavy lifting myself!”. But it’s possible you’ve also absorbed the fact that there are now two distinct ways of implementing NFC operations in a BlackBerry 10 native application and perhaps you find that confusing or simply a little odd. So we’ll close our article by considering the two approaches and how you might decide which to use for your particular application.

 

Decision time: BlackBerry Platform Services or Invocation Framework and QML?

 

If you’ve got this far and especially if you’ve read the original article on reading and writing tags for BlackBerry 10, you should now be very aware that you have a choice as to how you go about implementing NFC operations in a native application. In broad terms you can either:

 

  1. Use the BlackBerry Platform Services APIs direct from C++. We’ll call this “the BPS approach”. Or
  2. Use the Invocation Framework and QML. We’ll call this “the IF/QML approach”.

Let’s briefly consider the pros and cons of the two and how to go about deciding which approach to use.

 

Approach Pros Cons Notes
BPS

You have complete control over everything but especially the user experience. No “extra screens” from the system or other applications are involved. The user’s interaction with your app should be exactly as you want it to be.

 

You can do anything. Anything that’s possible anyway!

You could find yourself writing quite a lot of C/C++ code. Certainly, as hopefully this article has demonstrated clearly, there will be much more code required than if you did them same thing with the IF/QML approach.

  

You’ll need to be aware of and take care of the need to use a background thread to avoid blocking other operations in your application.

You can use a couple of different patterns with BPS; either an event loop as shown in NFC Tool or you can use the AbstractBpsEventHandler class for a more object oriented pattern.
IF/QML Much less code to write. You need to write a fraction of the code you’d need with the BPS approach. Not surprising since in reality you’re exploiting the code written by someone else in another application.

User experience compromise. You’ll need to be OK with letting the helper application selected by IF insert itself in your user experience with an extra screen (at least). It’s also necessary that you hook your invocation request into something like a Button component or the action bar so that the user must interact with your UI explicitly to trigger the IF action. This will be fine for some applications but not all.

 

You can’t do everything. Not all NFC use cases/operations are available via the IF/QML approach whereas from the BPS approach they are. Examples include ISO7816-4 interactions with the secure element and in fact card emulation in general; Virtual target emulation; ISO15693 tag reading and writing.

Reading tags using the Invocation Framework still requires C++ coding but it’s pretty easy. Also, you still need to use C++ to create NDEF message content as illustrated with our NdefFactory class.

 

Summary

We hope that this article helps you exploit NFC on BlackBerry 10 in the easiest possible way, through the Invocation Framework and QML and that our exploration of the more general design and implementation aspects of our sample application “NFC Tool Lite” are useful in helping you get started with BlackBerry 10 application development using C++, Qt and Cascades.

You can download NFC Tool Lite, including its full source code from:

https://github.com/blackberry/Cascades-Community-Samples

 

NFC Tool Lite was written for the BlackBerry 10 "Dev Alpha" device and requires the following versions of the NDK and device software to build and run:

 

• BlackBerry 10 Native SDK 10.0.9 (beta 3)
• BlackBerry Dev Alpha Device Software 10.0.9 (beta 3)

 

You can find details of other NFC related articles and sample applications written by Martin and John at:

NFC Article and Code Index

You can contact Martin or John either through the BlackBerry support forums or through Twitter®:

 

 

  Support Forum ID Twitter
Martin mwoolley @mdwrim
John jomurray @jcmrim
Contributors