The Sending.Network iOS SDK provides a messaging framework that enables you to integrate chatroom and notification services within your mobile applications. This quickstart will show you how to set up the SDK and make API calls like user registration, room creation, etc. Let's explore how we would make a simple client that can send and receive messages, create a chat room, get member lists, etc.
Prerequisites
Components
Requirements
OS
iOS 14 or above
Software
Xcode 13.0 or above
Installation
CocoaPods based Installation
You can connect to SDN network by running a local P2P service or connecting to an existing Edge Node.
To build the application that connects to an existing Edge Node, add the following line to the podfile.
pod SendingnetworkSDK/Lite
To build the application that runs a local P2P service, add the following line to the podfile.
pod SendingnetworkSDK
Include the header
import SendingnetworkSDK
Start the local P2P service
If you connect to an existing edge node in the previous step, you can safely skip this step.
To create a local P2P service:
RadixService.shared.start()
Initialize the client
If you choose to connect to an existing Edge Node in the previous step, please contact developer@sending.network for a test node URL and assign it tocredentials.homeserver.
var client:MXRestClient?
let credentials = MXCredentials()
credentials.node = "http://localhost:65432"
self.client = MXRestClient(credentials: credentials, unrecognizedCertificateHandler: nil)
Login in to user DID
func DIDLogin() {
client?.getDIDList(walletAddress, success: { [weak self] response in
pre_loginDID(did: response?.array[0])
}, failure: { error in
})
}
func pre_loginDID(did: String) {
client?.postPreLoginDID(did, success: {[weak self] response in
let token = self.signinMessage(message: response.message, did: response.did)
self.loginWithDID(identifier: ["did":did,"token":token], updateTime: response.updated)
}, failure: { error in
})
}
func loginWithDID(identifier: [String: String], updateTime: String) {
client?.postLoginDID(did, withParameter: ["type":" m.login.did.identity","updated":updateTime,"identifier":identifier], success: { response in
print("\(response.accessToken),\(response.userId),\(response.homeServer),\(response.deviceId),\(response.guideState)")
}, failure: { error in
})
}
Keeping your access token safe is essential, as it allows complete access to your account.
Log in with your access token
Instantiate a new client object and use the access token to log in:
// Login with the access token
let credentials = MXCredentials(homeServer: "http://localhost:65432",
userId: "YOUR_USER_ID",
accessToken: "YOUR_ACCESS_TOKEN")
// Create a client
let client = MXRestClient(credentials: credentials, unrecognizedCertificateHandler: nil)
// Create a session to interact with the server and keep it throughout the app's lifetime
// or until the user logs out:
let session = MXSession(sendingNetworkRestClient: client)
Sync and listen
Next, we start the client which sets up the connection to the server and performs the first sync, then listen for the response to get the latest state from the server:
// Create a session to interact with the server and keep it throughout the app's lifetime
// or until the user logs out:
let session = MXSession(sendingnetworkRestClient: client)
session.start { response in
guard response.isSuccess else {
print("sync envnt failed")
return
}
session.listenToEvents(){ event, direction, customObject in
switch direction {
case .forwards:
// Live/New events come here
if event.eventId != nil{
switch event.wireType{
// Got a message from other user.
case kMXEventTypeStringRoomMessage:
let msg = event.content["body"] as! String
print("got message: ", msg, " from: ", event.sender!, "at time: ", event.ageLocalTs)
// Send a receipt, then the message won't send again.
self.client?.sendReadReceipt(toRoom: event.roomId, forEvent: event.eventId){ response in }
break;
// Got a room event.
case kMXEventTypeStringRoomMember:
let ms = event.content["membership"] as! String
if ms == "invite"{
// Invited by a user.
print("invited to room: \(event.roomId!) by user: \(event.sender!)")
self.join_room(room_id: event.roomId!)
}else if ms == "join"{
print("join the room: ", event.roomId)
}
break;
default:
print("room event: ", event.roomId, event.eventType, event.type, event.content)
}
}else{
print("room event: ", event)
}
break
case .backwards:
// Events that occurred in the past will come here when requesting pagination.
// roomState contains the state of the room just before this event occurred.
break
}
}
}
If you are only interested in some specific type of event, you can set the value of the parameter types:
session.listenToEvents([MXEventType.roomMessageFeedback,
MXEventType.roomMessage
]){ event, direction, customObject in
}
Create a private room and chat with a user
If you want to chat with a user, you can create a private room.
let user = "THE_USER_ID_YOU_WANT_TO_CHAT_WITH"
let params = MXRoomCreationParameters()
params.inviteArray = [user]
params.isDirect = true
params.visibility = "private"
params.preset = "trusted_private_chat"
let dic:[String:Any] = [
"type": "m.room.guest_access","state_key": "",
]
params.name = "THE_NAME_YOU_WANT"
params.roomType = "m.room.guest_access"
params.initialStateEvents = [ dic ]
params.creationContent = [ "guest_access": "can_join"]
client.createRoom(parameters: params){ response in
switch response{
case .failure(let error):
print(error)
return
case .success(let resp):
return
}
}
Create a room
Now you can create a room to chat with a specific interest group.
// room parameters
let params = MXRoomCreationParameters()
params.name = "THE_ROOM_NAME"
client.createRoom(parameters: params) { response in
switch response{
case .failure(let error):
print(error)
return
case .success(let resp):
print("room id: ", resp.roomId!)
return
}
}
Invite users with the same interest
It's time to invite users to the room you created.
let roomId = "THE_ROOM_ID";
let userId = "THER_USER_ID_YOU_WANT_INVITE";
client.invite(MXRoomInvitee.userId(userId), toRoom: roomId) { response in
switch response{
case .success():
print("invite user successfully")
return
case .failure(let error):
print(error)
return
}
}
Get messages of a room
To get messages, we need to reuse the mxSession instance created before:
// Retrieve the room from its room id
let room = mxSession.room(withRoomId: "YOUR_ROOM_ID")
// Add a listener on events related to this room
_ = room?.liveTimeline.listenToEvents { (event, direction, roomState) in
switch direction {
case .forwards:
// Live/New events come here
break
case .backwards:
// Events that occurred in the past will come here when requesting pagination.
// roomState contains the state of the room just before this event occurred.
break
}
}
Post a message to a room
To post a message, we create a content message and specify a room.
client.sendTextMessage(toRoom: "YOUR_ROOM_ID", text: "Hello World!") { (response) in
if case .success(let eventId) = response {
// eventId is for reference
// If you have registered events listener like in the previous use case, you will get
// notification for this event coming down from the server events stream and
// now handled by MXSession.
}
}