Using IM API
In order to use IM API, the client has to create a connection using an
own unique application ID and log in to the remote IM server. After creating
the interface objects, the user application has to register its observers
using the corresponding method from each interface class. This is necessary
because the methods of this API are non-blocking and the notification when
the operation is complete is delivered through the observer methods. Each
asynchronous operation returns an operation ID when the request is issued.
When the operation ends, the observer method is called with the operation
ID to map it back to the corresponding request.
Creating the connection and registering the observer
Creating
CImConnection
involves the ECom framework. ECom
loads imclient.dll, which contains the API implementation. If the implementation
is not found the NewL()
method leaves with KErrNotFound
.
After the object is created, the user has to register its implementation of
the MImConnectionObserver
interface.
The client application has to have an application ID, which is supposed
to be unique in the domain of the application using the instant messaging
services. The application ID is given in the
NewL()
method.
That ID is used in routing the instant messages to the correct application
in case the session to the IM server is shared between two or more applications.
Registering can be done only once, a subsequent registration without unregistration
leads to an error.
An application ID can be defined as a literal, e.g.:
_LIT(KMyApplicationId, “MyIMApplication”);
Example code:
void CSDKExample1AppUi::ConstructL()
{
BaseConstructL( );
iAppContainer = new (ELeave) CSDKExample1Container;
iAppContainer->SetMopParent( this );
iAppContainer->ConstructL( ClientRect( ) );
AddToStackL( iAppContainer );
// Create an instance of the connection.
// If the plugin is not found the eCom will leave with KErrNotFound
iMyImConnection = CImConnection::NewL( KMyApplicationId );
}
Related APIs
CImConnection
KErrNotFound
MImConnectionObserver
NewL()
Logging in
After the
CImConnection
object is created the client application
has to log in. Logging in is done using the IM server URL, user ID, password
and the access point ID that is intended to be used. In case there already
is an existing session with the same user parameters that session is shared.
Example code:
void CSDKExample1AppUi::TestConnectL ( )
{
_LIT(KServer, “http://impsdomain.com:8080/wv”);
_LIT(KUserId, “wv:somebody@impsdomain.com”);
_LIT(KPassword, ”secret”);
TRAPD(err,iMyImConnection->LoginL(
KServer,
KUserId,
KPassowrd,
0)); // use existing AP!!!
if ( err != KErrNone )
{
// Failed to start the registration
CAknErrorNote* note = new(ELeave) CAknErrorNote();
TBuf<0x100> buf;
buf.Format( _L("Login failed:( %i )"), err );
note->ExecuteLD( buf );
}
}
The
HandleLoginL
method is implemented by the client.
It is called when LoginL()
is completed.
void CSDKExample1AppUi::HandleLoginL( const TInt aErrorCode )
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::ELongTimeout );
TBuf<0x100> buf;
buf.Format( _L("HandleLoginL( %i )"), aErrorCode );
note->ExecuteLD( buf );
}
Related APIs
CImConnection
HandleLoginL
LoginL()
Canceling the ongoing login
If the login operation is not yet finished, there is a possibility to cancel
it. If the login was not yet started or it is finished already the method
will leave with an appropriate error code. The method is asynchronous and
will complete by calling the corresponding observer method.
The
HandleCancelLoginL
method is implemented by the client.
It is called when CancelLoginL
is completed.
Example code:
void CSDKExample1AppUi::HandleCancelLoginL( const TInt aErrorCode )
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::ELongTimeout );
TBuf<0x100> buf;
buf.Format( _L("HandleCancelLoginL( %i )"), aErrorCode );
note->ExecuteLD( buf );
}
Related APIs
CancelLoginL
HandleCancelLoginL
Logging out
After a successful login the connection can be closed by starting a logout
procedure. If calling the method when not logged in it will leave with an
appropriate error code. The method is asynchronous and will complete by calling
the corresponding observer method.
HandleLogoutL
method is implemented by the client. It
is called when LogoutL
is completed.
Example code:
void CSDKExample1AppUi::HandleLogoutL( const TInt aErrorCode )
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::EShortTimeout );
TBuf<0x100> buf;
buf.Format( _L("HandleLogoutL( %i )"), aErrorCode);
note->ExecuteLD( buf );
}
Related APIs
Unregistering the connection observer
By unregistering the connection observer all the connection related ongoing
tasks are cancelled. It is advised that when login is ongoing or already logged
in, first cancel the login, or logout before unregistering the connection
observer.
Creating IM client and registering the observer
Creating the
MImClient
interface is needed when the user
wants to send and receive instant messages. After the creation is successful
the user has to register its IM observer. Without registering that observer
it is not even possible to send a point-to-point message because the notification
about the sending is delivered through the HandleMessageSentL()
observer
method.
The
CreateImClientL
method creates the IM Client interface.
A pointer is returned to the object. It is the client’s responsibility to
destroy the object.
Example code:
void CSDKExample1AppUi::TestCreacteImClientL()
{
TRAPD(err,iMyImClient = iMyImConnection->CreateImClientL());
// Failed to create IM Interface
if ( err != KErrNone )
{
CAknErrorNote* note = new(ELeave) CAknErrorNote();
note->ExecuteLD(_L("No IM Interface!"));
}
}
Before using the methods in the
MImClient
interface, the
observer must be registered successfully to IM API using the RegisterObserverL
method.
Example code:
void CSDKExample1AppUi::TestRegisterImObserverL()
{
TRAPD(err, iMyImClient->RegisterObserverL( this ) );
if( err != KErrNone )
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::ELongTimeout );
TBuf<0x100> buf;
buf.Format( _L("Registering failed with %d"),ret );
note->ExecuteLD( buf );
}
}
Related APIs
CreateImClientL
HandleMessageSentL()
MImClient
RegisterObserverL
Sending a point-to-point message
Sending a point-to-point message is possible by using a user ID (e.g. WV
user ID) or contact model ID from the contacts DB. In the latter case the
IM API translates the recipient’s address to the corresponding protocol user
ID. In case the contact ID given in the method does not have a user ID in
its fields, the error code
KImApiErrInvalidContactId
is returned
by a leave mechanism.
In case there are more contact IDs in the recipient list and for example
one does not have a user ID, this one is silently removed from the list and
a message sending is attempted to the other recipients. In case the recipient
was addressed directly with a user ID the validity of the ID is checked only
in the remote IMPS server. Therefore the error code can be delivered only
to the observer object by the
HandleSendErrorL()
method.
For more information on error handling, see Section Error handling
It is not possible to send several point-to-point messages in the same
active object scheduling round, e.g. calling
SendPToPMessageL()
several
times one after another in the same function, due to some limitations in the
protocol stack. That kind of usage leads to the error KErrServerBusy
.
The
SendPToPMessageL
method has two prototypes. Textual
instant messages can be sent using contact model IDs or directly a user ID.
This method is asynchronous and HandleMessageSentL()
or HandleSendErrorL()
is
called when completed.
This method returns an operation ID. Please note that only one message
can be sent during an active object scheduling round, which means for example
that the
SendPToPMessageL
method cannot be called subsequently
in one function.
Example code:
Example code of sending with contact IDsvoid CSDKExample1AppUi::TestSendPToPMessageContactL()
{
// Select contact from the Contacts Model
_LIT(KWVStart, "");
// Specify in which fields search should be performed
CContactItemFieldDef* fieldToSearchIn = new (ELeave) CContactItemFieldDef();
CleanupStack::PushL( fieldToSearchIn );
fieldToSearchIn->AppendL( KUidContactFieldVCardMapWV );
// search in contact database
CContactIdArray *myContactArray = iMyContacts->FindLC(KWVStart, fieldToSearchIn );
// Call the method
TRAPD(err, iMyImClient->SendPToPMessageL(*myContactArray, _L("Hi there!"));
if ( err != KErrNone )
{
CAknErrorNote* note = new(ELeave) CAknErrorNote();
note->ExecuteLD(_L("Sending failed"));
}
CleanupStack::PopAndDestroy( 2 ); // fieldToSearchn, myContactArray
}
Example code of sending with user IDs:void CSDKExample1AppUi::TestSendPToPMessageContactL()
{
CDesCArray* userIds = new(ELeave) CDesCArrayFlat(4);
CleanupStack::PushL(userIds);
userIds->AppendL(_L("wv:user1@impsdomain.com"));
userIds->AppendL(_L("wv:user2@impsdomain.com"));
userIds->AppendL(_L("wv:user3@impsdomain.com"));
userIds->AppendL(_L("wv:user4@impsdomain.com"));
// Call the method
TRAPD(err, iMyImClient->SendPToPMessageL(*userIds, _L("Hi there!"));
if ( err != KErrNone )
{
CAknErrorNote* note = new(ELeave) CAknErrorNote();
note->ExecuteLD(_L("Sending failed"));
}
CleanupStack::PopAndDestroy( ); // userIds
}
HandleMessageSentL()
is implemented by client and it is
called when SendPToPMessageL
is completed.
Example code:
void CSDKExample1AppUi:: HandleMessageSentL(const TInt aOpCode,
const TInt aErrorCode)
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::EShortTimeout );
TBuf<0x100> buf;
buf.Format( _L("HandleMessageSentL( %i )"), aErrorCode );
note->ExecuteLD( buf );
}
HandleSendErrorL
method is implemented by the client.
It is called when SendPToPMessageL
is completed with an error.
If the error is KImApiErrPartialSuccess
the detailed list
of failed user IDs can be fetched using the MImClientDetailedError
interface
.
Example code:
void CSDKExample1AppUi:: HandleSendErrorL(const TInt aOpCode,
const TInt aErrorCode,
MImClientDetailedError* aDetailedError);
{
CAknInformationNote* note = new (ELeave) CAknInformationNote( EFalse );
note->SetTimeout( CAknNoteDialog::EShortTimeout );
TBuf<0x100> buf;
buf.Format( _L("HandleSendErrorL( %i )"), aErrorCode );
note->ExecuteLD( buf );
if ( aDetailedError )
{
_LIT(KMessage, "Failed contacts:");
TPtrC ptr(KMessage);
CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(ptr);
CleanupStack::PushL(dlg); // << dlg
dlg->PrepareLC(R_MESSAGE_QUERY);
dlg->QueryHeading()->SetTextL(_L("Failed contacts"));
buf.FillZ();
// iterate through the failed users list
for(TInt i(0); i < aDetailedError->Count(); ++i)
{
// read the ith user
buf.AppendFormat(_L("%S %d:\n"),
& aDetailedError>UserId(i),
aDetailedError->ErrorCode(i));
}
dlg->SetMessageTextL(buf);
dlg->RunLD();
CleanupStack::Pop(); // >> dlg
}
Related APIs
HandleMessageSentL()
HandleSendErrorL
HandleSendErrorL()
KErrServerBusy
KImApiErrInvalidContactId
KImApiErrPartialSuccess
SendPToPMessageL
SendPToPMessageL()
Receiving a point-to-point message
New point-to-point messages are delivered to the IM observer method
HandleNewPToPMessage()
.
Example code:
Example code for textual messagesvoid CSDKExample1AppUi::HandleNewPToPMessageL(
const TInt aErrorCode,
const TContactItemId aContactId,
const TDesC& aUserId,
const TDesC& aMessageType,
const TDesC16& aContent )
{
TBuf<0x100> buf;
_LIT(KMessage, "New Message");
TPtrC ptr(KMessage);
CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(ptr);
dlg->PrepareLC(R_MESSAGE_QUERY);
// Show the sender user
buf.AppendFormat(_L("from %S"), & aUserId);
dlg->QueryHeading()->SetTextL(buf);
buf.FillZ();
// show the message itself
if( aMessageType.Compare(_L("text/plain")) == 0 )
dlg->SetMessageTextL(aContent);
else
{
buf.Append(_L("Message content cannot be showed!"));
dlg->SetMessageTextL(buf);
}
dlg->RunLD();
}
Related APIs
Receiving partial success
In case that one or more user IDs were incorrect for some reason
KImApiErrPartialSuccess
is
returned in the HandleSendErrorL()
observer method. In that
case the user is able to fetch the failure reasons for each failed user ID.
The user IDs are not converted back to contact IDs if the contact IDs were
used in sending the instant message.
Related APIs
HandleSendErrorL()
KImApiErrPartialSuccess
Unregistering the IM observer
By unregistering the observer all the pending requests are cancelled.