QML and BBM. Together at last… Part 2

QML and BBM. Together at last… Part 2

Unlock BBM for your QML app

UPDATE: Beta 4 + Gold Release 
BBM Sample Code
Since Beta 4 there has been some BBM design changes and it seems like these changes didn’t effect existing apps (like HelloBBM) until the Gold release today. There’s been quite a few changes and actually the samples are very nicely done and can be found here.

However, HelloBBM was created to show a more real world example of using some essential BBM functionality and since that’s still appropriate I’ve updated the sample code. This was pretty much a complete rewrite, mainly because I thought the new samples were so nicely done I couldn’t pass up the opportunity to redesign instead of patching. Below are some of the main changes but please visit the code for more details…

Overall design
Basically, I’m now using a registration.qml file which will be the page that users first see only if there’s some type of error, such as BBM registration failed or no internet access. If this happens you’ll notice a status message and a button which the user can use to try to reconnect to BBM. If however, BBM registration is successful it automatically transitions into your main.qml file. Once successful, the registration process will be by passed the next time the app is opened – changes introduced in Beta 4.

Main.cpp file
This is probably the most interesting change because it shows the bigger design change and effects all other files in the sample. I’ve tried to add extra comments in the code and provide a stripped down version of the community samples but if you have any questions or suggestions please let me know.

Disclaimer: I’m not an expert in C++, QML or software design :)

  1. main.cpp (entry point)
  2. registration code gets called (c++ and qml)
  3. registration successful – return and call appName.cpp file (C++ and main.qml)
  4. registration failed – registration.qml remains and provides user ability to try to reconnect (not required dependent on type of app)
    // this is where the server is started etc
    Application app(argc, argv);

    // localization support
    QTranslator translator;
    QString locale_string = QLocale().name();
    QString filename = QString( "HelloBBM_%1" ).arg( locale_string );
    if (translator.load(filename, "app/native/qm")) {
        app.installTranslator( &translator );
    }

    // Every application is required to have its own unique UUID. You should
    // keep using the same UUID when you release a new version of your application.
    //TODO:  YOU MUST CHANGE THIS UUID!
    // You can generate one here: http://www.guidgenerator.com/
    const QUuid uuid(QLatin1String("c845ff98-303b-4800-b2a3-a54f14bda5ff"));

    //Setup BBM registration handler
    RegistrationHandler *registrationHandler = new RegistrationHandler(uuid, &app);

    //AppName.cpp file which contains your main.qml file
    HelloBBM *helloBBM = new HelloBBM(registrationHandler->context(), &app);

    // Whenever the registration has finished successfully, we continue to the main UI
    // Added finishRegistration() to registrationFinished()
    // This is to emit signal and by pass use of continue button as shown in sample
    QObject::connect(registrationHandler, SIGNAL(registered()), helloBBM, SLOT(show()));

    // we complete the transaction started in the app constructor and start the client event loop here
    return Application::exec();

 

UPDATE:  Beta 3
I’ve made a sample project for the article below. It’s open source so please feel free to take, use and modify - BBM Sample Code

From my last post – QML and BBM. Together at last. – we went over how you can integrate QML and BBM from the samples BlackBerry provided. That was only high level but all of the essentials were there. However looking back at it, and having it pointed out to me as well, if you’re new to QML, adding C++ to the mix can be a deadly combination. I know! I’ve felt it myself. And I’d like to shorten the learning curve for others as so many have done for me in the past.

On that note, I’d like to share some of my app code…now, I can’t go and give it all away, after all I’m hoping to get a 10k stamp of approval from the folks bring Built for BlackBerry to life and if we all make X & O games only the first one in will get that stamp :)

Okay, lets get started…
Registration.cpp file

//header stuff
...

RegistrationHandler::RegistrationHandler()
{
// Attempt to register the application with the following UUID.
// Define your own UUID here.  You can generate one here: http://www.guidgenerator.com/
m_uuid = QString::fromUtf8("f6ffc443-c55b-4f19-aef6-123456789000");
// this->appRegister();
}

void RegistrationHandler::appRegister()
{
LOG("appRegister");
m_context = new bb::platform::bbm::Context(QUuid(m_uuid));
Global::instance()->setContext(m_context);
QObject::connect(m_context, SIGNAL(registrationStateUpdated(bb::platform::bbm::RegistrationState::Type)),
this, SLOT(registrationStatus(bb::platform::bbm::RegistrationState::Type)));
m_context->requestRegisterApplication();
}

void RegistrationHandler::checkRegistrationAccess(){
LOG("checkRegistrationAccess");
bb::platform::bbm::RegistrationState::Type status = bb::platform::bbm::RegistrationState::Unknown;
if (Global::instance()->getContext()) {
status = Global::instance()->getContext()->registrationState();
}
registrationStatus(status);
}

void RegistrationHandler::registrationStatus(bb::platform::bbm::RegistrationState::Type state) {
LOG("registrationStatus: %i", state);

switch(state){
case bb::platform::bbm::RegistrationState::Unregistered:
this->registrationFailed();
break;
case bb::platform::bbm::RegistrationState::Unknown:
this->registrationFailed();
break;
case bb::platform::bbm::RegistrationState::Allowed:
 LOG("BBM SP registration succeeded");
break;
...
}

void RegistrationHandler::registrationFailed() // update to accept string to id the exact error for user
{
LOG("registrationFailed");
//You could provide a different error msg for each failure code to instruct the user on how to continue.
}

That’s basically it for this file. Now for the appName.cpp file…Disclaimer: I’m not an expert in C++, QML or software design so if you have suggestions please write a comment and help improve the code.

appName.hpp file
What I’m doing: Setting up some #define so that I can easily call methods from a switch/case and have all BBM code in one area. This will allow me to plug-n play any new code and easily make updates.

#include "Global.hpp"
#include "RegistrationHandler.hpp"
#include "UpdateProfilePage.hpp"
#include "InviteToDownload.hpp"
...

ProfileBox *profileBox;
RegistrationHandler* regBBM;
InviteToDownload *inviteToDownload;
UpdateProfilePage *updateProfilePage;
bb::platform::bbm::UserProfile * m_userProfile;

appName.cpp file

#define REGISTERBBM 4
#define PROFILEBOX 5
#define PRESONALMESSAGE 6
#define STATUSMESSAGE 7
#define INVITETODOWNLOAD 8
...

appName::appName(bb::cascades::Application *app) :
QObject(app) {
...
//normal qml stuff like QmlDocument::create("asset:///main.qml");
...
ControlsForBBM(REGISTERBBM);
Application::instance()->setScene(appPage);
}

...

void appName::ControlsForBBM(int state) {

  switch (state) {
        case REGISTERBBM: {
                regBBM = new RegistrationHandler();
                regBBM->appRegister();
                break;
        }
        case PROFILEBOXPUZZLE: {
                profileBox = new ProfileBox();
                profileBox->createItem(msg);
                break;
        }
        case PRESONALMESSAGE: {
                updateProfilePage = new UpdateProfilePage(m_userProfile);
                updateProfilePage->savePersonalMessage();
                break;
        }
        case STATUSMESSAGE: {
                updateProfilePage = new UpdateProfilePage(m_userProfile);
                updateProfilePage->saveStatus();
                break;
        }
        case INVITETODOWNLOAD: {
                inviteToDownload = new InviteToDownload();
                inviteToDownload->sendInvite();
                break;
        }
  }

}

Done and done.
So that’s it. Strip out the QML from Registration file and in your appName.cpp file create method (in my case using a switch statement) that calls which ever BBM functionality you or your user requests. In the scenario above, I automatically register BBM and also set the application ProfileBox. But user interaction is required for updating personal message and status messages. In these cases I’ve added Q_INVOKABLE methods and UI buttons for the user to access this functionality.

Let me know your thoughts. Thanks.