nexmo-iOS v.1.2.3

Fixed

  • conversation.getEvents returned some NXMEvents containing a nil fromMember
  • Added descriptive userInfo for NXMErrors.

nexmo-android v1.2.0

Added

  • Add filter by EventType in NexmoConversation.getEvents
    NexmoConversation myConversation
    //Get all text event for a specifc conversation
    myConversation.getEvents(10, NexmoPageOrderDesc, "text", new NexmoRequestListener<NexmoEventsPage> {
        void onError(@NonNull NexmoApiError error){
        }
        
        void onSuccess(@Nullable NexmoEventsPage result){
            Collection<NexmoEvent> textEvents =  result.getData()
        }
    });
    //Get all member event for a specifc conversation
    myConversation.getEvents(10, NexmoPageOrderDesc, "member:*", new NexmoRequestListener<NexmoEventsPage> {
        void onError(@NonNull NexmoApiError error){
        }
        
        void onSuccess(@Nullable NexmoEventsPage result){
            Collection<NexmoEvent> memberEvents =  result.getData()
        }
    });

Fixed

  • Support for DTLS in WebRTC

nexmo-iOS v1.2.2

Fixed

  • Added support for DTLS in WebRTC.
  • didReceiveCall and didReceiveConversation being called only once for the same call or conversation.
  • Added option to enable push notification with only one pushKit or userNotification token.
  • Fix for NXMClientConfig region URLs.
  • On login with invalid user, return NXMConnectionStatusReasonUserNotFound.
  • Added build architectures: armv7 and armv7s.

nexmo-iOS v1.2.1

NXMClientConfig *config = [[NXMClientConfig alloc] initWithApiUrl:restUrl
                                                     websocketUrl:wsUrl
                                                           ipsUrl:ipsUrl
                                                    iceServerUrls:iceUrls];
[NXMClient setConfiguration:config]

This configuration is optional and a default will be set if not specified.

Note: setConfiguration should be used before accessing NXMClient.shared.

Fixed

Corrected nil values for fromMember for NXMConversation events.

nexmo-android v1.1.0

Added

  • Add iceServerUrls parameters to NexmoClient.Builder

Fixes

  • Fix Push Notification incoming call issue

nexmo-iOS v1.2.0

Added

NXMClient's getConversationsPageWithSize:order:completionHandler: method to get conversations with paging.

NXMConversationsPage, which represents the retrieved page, provides the following instance methods

  • hasNextPage / hasPreviousPage to check if forward/backward page retrieval is possible and
  • nextPage: / previousPage: to asynchronously retrieve the next/previous page.

Changed

NXMClient's getConversationWithUUid:completionHandler: method's name typo (now called getConversationWithUuid:completionHandler:).

nexmo-iOS v1.1.1

Added

NXMClientConfig object in order to change data center configuration. How to use:

[NXMClient setConfiguration:NXMClientConfig.DC]

NXMClient setConfiguration is optional, configuration will set to a default value. Note: you most call setConfiguration method before using NXMClient.shared.

nexmo-javascript v6.0.6

Fixes

  • Add iceGatherOnlyOneCandidate config option and use to define path in icegathering process

nexmo-javascript v6.0.5

Fixes

  • Change ice gathering process to send sdp on first ice candidate gathered

nexmo-android v1.0.3

Changes

  • change signature of NexmoClient.login(), remove NexmoRequestListener<NexmoUser> parameter
nexmoClient = new NexmoClient.Builder().build(context);
nexmoClient.setConnectionListener(new NexmoConnectionListener() {
      @Override
      public void onConnectionStatusChange(ConnectionStatus connectionStatus, ConnectionStatusReason connectionStatusReason) {
          switch (connectionStatus){
            case CONNECTED:
                //the client is connected to the server - the login successed 
            case DISCONNECTED:
            case CONNECTING:
            case UNKNOWN:
                //the client is not connected to the server - the login failed/not yet successed 
        } 
      });
NexmoClient.login("MY_AUTH_TOKEN")

Fixed

  • fix NexmoConversation.sendAttachment bug
  • fix NexmoAttachmentEvent received from backend
  • fix race condition bug cause drop calls
  • fix bug in push notification

nexmo-javascript v6.0.4

Fixes

  • Remove remaining audio elements after transferring a call to a new conversation
  • Update conversation.invite() to not include empty user_id or user_name fields within the requests

nexmo-iOS v1.1.0

Fixed

  • iOS 13 push notifications support
  • Start server call stability
  • Receiving a DTMF event in call and conversation

Added

NXMConversationDelegate did receive DTMF event method:

- (void)conversation:(nonnull NXMConversation *)conversation didReceiveDTMFEvent:(nullable NXMDTMFEvent *)event;

Changed

NXMClient - client enable push notifications method changed. param pushKitToken - only for VoIP push (incoming calls). param userNotificationToken - all push types:

- (void)enablePushNotificationsWithPushKitToken:(nullable NSData *)pushKitToken
                          userNotificationToken:(nullable NSData *)userNotificationToken
                                      isSandbox:(BOOL)isSandbox
                              completionHandler:(void(^_Nullable)(NSError * _Nullable error))completionHandler;

nexmo-javascript v6.0.3

New

  • Added TypeScript definition files

Changes

  • Added options for customized logging levels in the console of debug, info,

nexmo-javascript v6.0.1

Changes

  • Removed media.record() function
  • Removed cache option from SDK, used for storing conversations and events
  • Removed automatic syncing of all individual conversations in login, when sync is lite or full

nexmo-javascript v6.0.0

Breaking Changes

  • Change return value of application.getConversations() to new ConversationsPage object
// iterate through conversations before
application
  .getConversations()
  .then((conversations) => {
    conversations.forEach(conversation => {
      render(conversation);
    })
  });
// iterate through conversations after
application
  .getConversations({ page_size: 20 })
  .then((conversations_page) => {
    conversations_page.items.forEach(conversation => {
      render(conversation);
    })
  });
  • Change return value of conversation.getEvents() to new EventsPage object
// iterate through events before
conversation
  .getEvents()
  .then((events) => {
    events.forEach(conversation => {
      render(conversation);
    })
  });
// iterate through events after
conversation
  .getEvents({ event_type: 'member:*' })
  .then((events_page) => {
    events_page.items.forEach(event => {
      render(event);
    })
  });
  • Rename method application.callPhone to application.callServer
  • Rename method application.call to application.inAppCall
  • Rename method call.createPhoneCall to call.createServerCall
  • Rename class Call to NXMCall
  • Rename class ConversationClient to NexmoClient
  • Rename class ConversationClientError to NexmoClientError
  • Rename files conversationClient.js and conversationClient.min.js to nexmoClient.js and nexmoClient.min.js
  • Deprecate member:call:state event (use instead member:call:status)
  • Remove automatic login in case of a websocket reconnection and emit the event

New

  • Send and listen for custom event types in a conversation.
//sending a custom event type to a conversation
conversation
  .sendCustomEvent({type: 'my_custom_event', body: { enabled: true }})
  .then((custom_event) => {
    console.log(event.body);
  });
//listening for a custom event type
conversation.on('my_custom_event', (from, event) => {
  console.log(event.body);
});
  • Add new PageConfig class for configuring settings for paginated requests
  • Add new Page class to wrap results of paginated requests
  • Add setup of default pagination configuration for conversations and events in ConversationClient initialization
  • Add wild card supported for filtering by event types using :* (eg. event_type: member:*)
new NexmoClient({
  conversations_page_config: {
    page_size: 25,
    order: 'asc'
    cursor: 'abc'
  },
  events_page_config: {
    page_size: 50,
    event_type: 'member:*'
  }
})
  • Add new ConversationsPage & EventsPage which extend Page class to wrap results of paginated requests for conversations and events
  • Add getNext() and getPrev() methods to ConversationsPage & EventsPage objects to fetch previous and next pages of conversations & events
  • Add 'conversations_page_last' param to application & 'events_page_last' param to conversation for reference to last page retrieved
application.conversations_page_last
  .getNext((conversations_page) => {
    conversations_page.items.forEach(conversation => {
      render(conversation)
    })
  })
conversation.events_page_last
  .getPrev((events_page) => {
    events_page.items.forEach(event => {
      render(event)
    })
  })
  • Add the ability to make an IP-IP call through callServer function
// IP-IP call scenario
application
  .callServer('username', 'app')
  .then((nxmCall) => {
    // console.log(nxmCall);
  });

// IP-PSTN call scenario
application
  .callServer('07400000000')
  .then((nxmCall) => {
    // console.log(nxmCall);
  });

Changes

  • Update reason object to receive reason.reason_text and reason.reason_code fields

Internal changes

  • Rename Event class to NXMEvent
  • Update CAPI requests to REST calls for these events
    • event:delivered
    • text:delivered
    • image:delivered
    • event:seen
    • text:seen
    • image:seen
    • conversation:events
    • audio:play
    • conversation:delete
    • conversation:invite
    • text
    • text:typing:on
    • text:typing:off
    • new:conversation
    • conversation:get
    • user:conversations
    • user:get
    • conversation:join
    • audio:say
    • audio:earmuff:on
    • audio:earmuff:off
    • audio:dtmf
    • audio:record
    • audio:play
    • conversation:member:delete
    • event:delete
    • audio:ringing:start
    • audio:ringing:stop
    • audio:mute:on
    • audio:mute:off
    • image
    • rtc:new
    • rtc:answer
    • rtc:terminate
    • knocking:new
    • knocking:delete

nexmo-iOS v1.0.0

Fixed

  • NexmoClient when disconnected returns error callback for all function.
  • CallMember status calculated by the current leg status.
  • CallMember supports failed, busy, timeout and canceled statuses.
  • Supports member invited.
  • Conversation has media methods.
  • NexmoClient is now singleton.
  • Call method changed to string instead of array.
  • NexmoClient delegate methods renamed.

Added

  • Added conversation media:
NXMConversation myConversation;
[myConversation enableMedia];   // my media will be enabled
[myConversation disableMedia];  // my media will be disabled

​ Added invite member:

NXMConversation myConversation;
[myConversation inviteMemberWithUsername:@"someUsername"
                      completion:myCompletionBlock];

  • Added the member state initiator:
NXMMember *member = someMember;
NSDictionary<NSValue *, NXMInitiator *> *initiators = member.initiators; 
​
NXMInitiator leftStateInitiator = initiators[NXMMemberStateLeft];
leftStateInitiator.isSystem;
leftStateInitiator.userId;
leftStateInitiator.memberId;
leftStateInitiator.time;

Added NXMConversationUpdateDelegate to notify on member updates like media,leg, and state. Added updatesDelegate property to NXMConversation:

@property (nonatomic, weak, nullable) id <NXMConversationUpdateDelegate> updatesDelegate;

Example:

@interface MyClass() <NXMConversationUpdateDelegate>
@implementation MyClass
​
- (void)setConversation:(NXMConversation *conversation) {
	conversation.updatesDelegate(self); // register to conversation updatesDelegate
}
​
- (void)conversation:(nonnull NXMConversation *)conversation didUpdateMember:(nonnull NXMMember *)member withType:(NXMMemberUpdateType)type {
	if (type == NXMMemberUpdateTypeState) {
		// the member state changed
	}
​
	if (type == NXMMemberUpdateTypeMedia) {
		// the member media changed
	}
}
@end

Changed

  • NXMClient is now a singleton:
NXMClient.shared // the shared instance of NXMClient

Renamed:

@property (nonatomic, readonly, nullable, getter=getToken) NSString *authToken; // was token
​
// was - (void)login;
- (void)loginWithAuthToken:(NSString *)authToken;
​
// was - (void)refreshAuthToken:(nonnull NSString *)authToken;
- (void)updateAuthToken:(nonnull NSString *)authToken;
​
// was callees array
- (void)call:(nonnull NSString *)callee
    callHandler:(NXMCallHandler)callHandler
    delegate:(nullable id<NXMCallDelegate>)delegate
  completion:(void(^_Nullable)(NSError * _Nullable error, NXMCall * _Nullable call))completion;
completionHandler:(void(^_Nullable)(NSError * _Nullable error, NXMCall * _Nullable call))completionHandler;

  • NXMClientDelegate renamed:
@protocol NXMClientDelegate <NSObject>
​
// was - (void)connectionStatusChanged:(NXMConnectionStatus)status reason:(NXMConnectionStatusReason)reason;
- (void)client:(nonnull NXMClient *)client didChangeConnectionStatus:(NXMConnectionStatus)status reason:(NXMConnectionStatusReason)reason;
​
// was - (void)incomingCall:(nonnull NXMCall *)call;
- (void)client:(nonnull NXMClient *)client didReceiveCall:(nonnull NXMCall *)call;
​
// was - (void)incomingConversation:(nonnull NXMConversation *)conversation;
- (void)client:(nonnull NXMClient *)client didReceiveConversation:(nonnull NXMConversation *)conversation;
@end

  • NXMConversation otherMembers property renamed to allMembers:
NXMConversation myConversation = someConversation;
NSArray<NXMMember *> * allMembers = myConversation.allMembers // return the all conversation members
​
- (void)joinMemberWithUsername:(nonnull NSString *)username // username instead of userId

  • NXMConversationDelegate renamed methods:
// was - (void)customEvent:(nonnull NXMCustomEvent *)customEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveCustomEvent:(nonnull NXMCustomEvent *)event;
​
// was - (void)textEvent:(nonnull NXMMessageEvent *)textEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveTextEvent:(nonnull NXMTextEvent *)event;
​
// was - (void)attachmentEvent:(nonnull NXMMessageEvent *)attachmentEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveImageEvent:(nonnull NXMImageEvent *)event;
​
// - (void)messageStatusEvent:(nonnull NXMMessageStatusEvent *)messageStatusEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveMessageStatusEvent:(nonnull NXMMessageStatusEvent *)event;
​
// was - (void)typingEvent:(nonnull NXMTextTypingEvent *)typingEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveTypingEvent:(nonnull NXMTextTypingEvent *)event;
​
// was - (void)memberEvent:(nonnull NXMMemberEvent *)memberEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveMemberEvent:(nonnull NXMMemberEvent *)event;
​
// was - (void)legStatusEvent:(nonnull NXMLegStatusEvent *)legStatusEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveLegStatusEvent:(nonnull NXMLegStatusEvent *)event;
​
// was - (void)mediaEvent:(nonnull NXMEvent *)mediaEvent;
- (void)conversation:(nonnull NXMConversation *)conversation didReceiveMediaEvent:(nonnull NXMMediaEvent *)event;

​ Use username instead of userId.

NXMCallDelegate renamed:

// was - (void)statusChanged:(nonnull NXMCallMember *)callMember;
- (void)didUpdate:(nonnull NXMCallMember *)callMember status:(NXMCallMemberStatus)status; 
- (void)didUpdate:(nonnull NXMCallMember *)callMember muted:(BOOL)muted;
​
// was - (void)DTMFReceived:(nonnull NSString *)dtmf callMember:(nonnull NXMCallMember *)callMember;
- (void)didReceive:(nonnull NSString *)dtmf fromCallMember:(nonnull NXMCallMember *)callMember;

NXMEvent and NXMMemberEvent add member object instead of memberId:

@property (nonatomic, readonly, nonnull) NXMMember *member;

NXMImageInfo renamed properties:

@property NSInteger sizeInBytes; // was size
@property NXMImageSize size; // was type

NXMMessageStatusEvent renamed property:

@property NSInteger referenceEventId; // was refEventId

NexmoClient logger exposed - NXMLogger object:

[NXMLogger setLogLevel:NXMLoggerLevelDebug];
NSArray *logNames = [NXMLogger getLogFileNames];
  • Removed NXMLoggerDelegate:
NXMClient myClient
[myClient setLoggerDelegate:LoggerDelegate];