Card invocation

Cards enhance the invocation framework's capabilities by allowing applications to share the UI and the application logic with other applications. You send a request to invoke a card in the same way as an invocation request for an application, which means that everything that you learned about sending an invocation request applies to cards as well.

Here's how you can use the invocation framework to import a card from another application:

// Create and send an invocation for the card target
InvokeManager* invokeManager = new InvokeManager();
InvokeRequest cardRequest;
cardRequest.setTarget("com.example.myapp");
cardRequest.setAction("bb.action.VIEW");
cardRequest.setMimeType("image/png");
cardRequest.setUri("file://path/to/document.pdf");
InvokeTargetReply* reply = invokeManager->invoke(cardRequest);
reply->setParent(this);  

Before a new card is invoked and allowed to be stacked, the platform verifies that the client application is not already parenting a card. Unlike an application, a card may continue to exist in multiple instances, but a parent application (or a card) can parent only one card at a time. This is important to consider, since multiple instances of a card may be running at the same time.

Cards support a "fire and forget" import model. However, for applications that require notifications and additional feedback, cards also provide peek notifications and response data.

Listen for peek events

Cards offer a parent card or an application the ability to receive notifications when a user peeks at another card. This is important if you want your application to display content differently during a peek event. Here is how you can enable your application to listen for peek events:

// connect peekStarted and peekEnded signals.
                
                
// If any Q_ASSERT statement(s) indicate that the slot failed to connect to 
// the signal, make sure you know exactly why this has happened. This is not
// normal, and will cause your app to stop working!!
bool connectResult;

// Since the variable is not used in the app, this is added to avoid a 
// compiler warning.
Q_UNUSED(connectResult);

connectResult = QObject::connect(invokeManager, SIGNAL(peekStarted(bb::system::CardPeek::Type)), 
                                 parent,        SLOT(peekStarted(bb::system::CardPeek::Type)));
// This is only available in Debug builds.
Q_ASSERT(connectResult);
 
connectResult = QObject::connect(invokeManager, SIGNAL(peekEnded()),
                                 parent,        SLOT(peekEnded()));
// This is only available in Debug builds.
Q_ASSERT(connectResult);

...
  
void peekStarted(bb::system::CardPeek::Type peekType)
{
    // If needed adjust the content based on peek type (parent peek/root peek).
}
  
void peekEnded()
{
    // Revert to non peek state.
}

Listen for a card response message

A card can send a response message to the parent application when a card completes its task. For example, a picker card can return the data, that a user selects, to the client application. Here's how you can listen for card response messages:

// If any Q_ASSERT statement(s) indicate that the slot failed to connect to 
// the signal, make sure you know exactly why this has happened. This is not
// normal, and will cause your app to stop working!!
bool connectResult;

// Since the variable is not used in the app, this is added to avoid a 
// compiler warning.
Q_UNUSED(connectResult);

connectResult = connect(invokeManager, SIGNAL(childCardDone(const bb::system::CardDoneMessage&)), 
                        this,          SLOT(childCardDone(const bb::system::CardDoneMessage&)));
                        
// This is only available in Debug builds.
Q_ASSERT(connectResult);

void App::childCardDone(const bb::system::CardDoneMessage &message)
{
    // Read message here.
}

Typical card usage for previewers and many composers does not involve a response. Therefore, a best practice is to design your previewer and composer cards in such a way that any response is optional.

Close a card

An application may request to close a card that it imported. As a result the card is transitioned off screen. When a user closes the card, both the application and the card are notified. However, if the card is closed by the application itself, the card cannot provide a response. Also, when an application closes a card, it closes the entire stack of cards (including children of the card) above it. Here's how your application can request to close a child card:

invokeManager->closeChildCard();

Last modified: 2014-04-10

comments powered by Disqus