iOS - TwilioVideo - Unable to connect on call with remote participant - ios

I am developing app with video calling functionality and I am using Twilio Video for that.
Currently using TwilioVideo SDK v4.6.2 and iOS Version 14.x and Above
I am not able to connect to the TwilioVideo room
Below is my code:
func connect() {
guard let accessToken = self.accessToken, let roomName = self.roomName else {
return
}
prepareAudio()
prepareCamera()
let connectOptions = ConnectOptions(token: accessToken) { (builder) in
builder.isDominantSpeakerEnabled = true
builder.isNetworkQualityEnabled = true
if let localAudioTrack = self.localAudioTrack {
builder.audioTracks = [localAudioTrack]
}
if let localVideoTrack = self.localVideoTrack {
builder.videoTracks = [localVideoTrack]
}
if let preferredAudioCodec = TwiloVideoSettingsManager.shared.audioCodec {
builder.preferredAudioCodecs = [preferredAudioCodec]
}
if let preferredVideoCodec = TwiloVideoSettingsManager.shared.videoCodec {
builder.preferredVideoCodecs = [preferredVideoCodec]
}
if let encodingParameters = TwiloVideoSettingsManager.shared.getEncodingParameters() {
builder.encodingParameters = encodingParameters
}
builder.region = "gll"
builder.roomName = roomName
}
self.room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)
UIApplication.shared.isIdleTimerDisabled = true
}
Response in not received from Twilio in either of the methods mentioned below
func didConnect(to room: Room) {
NSLog("Room: \(room.name) SID: \(room.sid)")
if (room.remoteParticipants.count > 0) {
self.remoteParticipant = room.remoteParticipants[0]
self.remoteParticipant.delegate = self
}
self.delegate.videoServiceManagerDidConnectToRoom(name:room.name)
}
func roomDidFailToConnect(room: Room, error: Error) {
NSLog("Failed to connect to a Room: \(error).")
self.delegate.videoServiceManagerFailToConnectRoom(error: error.localizedDescription)
self.leaveRoom()
}
I am not able connect to the room every time and sometimes I get the error mentioned below :
Failed to connect to a Room: Error Domain=com.twilio.video Code=53000 "Signaling connection error" UserInfo={NSLocalizedDescription=Signaling connection error, NSLocalizedFailureReason=SIP error 408}.
When I check the Twilio logs in debug mode I am not getting any error.
Please guide me to rectify if there is any mistake in my code

Twilio employee here. Error 53000 is somewhat vague and could occur due to different things: https://www.twilio.com/docs/api/errors/53000
I'd suggest the following next steps:
try reproducing this error using the iOS Quickstart app (https://github.com/twilio/video-quickstart-ios)
try running our Networktest on the problematic device: https://www.networktest.twilio.com

Related

Kotlin Multiplaform iOS Exceptions showing in Xcode, not in Firebase

We have noticed in our project, we are getting allot of exceptions logged in Xcode (->Organiser->Crashes) logged in production...
However these Share crashes don't give any extra debug infomation, nor are they logged in our Firebase exceptions.
This is how network API calls are being made using ktor 1.6:
#Throws(CancellationException::class, ResponseException::class, Exception::class)
suspend fun getProfileGoals(profileId : Int) : ProfileGoal{
val url = "$base/api/goals/$profileId"
var client = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
useAlternativeNames = false
coerceInputValues = true
encodeDefaults = true
})
}
return client.get(url){
headers {
header(DEVICE_ID, deviceId)
}
}
}
And this is how it is used in iOS:
func getGoals(){
profilesApi?.getProfileGoals(profileId: Int32(selfProfile!.profileId), completionHandler: { profileGoal, error in
if let profileGoal = profileGoal {
self.profileGoals = profileGoal
....
}
}
self.collectionView.reloadData()
})
}
There are obviously lots of other API calls, but they are all done in a similar way.
I guess my question is, is anything obviously wrong or done the incorrect way or how to get these exceptions appearing in Firebase Crashlytics, which may hopefully have more info for debugging

GRPC-Swift Send HTTPProtocolVersion from Client

I'm trying GRPC-Swift for Client-Server application.
I'm using GRPC-Swift for both Client and Server
Client is an iPhone application, which I tried with iPhone Simulator.
I followed this link for Client-side streaming RPC.
When I send message to Server from Client, I got the following error message in the console from Server,
error io.grpc.server_channel_call : unable to determine http version
From the Server in the
HTTPProtocolSwitcher.swift
inside the function func channelRead(context: ChannelHandlerContext, data: NIOAny), it is checking for HTTPProtocolVersion, and it is missing.
How to send the HTTPVersion from the Client code?
Update:
Client Code
import GRPC
import NIO
class HTTPClient {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
private var channel: ClientConnection?
private var client: ChatGuide_ChatGuideClient?
private var clientCall: ClientStreamingCall<ChatGuide_TextMessage, ChatGuide_TextMessage>?
func connect(host: String, port: Int) throws {
let channel = ClientConnection.secure(group: self.group)
.connect(host: host, port: port)
self.channel = channel
self.client = ChatGuide_ChatGuideClient(channel: channel)
}
func disconnect() {
do {
self.clientCall?.sendEnd(promise: nil)
_ = try self.clientCall?.status.wait()
try self.group.syncShutdownGracefully()
} catch let error {
print("\(type(of: self)): Could not shutdown gracefully -", error.localizedDescription)
}
}
func initiateClient() {
let timeAmount = TimeAmount.minutes(1)
let timeLimit = TimeLimit.timeout(timeAmount)
let options = CallOptions(timeLimit: timeLimit)
let call = self.client?.chat(callOptions: options)
call?.response.whenSuccess { (message) in
print("\(type(of: self)): Message from server -", message.text)
}
call?.response.whenFailure { (error) in
print("\(type(of: self)): Response error -", error.localizedDescription)
}
self.clientCall = call
}
func send(text: String) {
if self.clientCall == nil {
self.initiateClient()
}
let message = ChatGuide_TextMessage.with {
$0.text = text
}
self.clientCall?.sendMessage(message, promise: nil)
}
}
Hey Vignesh,
I am currently learning gRPC-Swift myself, so I hope I will be of service and not muck things further.
However, it looks to me that you are not configuring the HTTP/1.x layer in order to transfer Protobuf packets, if you take a look at the HTTP1ToGRPCServerCodec.swift file Here
I think you will have a much clearer idea of how to adjust your code, I am sorry I can't provide more details, however not being too sure myself without further testing and reviewing the codebase.
Best regards and keep me posted if indeed i was helpful,
cheers
From the Server I have initiated insecure Server as,
let server = Server.insecure(group: self.group)
From the Client I have initiated secure ClientConnection as,
let channel = ClientConnection.secure(group: self.group)
And I got this clarification from here
So I made the ClientConnection also insecure as,
let channel = ClientConnection.insecure(group: self.group)
And after this it is working now.

Swift - unable to connect to open hotspot

I'm attempting to connect to an open Wi-Fi network using the NEHotspotConfigurationManager without any luck. I've ensured my app has the proper Hotspot Configuration Entitlement and I'm running on a device that is > iOS 11.
Here is the code I'm using to connect to the open network.
// MARK: - Connect to Hotspot
#available(iOS 11.0, *)
func connectToHotspot(completion: #escaping APConnectionStatusHandler) {
let configuration = NEHotspotConfiguration.init(ssid: Constants.hotspotSSID)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(NEHotspotConfiguration.init()) { connectionError in
if let error = connectionError {
debugPrint("Failed to automatically connect to \(Constants.hotspotSSID)")
debugPrint(error)
completion(false, error.localizedDescription)
}
else {
debugPrint("Automatically connected to \(Constants.hotspotSSID)")
completion(true, nil)
}
}
}
connectionError is populated every time I run this with:
Domain=NEHotspotConfigurationErrorDomain Code=1 "invalid SSID."
I'm unable to find any information on what exactly this error message means. The network shows up in the list of networks for the device I'm using. I'm spelling it correctly and the error message is the same regardless of what SSID string I use.
Any recommendations?
Maybe you shouldn't use Constant.hotspotSSID.
According to the afore-mentioned, I cannot identify what is the 'Constant' or which data type it is.
Here is my thought, try this:
let yourSSID: String = "SSID"
let configuration = NEHotspotConfiguration.init(ssid: yourSSID)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration) {
(error) in
if error != nil {
print("Connect-> Failure!")
} else {
print("Connect-> Success!")
}
}

pjsip connect to asterisk trouble

I have added pjsip lib through cocoapods from here https://github.com/chebur/pjsip.
No I'm trying to connect to sip server using this pjsip example.
Here is my code:
func startPjsip() {
var status: pj_status_t
// Create pjsua first
status = pjsua_create()
if status != Int32(PJ_SUCCESS.rawValue) {
pjsuaError("Error in pjsua_create()", status: status)
}
// Init Pjsua
var config = pjsua_config()
pjsua_config_default(&config)
// on reg state
config.cb.on_reg_state = { (accountId: pjsua_acc_id) in
p("on_reg_state", accountId)
}
// Init the logging config structure
var logConfig = pjsua_logging_config()
pjsua_logging_config_default(&logConfig)
logConfig.console_level = 4
// Init the pjsua
status = pjsua_init(&config, &logConfig, nil)
if status != Int32(PJ_SUCCESS.rawValue) {
pjsuaError("Error in pjsua_init()", status: status)
}
// Adding UDP transport
// Init transport config structure
var udpTransportConfig = pjsua_transport_config()
pjsua_transport_config_default(&udpTransportConfig)
udpTransportConfig.port = 5060
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &udpTransportConfig, nil)
if status != Int32(PJ_SUCCESS.rawValue) {
pjsuaError("Error in creating UDP transport", status: status)
}
// Initialization is done, now start pjsua
status = pjsua_start()
if status != Int32(PJ_SUCCESS.rawValue) {
pjsuaError("Error starting pjsua", status: status)
}
// Register the account on local sip server
var accountConfig = pjsua_acc_config()
pjsua_acc_config_default(&accountConfig)
// username
let username = "10001"
let domain = "voip01.interpreters.travel"
let userId = "sip:\(username)#\(domain)"
accountConfig.id = pj_str_t(ptr: stringToPointer(string: userId), slen: pj_ssize_t(userId.characters.count))
// uri
var uri = "sip:\(domain)"
accountConfig.reg_uri = pj_str_t(ptr: stringToPointer(string: uri), slen: pj_ssize_t(uri.characters.count))
accountConfig.cred_count = 1
accountConfig.cred_info.0.realm = pj_str_t(ptr: stringToPointer(string: "*"), slen: pj_ssize_t("*".characters.count))
let scheme = "digest"
accountConfig.cred_info.0.scheme = pj_str_t(ptr: stringToPointer(string: scheme), slen: pj_ssize_t(scheme.characters.count))
accountConfig.cred_info.0.data_type = Int32(PJSIP_CRED_DATA_PLAIN_PASSWD.rawValue)
let password = "10001"
accountConfig.cred_info.0.data = pj_str_t(ptr: stringToPointer(string: password), slen: pj_ssize_t(password.characters.count))
accountConfig.cred_info.0.username = pj_str_t(ptr: stringToPointer(string: username), slen: pj_ssize_t(username.characters.count))
var accountId = pjsua_acc_id()
status = pjsua_acc_add(&accountConfig, pj_bool_t(PJ_TRUE.rawValue), &accountId)
p(accountId)
if status != Int32(PJ_SUCCESS.rawValue) {
pjsuaError("Error adding account", status: status)
}
}
func pjsuaError(_ message: String, status: pj_status_t) {
let url = NSURL(fileURLWithPath: #file)
let fileName: String = url.lastPathComponent == nil ? #file : url.lastPathComponent!
pjsua_perror(fileName, message, status)
pjsua_destroy()
}
func stringToPointer(string: String) -> UnsafeMutablePointer<Int8> {
let cs = (string as NSString).utf8String
return UnsafeMutablePointer<Int8>(mutating: cs!)
}
When I run application I've got request sending to sip server, it returns 401 Unauthorized (log is here), which seems to be fine according to this doc.
After that pjsip send another request and sip server return 403 Forbidden, here is the log.
I've asked my server guy what is the problem and he said that he used the same credentials with JsSIP lib for browser client and everything works fine for him. Here is the log he gave to me.
I have looked at his log and see difference in these lines:
mine - Via: SIP/2.0/UDP
his - Via: SIP/2.0/WSS
So seems that I'm using wrong transport protocol. But I don't know how to set pjsip to use wss protocol.
Can someone help me if you have the same issues. Or what I need to read/try to achieve my goal.
UPDATE:
I have added Starscream, and got it working to connect to wss:// url. Here is the code:
var socket: WebSocket!
override func viewDidLoad() {
super.viewDidLoad()
socket = WebSocket(url: URL(string: "wss://voip01.interpreters.travel:4443")!)
socket.delegate = self
socket.pongDelegate = self
socket.headers["Sec-WebSocket-Protocol"] = "sip"
socket.connect()
}
func websocketDidConnect(socket: WebSocket) {
print("websocketDidConnect")
print(socket)
}
It says "websocketDidConnect". But now I need to send SIP REGISTER through this wss transport protocol. I can't find any information how to setup pjsip to use wss.
I have tried to change pjsua_transport_create with PJSIP_TRANSPORT_TCP or TLS but no success.
Please, can someone help me where to find information about pjsip + websocket support.

Error when I'm using MailCore2 in Swift 2

I'm using the MailCore2 at Swift in my iOS application to send message to email in the background without open built-in mail application, But when I'm running app on my device ( real device ) I have this problem:
My complete code for send button:
#IBAction func sendButton(sender: AnyObject) {
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "smtp.gmail.com"
smtpSession.username = "from-email"
smtpSession.password = "password"
smtpSession.port = 465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "AAA", mailbox: "to-email")]
builder.header.from = MCOAddress(displayName: "RRR", mailbox: "from-email")
builder.header.subject = messageTitleTextField.text
var message = messageTextView.text
builder.htmlBody = message
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Sent successfully, Thanks!")
}
}
}
Error:
Optional(Error Domain=MCOErrorDomain Code=5 "Unable to authenticate with the current session's credentials." UserInfo={NSLocalizedDescription=Unable to authenticate with the current session's credentials.})
Already I change setting of unsecure app from gmail account but I solved the credentials problem by unlocking gmail account from this link
https://accounts.google.com/DisplayUnlockCaptcha
In my case I had to "Change account access for less secure apps"
https://support.google.com/accounts/answer/6010255?hl=en
If somebody has this problem its quite helpful to know that it is actually problem with security on google side and there it has to be handled...I will leave it because when this happened to me the error didn't say anything I had to search for problem to find out that you have to go to that link on google and find out how to setup it correctly, I wasted time , it will be helpful for others who wants to send mail by smtp with google account

Resources