Skip to main content

ECV Video Görüşme iOS SDK [TR]

Zeynep Baysun tarafından oluşturuldu, 12 Haziran 2025

image-20240102-113213.png image-20240102-113321.png

ECV Video Call iOS SDK

İçindekiler

Giriş

ECV Video Call iOS SDK'ye hoş geldiniz! Bu SDK, iOS uygulamalarınıza gerçek zamanlı görüntülü görüşme işlevselliğini sorunsuz bir şekilde entegre etmenizi sağlar. Sinyalleşme, WebRTC eş bağlantıları, medya akışları ve görüşme durumu yönetimi gibi karmaşıklıkları sizin yerinize yönetir, böylece siz uygulamanızın kullanıcı arayüzüne ve iş mantığına odaklanabilirsiniz.

Bu depo şunları içerir:

  1. SDK: Önceden derlenmiş bir iOS Framework'ü (.framework dosyası) olarak sunulur. Bunu projenize bağımlılık olarak ekleyeceksiniz.
  2. Demo Uygulaması: SDK özelliklerinin nasıl kullanılacağını gösteren bir demo uygulamasının (ECV175_iOS_DEMO) tam kaynak kodu. Bu demo, referans ve örnek amaçlıdır, üretim için hazır bir arayüz kodu değildir.

Temel Özellikler

  • ECV arka uç servislerine (v1.5 ve v1.75+) bağlantı kurar
  • WebRTC kurulumunu ve eşler arası bağlantıyı yönetir
  • Yerel ve uzaktaki video/ses akışlarını yönetir
  • Sesi ve videoyu sessize alma/açma kontrolleri sağlar
  • Kamera değiştirmeyi destekler
  • Görüşme yaşam döngüsü olaylarını yönetir (arama, kuyruk, bağlı, bekletme, sonlandırma)
  • Yapılandırılabilir ortamlar ve görüşme parametreleri sunar

Başlarken

Ön Koşullar

  • Xcode (En Son Kararlı Sürüm Önerilir)
  • Temel iOS geliştirme bilgisi (Swift)
  • Minimum iOS Sürümü: 13.0
  • Hedef iOS Sürümü: 17.0

1. Gerekli Framework'leri Ekleyin

Uygulamanızın ECV SDK framework'ünü ve gerekli bağımlılıklarını (WebRTC) içermesi gerekir. Bunları .framework dosyaları olarak alacaksınız.

  1. Gerekli Framework Dosyaları:

    • ECV SDK: (ör. ECV175_iOS_SDK.xcframework)
    • WebRTC: WebRTC.xcframework
  2. Framework'leri projenize ekleyin:

    • Framework dosyalarını Xcode projenize sürükleyip bırakın
    • "Gerekirse öğeleri kopyala" seçeneğinin işaretli olduğundan emin olun
    • Hedefinizin "Frameworks, Libraries, and Embedded Content" bölümüne ekleyin
    • Her framework için "Embed & Sign" ayarını yapın
  3. Proje Derleme Ayarlarında:

    • "Enable Bitcode" seçeneğini Hayır olarak ayarlayın
    • Framework arama yollarına framework'leri ekleyin
    • "Build Active Architecture Only" ayarını ihtiyacınıza göre yapılandırın

2. Demo Uygulamasını Keşfedin

Dahil edilen demo uygulaması (ECV175_iOS_DEMO), SDK entegrasyonunun pratik bir örneğini sunar.

  1. ECV175_iOS_DEMO.xcodeproj dosyasını Xcode'da açın
  2. Demo uygulamasını bir simülatörde veya gerçek cihazda derleyip çalıştırın
  3. Özellikle UI dizinindeki dosyaları ve AppState.swift dosyasını inceleyerek SDK bileşenlerinin nasıl başlatıldığını ve kullanıldığını anlayın

3. Temel SDK Başlatma (Kavramsal)

// AppDelegate'inizde veya merkezi bir yönetim nesnesinde bir yerde
import ECV175_iOS_SDK

// 1. SDK Yapılandırmasını Tanımlayın (Detaylar için Yapılandırma bölümüne bakın)
let sdkConfig = ECVSdkConfiguration(
    name: "Ortam_Adi", // Uygulamanıza veya arka ucunuza referans veren herhangi bir ad
    serviceUrl: "SERVIS_URLINIZ", // Gerçek servis URL'niz ile değiştirin
    useQueueSocket: true // veya false, arka uç sürümünüze göre ayarlayın (1.75+ için true, 1.5 için false)
    // İsteğe bağlı olarak webrtcUrl, signalingUrl vb. geçersiz kılınabilir
)

// 2. SDK Örneğini Başlatın
// Tek bir örneğin merkezi olarak yönetilmesi önerilir
let ecvSdk = ECVSdk(config: sdkConfig)

// Bu örneği uygulamanız genelinde erişim için saklayın (ör. AppDelegate, DI, Singleton)
// Örnek: MyApp.sdkInstance = ecvSdk

Temel Kavramlar

  • ECVSdk: SDK ile etkileşimde bulunmak için ana giriş noktasıdır. Görüşme oluşturmak ve genel ayarlara/modüllere erişmek için kullanılır.
  • ECVSdkConfiguration: SDK için arka uç URL'lerini ve bağlantı parametrelerini tanımlar.
  • VideoCall: Tek bir görüntülü görüşme oturumunu temsil eder. Görüşme durumunu, olaylarını ve bağlantı detaylarını yönetir.
  • WebRtcConnection: Temel WebRTC eş bağlantısını, medya akışlarını ve render işlemlerini yönetir. VideoCall.connect() ile erişilir.
  • Olaylar: SDK, uygulamanıza görüşme durumu değişiklikleri, hatalar ve medya olayları hakkında bildirimde bulunmak için bir delege sistemi kullanır (VideoCallEvent).
  • Renderers (RTCMTLVideoView): Yerel ve uzaktaki videoyu göstermek için kullanılan standart WebRTC görünümleridir. Yaşam döngülerini yönetmeli ve WebRtcConnection ile ilişkilendirmelisiniz.

Demo Uygulama Akışı

Demo uygulaması şu temel akışı izler:

  1. EnvironmentsScreen: Arka uç bağlantı yapılandırmalarının (Servis URL'si vb.) seçilmesini veya tanımlanmasını sağlar. Bu ekran gösterim amaçlıdır; uygulamanızda genellikle sabit bir yapılandırma olur veya dinamik olarak alınır.
  2. MainScreen: Gerekli görüşme bilgilerini toplar (ör. arayan adı, özellikler), izinleri ister (Kamera, Mikrofon) ve sdk.createCall() ile görüşmeyi başlatır.
  3. QueueScreen: Bir temsilciye bağlanana kadar bekleme durumunu gösterir. AgentConnected veya Error/Hangup olaylarını dinler.
  4. CallScreen: Ana görüntülü görüşme arayüzüdür. Yerel ve uzaktaki video için RTCMTLVideoView'ları yönetir, görüşme kontrollerini (sessize alma, kamera değiştirme, kapatma) gösterir ve SDK olaylarına göre arayüzü günceller.

Sonraki Adımlar

  • Başlarken bölümündeki adımları izleyerek SDK ve demo uygulamasını kurun.
  • SDK'nın temel bileşenlerini ayrıntılı olarak anlamak için Kullanım Kılavuzu'nu okuyun.
  • Demo uygulamasının kaynak kodunu incelerken Demo Uygulama Kılavuzu'na başvurun.

Kullanım Kılavuzu

Bu belge, ECV Video Call iOS SDK'sını uygulamanızda kullanmaya dair ayrıntılı bilgiler sunar.

SDK Başlatma

Temel Başlatma

import ECV175_iOS_SDK

// SDK yapılandırmasını oluşturun
let config = ECVSdkConfiguration(
    name: "Ortam_Adi", // Uygulamanıza veya arka ucunuza referans veren herhangi bir ad
    serviceUrl: "SERVIS_URLINIZ",
    useQueueSocket: true // veya arka uç sürümünüze göre false (false: 1.5, true veya false: 1.75)
)

// SDK örneğini başlatın
let sdk = ECVSdk(config: config)

Yapılandırma Seçenekleri

ECVSdkConfiguration sınıfı çeşitli yapılandırma seçeneklerini destekler:

let config = ECVSdkConfiguration(
    name: "Ortam_Adi",
    serviceUrl: "SERVIS_URLINIZ",
    useQueueSocket: true,
    webrtcUrl: "WEBRTC_URLINIZ", // Opsiyonel, varsayılan: serviceUrl
    signalingUrl: "SIGNALING_URLINIZ", // Opsiyonel, varsayılan: serviceUrl
    waitForRoomIntervalDelay: Int, // Opsiyonel (Sadece 1.5 için), varsayılan: 3000
    waitForRoomIntervalEndpoint: String // Opsiyonel (Sadece 1.5 için), varsayılan: "serviceUrl + API.waitForRoomInterval + \"?rtcId=\""
)

Ekstra Ayarlar

Logger.setLevel(logLevel: .debug) // .debug: SDK'daki tüm logları görmek için (.debug, .info, .warn, .error) // varsayılan: .info

Görüşme Oluşturma ve Yönetme

Görüşme Oluşturma

// Görüntülü görüşmeyi oluştur ve başlat
let call = await sdk.createVideoCall()

Eğer zaten bir rtcId'niz varsa, bunu createVideoCall fonksiyonuna verebilirsiniz, aksi takdirde otomatik olarak backend tarafından oluşturulur (varsayılan)

let call = await sdk.createVideoCall(rtcId: "rtcId'niz")

VideoCall Olayları

Görüşmeyi başlatmadan önce olaya dinleyici ekleyebilirsiniz

sdk.modules.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
    if(videoCall.rtcId != call.rtcId){
        return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
    }

    if(newEvent.type == .AgentConnected) {
        Logger.info("sdk.modules.onCallEvent'ten: \(newEvent.type)")
    }
    else if(newEvent.type == .Error){
        Logger.error("sdk.modules.onCallEvent'ten: \(newEvent.detail ?? "")")
    }
    else {
        Logger.info("sdk.modules.onCallEvent'ten: \(newEvent)")
    }
}

VideoCall Parametreleri

Görüşmeyi başlatmak için bir DialCallParameters nesnesi hazırlamamız gerekir

let dialCallParameters = DialCallParameters(
    callerName: "Arayan_Adi",      // Opsiyonel ama verilmesi önerilir, verilmezse rastgele bir ad oluşturulur
    attributes: [String: String],   // Opsiyonel, görüşmeye veri ekleyin
    queue: String?,                 // Opsiyonel, kuyruk adı, verilmezse sistemin varsayılan kuyruğu kullanılır
    // Gelişmiş Opsiyonel Parametreler
    acdAttributes: [String: String],
    customPayload: [String: String],
    additionalHeaders: [String: String],
)

Örnek:

let dialCallParameters = DialCallParameters(
    callerName: "John Doe",
    attributes: [
        "department": "destek",
        "priority": "yüksek"
    ],
    queue: "TeknikDestek",
)

VideoCall'u Başlatma

Bir VideoCall başlatmak için call.start kullanılır

await call.start(dialCallParameters: dialCallParameters)

Bir Temsilcinin Bağlanmasını Bekleme (Kuyrukta)

Bir temsilcinin bağlanmasını beklemenin iki basit yolu vardır

1- (1.5 ve 1.75+) Daha önce uyguladığımız VideoCall olaylarını kullanmak if(newEvent.type == .AgentConnected)

2- (Sadece 1.75+) Awaited, promise tabanlı görev kullanmak:

let isAgentConnected = await call.agentConnected?.value
Logger.info("isAgentConnected: \(String(describing: isAgentConnected))")

if(isAgentConnected == true) {
    // Geliştirme için görüşmeyi ayrı bir web tarayıcısında açmak için
    if let urlString = call.getUrl(), let url = URL(string: urlString) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
    else {
        Logger.error("URL açılamadı: geçersiz URL string")
    }
}
else {
    Logger.warn("Temsilci bağlanmadı!")
}

VideoCall'u Bağlama

1- videoCall.connect() kullanarak

CallScreen.swift dosyanızda

func setup() {
  Task {
      guard let rtcId = self.rtcId else {
          self.callError = "RtcId başlatılmadı"
          Logger.error("Kurulum başarısız: RtcId nil")
          return
      }

      if let videoCall = appState.sdk?.getVideoCall(rtcId: rtcId){
          self.videoCall = videoCall
      }
      else {
          self.videoCall = await appState.sdk?.createVideoCall(rtcId: rtcId)
      }
      
      // Olayları yönet
      let ECVModules = appState.sdk?.modules
      ECVModules?.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
          if(self.videoCall?.rtcId != videoCall.rtcId){
              return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
          }
          
          if(newEvent.type == .CallEnded){
              ECVModules?.onCallEvent = [] // Olayları sıfırla, taşmayı önle
              path.append(NavigationRoute.mainScreen)
          }
      }

      guard let webRtcConnection = self.videoCall?.connect() else {
          self.callError = "WebRtcConnection bağlantı kurulamadı"
          Logger.error("Kurulum başarısız: WebRtcConnection nil")
          return
      }
      self.webRtcConnection = webRtcConnection

      Logger.debug("Renderer'lar başlatılıyor ve atanıyor...")
      let local = Renderer()
      let remote = Renderer()

      webRtcConnection.localVideoRenderer = local
      webRtcConnection.remoteVideoRenderer = remote

      self.localRenderer = local
      self.remoteRenderer = remote

      Logger.info("WebRTC odası başlatılıyor...")
      await webRtcConnection.startRoom()
      Logger.info("Görüşme kurulumu tamamlandı.")
  }
}

2- Ya da çağrıcı, görüntülü görüşmeye web tarayıcısı ile katılabilir (önerilmez / geliştirme için faydalı)

if let urlString = call.getUrl(), let url = URL(string: urlString) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
else {
    Logger.error("URL açılamadı: geçersiz URL string")
}

Görüntülü Görüşme Arayüzü

Video Görünümlerini Ayarlama

import Foundation
import SwiftUI
import Combine
import ECV175_iOS_SDK
import WebRTC

struct CallScreen: View {
    let rtcId: String?
    @EnvironmentObject var appState: AppState

    @Binding var path: NavigationPath

    @State private var videoCall: VideoCall?
    @State private var webRtcConnection: WebRtcConnection?

    @State private var localRenderer: Renderer?
    @State private var remoteRenderer: Renderer?

    let localStreamWidth: CGFloat = 80
    let localStreamHeight: CGFloat = 120
    let margin: CGFloat = 10
    let pipBottomPadding: CGFloat = 70
    
    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()

            WebRtcVideoView(renderer: remoteRenderer).ignoresSafeArea()

            WebRtcVideoView(renderer: localRenderer)
                .frame(width: localStreamWidth, height: localStreamHeight)
                .cornerRadius(8)
                .overlay(
                    RoundedRectangle(cornerRadius: 8)
                        .stroke(Color.white.opacity(0.5), lineWidth: 1)
                )
                .padding(.trailing, margin)
                .padding(.bottom, margin + pipBottomPadding)

            // ... Görüşme Butonları
        }
        .navigationBarHidden(true)
        .statusBar(hidden: true)
        .onAppear(perform: setup)
        .onDisappear {
            hangup(by: "onDisappear")
        }
    }

    // MARK: - Video Renderer SwiftUI Wrapper

    struct WebRtcVideoView: UIViewRepresentable {
        let renderer: (any RTCVideoRenderer)?

        func makeUIView(context: Context) -> UIView {
            if let renderer = renderer as? Renderer {
                return renderer.view
            } else if let renderer = renderer as? Renderer {
                return renderer.view
            } else {
                return UIView()
            }
        }

        func updateUIView(_ uiView: UIView, context: Context) {}
    }

    // MARK: - Özel Renderer Sınıfları

    class Renderer: NSObject, RTCVideoRenderer {
        let view: RTCMTLVideoView

        override init() {
            self.view = RTCMTLVideoView()
            self.view.videoContentMode = .scaleAspectFill
            super.init()
            Logger.debug("Renderer oluşturuldu")
        }

        deinit { Logger.debug("Renderer yok edildi") }

        func setSize(_ size: CGSize) {
            view.setSize(size)
        }

        func renderFrame(_ frame: RTCVideoFrame?) {
            view.renderFrame(frame)
        }
    }

    func hangup(by: String = "HangUpButton") {
        Logger.debug("Kapatma isteği: \(by)")

        videoCall?.hangup()

        videoCall = nil
        webRtcConnection = nil
        localRenderer = nil
        remoteRenderer = nil
    }

    // func setup(){
    // ... buraya yapıştırın
    //}
}

Görüşme Kontrolleri

// Sesi Sessize Al / Aç
webRtcConnection.setAudioEnabled(state: false) // Sessize al
webRtcConnection.setAudioEnabled(state: true)  // Sesi aç

// Videoyu Aç / Kapat
webRtcConnection.setVideoEnabled(state: false) // Videoyu kapat
webRtcConnection.setVideoEnabled(state: true)  // Videoyu aç

// Kamera Değiştir
try await webRtcConnection.switchCamera()

// Feneri Aç / Kapat
webRtcConnection.setFlashlightEnabled(state: true)
webRtcConnection.setFlashlightEnabled(state: false)

// Görüşmeyi Sonlandır
videoCall.hangup()

Görüntülü Görüşme Olay Yönetimi

Bir olay sdk.modules.onCallEvent içinde tetiklendiğinde, newEvent bir VideoCallEvent'tir ve newEvent.type bir VideoCallEventType'dır.

sdk.modules.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
    if(videoCall.rtcId != call.rtcId){
        return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
    }

    if(newEvent.type == .DialSuccess){
        Logger.debug("sdk.modules.onCallEvent'ten: \(newEvent.detail ?? "")")
    }
    else if(newEvent.type == .CallEnded){
        // burada işle
    }
    //else if(){

    //}
}

Her tip kendi içinde açıklayıcıdır:

public enum VideoCallEventType {
    case None
    case Init
    case GotRtcId
    case DialSuccess
    case Error
    case OnQueue
    case AgentConnected
    case CallEnded
    case SignalingConnected
    
    case GotLocalStream
    case GotRemoteStream
    
    case JoinedRoom
    case SignalingRegistered
    case RtcPeerConnectionCreated
    
    case GotOffer
    case SentOffer
    case GotAnswer
    case SentAnswer
    
    case AudioMuted
    case AudioUnmuted
    case VideoMuted
    case VideoUnmuted
    
    case RemoteAudioMuted
    case RemoteAudioUnmuted
    case RemoteVideoMuted
    case RemoteVideoUnmuted
    
    case StartHold
    case EndHold
    
    case TakePhotoOn
    case TakePhotoOff
    
    case WebRtcOnDataChannel
    case TextChannelConnected
    case TextChannelMessage
    case ConnectionTimeoutStart
    case ConnectionTimeoutEnd
    case WebRtcConnected
    case WebRtcRenegotiationNeeded

    case WebRtcDisconnected
    case WebRtcFailed
    case Hangup

    case FlashOn
    case FlashOff
    
    case TransferPending
    case TransferCancelled
    case TransferCompleted
}

Hata Yönetimi

Hataları daha hassas şekilde yönetmek için, bir hata oluştuğunda .onCallEvent altında videoCall.lastError'ı kontrol edebilirsiniz.

sdk.modules.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
    if(videoCall.rtcId != call.rtcId){
        return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
    }

    if(newEvent.type == .Error){
        Logger.error("sdk.modules.onCallEvent'ten: \(newEvent.detail ?? "")")

        Logger.error(videoCall.lastError)
    }
}

videoCall.lastError'ın tipi ErrorObject'tir ve içinde şunlar bulunur:

public class ErrorObject {
    public var name: ErrorName
    public var message: String
    
    public init(name: ErrorName = ErrorName.NO_ERROR, message: String = "Hata yok.") {
        self.name = name
        self.message = message
    }
}

public enum ErrorName {
    case NO_ERROR
    case SERVICE_URL_REQUIRED
    case CALL_NOT_INITIALIZED
    case CALL_ALREADY_DIALED
    case QUEUE_SOCKET_CLOSED
    case ERROR_DIALING
    case CALL_NOT_DIALED
    case ERROR_WAITING_FOR_ROOM
    case NO_ICE_SERVERS_FOUND
    case HANGUP_FAILED
}

Yani belirli bir hatayı kontrol edebilirsiniz:

sdk.modules.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
    if(videoCall.rtcId != call.rtcId){
        return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
    }

    if(newEvent.type == .Error){
        Logger.error("sdk.modules.onCallEvent'ten: \(newEvent.detail ?? "")")
        Logger.error(videoCall.lastError)

        switch videoCall.lastError.name {
            case .SERVICE_URL_REQUIRED:
                break
            case .CALL_NOT_DIALED:
                break
            case .NO_ICE_SERVERS_FOUND:
                break
            // vb..
        }
    }
}

İzin Yönetimi

// Kamera ve mikrofon izinlerini isteyin
AVCaptureDevice.requestAccess(for: .video) { granted in
    if granted {
        // Kamera izni verildi
    } else {
        // Kamera izni reddedildi
    }
}

AVCaptureDevice.requestAccess(for: .audio) { granted in
    if granted {
        // Mikrofon izni verildi
    } else {
        // Mikrofon izni reddedildi
    }
}

En İyi Uygulamalar

  1. Tek SDK Örneği: Uygulamanızın yaşam döngüsü boyunca tek bir ECVSdk örneği bulundurun.
  2. Doğru Temizlik: Görüşme sona erdiğinde kaynakları mutlaka temizleyin:
  3. Hata Kurtarma: Uygun hata kurtarma mekanizmaları uygulayın:
  4. Bellek Yönetimi: Retain cycle'lara dikkat edin:
weak var call: VideoCall?
weak var webRtcConnection: WebRtcConnection?

Yapılandırma Kılavuzu

Bu belge, ECV Video Call iOS SDK'da mevcut olan yapılandırma seçeneklerini detaylandırır.

SDK Yapılandırması

Temel Yapılandırma

ECVSdkConfiguration sınıfı, görüntülü görüşme örneğini yapılandırmak için kullanılır:

let config = ECVSdkConfiguration(
    name: "Ortam_Adi",
    serviceUrl: "SERVIS_URLINIZ",
)

Gerekli Parametreler

  • name: String Uygulamanıza veya arka ucunuza referans veren herhangi bir ad
  • serviceUrl: String ECV arka uç servisinizin temel URL'si

Opsiyonel Parametreler

  • webrtcUrl: String Özel WebRTC sunucu URL'si, varsayılan: serviceUrl
  • signalingUrl: String Özel sinyalleşme sunucu URL'si, varsayılan: serviceUrl
  • useQueueSocket: Bool Kuyruk soketi kullanılsın mı (v1.75+ için true, v1.5 için false), varsayılan: true
  • waitForRoomIntervalDelay: Integer Sadece useQueueSocket: false ise aktif/etkin olur, ECV 1.5'te, temsilcinin http isteğiyle bağlanıp bağlanmadığını kontrol etme aralığı, varsayılan: 3000
  • waitForRoomIntervalEndpoint: String Sadece useQueueSocket: false ise aktif/etkin olur, ECV 1.5'te, "temsilcinin bağlanmasını bekleme" http endpoint'i, varsayılan: serviceUrl + API.waitForRoomInterval + "?rtcId="

Örnek Kullanımlar:

let configV175 = ECVSdkConfiguration(
    name: "Bir ECV 1.75 Uygulaması",
    serviceUrl: "https://prod-v175.ecv.ornek.com"
)

let configV15 = ECVSdkConfiguration(
    name: "Bir ECV 1.5 Uygulaması",
    serviceUrl: "https://prod-v15.ecv.ornek.com",
    useQueueSocket: false
)

let configSeparateV15 = ECVSdkConfiguration(
    name: "Özel bir ECV 1.5 Uygulaması",
    serviceUrl: "https://api.ornek.com",
    webrtcUrl: "https://webrtc-v15.ornek.com", // /join için ayrı endpoint
    signalingUrl: "https://websocket-v15.ornek.com", // Sinyalleşme için ayrı WebSocket sunucusu (v1.5 için geçerliyse)
    useQueueSocket: false, // v1.5 için gerekli
    waitForRoomIntervalDelay: 3000, // 5 saniyede bir kontrol et
    waitForRoomIntervalEndpoint: "/ozel/pollstatus?callid=" // Özel polling endpoint
)

Görüşme Yapılandırması

Temel Görüşme Yapılandırması

DialCallParameters sınıfı, bireysel görüşmeleri yapılandırmak için kullanılır:

let dialCallParameters = DialCallParameters() // Zorunlu parametre yok

Opsiyonel DialCallParameters Parametreleri

  • callerName: String Arayanın adı, opsiyonel ama verilmesi önerilir, verilmezse rastgele bir ad oluşturulur
  • attributes: [String: String] Görüşmeye veri ekleyin
  • queue: String Verilmezse sistemin varsayılan kuyruğu kullanılır
  • acdAttributes: [String: String] Görüşme için ekstra özel acdAttributes (Gelişmiş Arka Uç Ayarları)
  • customPayload: [String: String] Görüşme için ekstra özel payload (Gelişmiş Arka Uç Ayarları)
  • additionalHeaders: [String: String] DialRequest'e eklenebilecek ekstra http başlıkları

Örnek Kullanımlar:

let dialCallParameters = DialCallParameters(
    callerName: "Jane Doe",
    attributes: [
        "hesapNumarasi": "ACC9876",
        "sonGorusme": "2023-10-26"
    ],
    queue: "DestekKuyrugu",
    additionalHeaders: ["X-Auth-Token": "kullanici_oturum_tokeni"]
)

await call.start(dialCallParameters: dialCallParameters)

WebRTC Bağlantı Parametreleri

Bu parametreler, videoCall.connect() çağrılırken isteğe bağlı olarak verilir ve WebRTC eş bağlantısının davranışını ince ayar yapmanızı sağlar. Çoğu parametrenin varsayılanı uygundur.

  • Bağlantı & Sinyalleşme:
    • connectionTimeout: Int = 10000: WebRTC bağlantı denemesi için zaman aşımı (ms)
    • joinHttpConnectTimeout: Int = 3000: /join isteği için HTTP bağlantı zaman aşımı (ms)
    • joinHttpReadTimeout: Int = 3000: /join isteği için HTTP okuma zaman aşımı (ms)
    • additionalHeaders: [String: String]: /join isteğine ve WebSocket sinyalleşme bağlantısına eklenen özel HTTP başlıkları. Kimlik doğrulama token'ları için faydalı.
  • Medya Kontrolü & Davranış:
    • videoCallEnabled: Boolean = true: Video izleri ayarlanacak mı. Sadece sesli görüşmeler için false yapın.
    • useSpeakerPhone: Boolean = true: Görüşme hoparlörle başlasın mı.
    • autoHandleCameraSwitch: Boolean = true: SDK'nın belirli olaylarda kamerayı otomatik değiştirmesine izin verir (ör. temsilci arka kamerayla fotoğraf isterse).
    • autoHandleHoldSideEffects: Boolean = true: Temsilci görüşmeyi beklemeye aldığında/aldığında yerel ses/video otomatik olarak sessize alınır/açılır.
  • Video Yapılandırması:
    • videoWidth: Int = 480 / videoHeight: Int = 640: İstenen video çözünürlüğü.
    • videoFps: Int = 0 (Varsayılan ~30): İstenen video kare hızı.
    • videoMaxBitrate: Int = 0 (WebRTC varsayılanı): Video kodlama için maksimum bitrate (kbps).
    • videoCodec: String = "VP8": Tercih edilen video codec'i ("VP8", "VP9", "H264").
    • videoCodecHwAcceleration: Boolean = true: Donanım hızlandırma açılsın mı.
  • Ses Yapılandırması:
    • audioCodec: String = "OPUS": Tercih edilen ses codec'i ("OPUS", "ISAC").
    • audioStartBitrate: Int = 0 (WebRTC varsayılanı): Başlangıç ses bitrate'i (kbps).
    • noAudioProcessing: Boolean = false: Platform ses işleme (AEC, AGC, NS) devre dışı bırakılır.
    • disableBuiltInAEC: Boolean = false / disableBuiltInNS: Boolean = false: Donanım AEC/NS devre dışı bırakılırsa.
  • Hata Ayıklama:
    • tracing: Boolean = false: WebRTC iç izlemeyi açar.
  • Veri Kanalı (textChannelConfig):
    • textChannelConfig: DataChannelConfig? = DataChannelConfig(...): Komutlar için kullanılan yerleşik metin veri kanalının yapılandırması (FLASH_ON/OFF, HOLD/PICKUP vb.). Genellikle varsayılan bırakılır. Detaylar için DataChannelConfig sınıfına bakın.

Örnek Kullanım:

let customConnectParams = ConnectParameters(
    videoWidth: 1280,
    videoHeight: 720,
    videoCodec: "H264",
    additionalHeaders: ["X-WebRTC-Auth": "webrtc_token"]
)

// WebRtcConnection'ı özel parametrelerle alın
let webRtcConnection = videoCall.connect(parameters: customConnectParams)
webRtcConnection.startRoom()

DataChannelConfig

DataChannelConfig, eşler arası iletişim ortamında bir veri kanalını başlatmak için kullanılan bir yapılandırma modelidir.

Özellikler

  • enabled: Bool Veri kanalı etkin mi.
  • label: String Veri kanalı için okunabilir bir etiket.
  • id: Int Veri kanalı için ID (-1 ise ayarlanmamış).
  • negotiated: Bool Kanal önceden müzakere edilmiş mi (manuel kurulum).
  • protocol: String Alt protokol adı (Swift anahtar kelime çakışmasını önlemek için yeniden adlandırıldı).
  • ordered: Bool Mesajlar sıralı mı gelmeli.
  • maxRetransmits: Int Maksimum tekrar sayısı (-1 ise ayarlanmamış).
  • maxRetransmitTimeMs: Int Tekrarlar için maksimum süre milisaniye cinsinden (-1 ise ayarlanmamış).

Başlatıcı

init(
    enabled: Bool,
    label: String,
    id: Int = -1,
    negotiated: Bool = false,
    protocol: String = "",
    ordered: Bool = true,
    maxRetransmits: Int = -1,
    maxRetransmitTimeMs: Int = -1
)

Demo Uygulama Kılavuzu

Genel Bakış

ECV175_iOS_DEMO uygulaması, ECV Video Call SDK'nın bir iOS uygulamasına nasıl entegre edileceğini ve kullanılacağını pratik olarak gösteren bir örnektir. Bu kılavuz, uygulamanın mimarisi, temel bileşenleri ve nasıl etkili kullanılacağı konusunda sizi yönlendirecek.

Uygulama Mimarisi

Temel Bileşenler

  1. Uygulama Yapısı
    • Modern iOS geliştirme uygulamalarıyla SwiftUI framework'ü kullanılarak inşa edilmiştir
    • MVVM (Model-View-ViewModel) mimari desenini takip eder
    • Ekran yönetimi için SwiftUI'nin navigasyon sistemini kullanır
    • NavigationRoute enum'u ile tip güvenli navigasyon uygular
    • Bağımlılık enjeksiyonu için environment object'leri kullanır
  2. Durum Yönetimi
    • AppState: Merkezi durum yönetim sınıfı;
      • Ortam yapılandırması kalıcılığı (UserDefaults ile)
      • SDK örneği yaşam döngüsü yönetimi
      • Ortam seçimi ve saklanması
      • @Published özellikleriyle reaktif UI güncellemeleri
    • ConfigurationManager: Ortam yapılandırmalarını yönetir
      • Ön tanımlı ve özel ortamları yönetir
      • Ortam yapılandırmaları için CRUD işlemleri sağlar
      • Ortam ayarlarını kalıcı hale getirir
  3. Navigasyon Sistemi
    • Üç ana rota ile tip güvenli navigasyon:
      • mainScreen: Ortam seçimi sonrası giriş noktası
      • queueScreen(rtcId:name:queue:): Kuyruk yönetim arayüzü
      • callScreen(rtcId:): Görüntülü görüşme arayüzü
    • Doğru geri dönüş ve derin bağlantı desteği
    • Modern navigasyon için SwiftUI'nin NavigationStack'i kullanılır

Temel Özellikler

  1. Ortam Seçimi
    • Birden fazla ortam yapılandırmasını destekler:
      • Ön tanımlı ortamlar
      • Ayarlanabilir özel ortamlar
    • Ortam yapılandırması şunları içerir:
      • Servis URL'si
      • WebRTC URL'si (opsiyonel)
      • Sinyalleşme URL'si (opsiyonel)
      • Kuyruk soketi yapılandırması
      • Oda aralığı ayarları
    • Seçilen ortam UserDefaults ile kalıcı hale getirilir
    • Seçilen ortam ile SDK otomatik başlatılır
  2. Görüntülü Görüşme Entegrasyonu
    • ECV Video Call SDK ile sorunsuz entegrasyon
    • Özellikler:
      • Gerçek zamanlı video akışı
      • Ses kontrolleri (sessize al/aç)
      • Video kontrolleri (aç/kapat)
      • Kamera değiştirme
      • Fener kontrolü
      • Resim içinde resim desteği
    • Kuyruk yönetim sistemi:
      • Mevcut kuyruklara katılma
      • Yeni kuyruk oluşturma
      • Kuyruk durumunu izleme
    • Görüşme olay yönetimi:
      • Görüşme durumu yönetimi
      • Hata yönetimi
      • Bağlantı durumu izleme

Başlarken

Ön Koşullar

  • Xcode 14.0 veya üzeri
  • iOS 15.0 veya üzeri
  • ECV175_iOS_SDK.xcframework
  • WebRTC.xcframework
  • Kamera ve mikrofon izinleri
  • İnternet bağlantısı

Kurulum Süreci

  1. Proje Yapılandırması
    • ECV175_iOS_DEMO.xcodeproj dosyasını açın
    • Demo uygulama hedefinin doğru yapılandırıldığından emin olun
    • Tüm bağımlılıkların doğru şekilde bağlandığını kontrol edin
    • Info.plist dosyasında gerekli izinleri yapılandırın:
      • Kamera kullanım açıklaması
      • Mikrofon kullanım açıklaması
  2. Ortam Yapılandırması
    • Uygulamayı başlatın
    • Ortam seçimi ekranından istediğiniz ortamı seçin
    • Ortam ayarlarını yapılandırın:
      • Servis URL'si (zorunlu)
      • WebRTC URL'si (opsiyonel)
      • Sinyalleşme URL'si (opsiyonel)
      • Kuyruk soketi ayarları
    • Uygulama, seçilen ortam ile SDK'yı otomatik olarak başlatacaktır

Uygulama Akışı

  1. İlk Başlatma
    • Uygulama, daha önce kaydedilmiş ortam yapılandırmasını kontrol eder
    • Varsa, otomatik olarak ana ekrana geçer
    • Yoksa, ortam seçimi ekranı gösterilir
    • Gerekli izinler (kamera, mikrofon) istenir
  2. Ana Ekran
    • Mevcut görüntülü görüşme seçeneklerini gösterir
    • Geçerli ortam yapılandırmasını gösterir
    • Şunlara erişim sağlar:
      • Kuyruk seçimi
      • Görüşme başlatma
      • Ortam ayarları
    • İzin yönetimini ele alır
    • Görüntülü görüşme örneğini başlatır
  3. Kuyruk Yönetimi
    • Mevcut kuyruklara katılma
    • Yeni kuyruk oluşturma
    • Kuyruk durumunu izleme
    • Kuyruk ayarlarını yapılandırma
    • Kuyruk olaylarını yönetme
  4. Görüntülü Görüşme Arayüzü
    • Gerçek zamanlı video akışı:
      • Yerel video önizlemesi
      • Uzaktaki video gösterimi
      • Resim içinde resim desteği
    • Görüşme kontrolleri:
      • Sesi sessize al/aç
      • Videoyu aç/kapat
      • Kamera değiştirme
      • Fener kontrolü
    • Görüşme yönetimi:
      • Kapatma işlevi
      • Hata yönetimi
      • Bağlantı durumu izleme

Kod Yapısı

Temel Dosyalar

  1. ECV175_iOS_DEMOApp.swift
    • Uygulama giriş noktası
    • Ana navigasyon yapısını kurar
    • Temel durum nesnelerini başlatır:
      • AppState
      • ConfigurationManager
    • Environment object'leri yapılandırır
  2. AppState.swift
    • Uygulama durumunu yönetir
    • Ortam kalıcılığını ele alır
    • SDK yaşam döngüsünü kontrol eder
    • Durum geri yüklemeyi uygular
    • SDK örneğini yönetir
  3. Views Dizini
    • Screens/:
      • EnvironmentsScreen.swift: Ortam seçimi ve yapılandırma
      • MainScreen.swift: Ana arayüz ve görüşme başlatma
      • CallScreen.swift: Görüntülü görüşme arayüzü
      • QueueScreen.swift: Kuyruk yönetimi
    • Components/: Yeniden kullanılabilir UI bileşenleri
    • SwiftUI ile uygun durum yönetimiyle arayüzler uygular

En İyi Uygulamalar

  1. Durum Yönetimi
    • Bağımlılık enjeksiyonu için @EnvironmentObject kullanın
    • Sorumlulukları net şekilde ayırın
    • Uygun hata yönetimi uygulayın
    • Reaktif güncellemeler için @Published özellikleri kullanın
    • Durum kalıcılığını doğru yönetin
  2. Navigasyon
    • Tip güvenli navigasyon rotaları kullanın
    • Doğru geri dönüşü uygulayın
    • Derin bağlantı senaryolarını yönetin
    • Navigasyon durumunu yönetin
    • Navigasyon hatalarını ele alın
  3. SDK Entegrasyonu
    • SDK'yı yalnızca gerektiğinde başlatın
    • SDK yaşam döngüsünü doğru yönetin
    • SDK işlemleri için hata yönetimi uygulayın
    • Kaynakları verimli yönetin
    • SDK olaylarını doğru yönetin

Sorun Giderme

  1. Yaygın Sorunlar
    • SDK başlatma hataları:
      • Ortam yapılandırmasını kontrol edin
      • Ağ bağlantısını doğrulayın
      • Gerekli izinlerin verildiğinden emin olun
    • Navigasyon durumu tutarsızlıkları:
      • Navigasyon rotalarını kontrol edin
      • Durum yönetimini kontrol edin
      • Navigasyon hatalarını ele alın
    • Ortam yapılandırma sorunları:
      • Yapılandırma ayarlarını doğrulayın
      • URL formatlarını kontrol edin
      • Zorunlu alanları doğrulayın
  2. Hata Ayıklama İpuçları
    • Ayrıntılı hata mesajları için konsol loglarını kontrol edin
    • Ortam yapılandırmasını doğrulayın
    • SDK'nın doğru başlatıldığından emin olun
    • Ağ bağlantısını izleyin
    • İzin durumunu kontrol edin
    • Xcode hata ayıklama araçlarını kullanın

SDK Entegrasyonu ve Teknik Detaylar

Temel Yapılandırma ve Derleme Sistemi

  1. Build.swift
    • Farklı derleme türlerini ve ortamları yönetir
    • Birden fazla bundle identifier destekler:
      • ccr.ECV175-iOS-DEMO.CORE: Temel demo ortamı
    • Her ortam yapılandırması şunları içerir:
      • Servis URL'si
      • Kuyruk yapılandırmaları
      • Ön tanımlı ayarlar (ör. callAttributes)
  2. AppState.swift
    • SDK entegrasyonu için merkezi durum yönetimi
    • Temel sorumluluklar:
      • SDK örneği yaşam döngüsü yönetimi
      • Ortam yapılandırması kalıcılığı
      • Durum geri yükleme
      • Olay yönetimi koordinasyonu
    • Reaktif güncellemeler için @Published özellikleri kullanır
    • Ortam seçimi için UserDefaults kalıcılığı uygular

Ekran Bazında SDK Entegrasyonu

  1. EnvironmentsScreen
    • Ortam seçimi ve yapılandırma
    • SDK Entegrasyonu:
      • Ortam yapılandırmalarını yönetir
      • Ön tanımlı ve özel ortamları yönetir
      • Ortam seçimini kalıcı hale getirir
      • Seçilen yapılandırma ile SDK'yı başlatır
  2. MainScreen
    • Görüşme başlatmak için ana arayüz
    • SDK Entegrasyonu:
      • Görüntülü görüşme örneğini başlatır
      • İzinleri (kamera, mikrofon) yönetir
      • Kuyruk seçimini yönetir
      • Görüşme olay dinleyicilerini kurar
      • Temel özellikler:
        // SDK başlatma
        let call = await appState.sdk?.createVideoCall()
        // Olay yönetimi
        ECVModules?.onCallEvent.append { (videoCall, newEvent, lastEvent) in
            // Olayları yönet
        }
        
  3. QueueScreen
    • Kuyruk yönetimi ve temsilci bağlantısı
    • SDK Entegrasyonu:
      • Kuyruğa katılmayı yönetir
      • Temsilci bağlantısını yönetir
      • Hem ECV 1.75 hem de 1.5 sürümlerini destekler
      • Temel özellikler:
        // Kuyruğa katılma
        let dialCallParameters = DialCallParameters(
            callerName: name,
            queue: queue,
            attributes: [queueKey: queueValue]
        )
        // Olay dinleme
        let ECVModules = appState.sdk?.modules
        ECVModules?.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
           if(videoCall.rtcId != call?.rtcId){
               return // Sadece mevcut görüşmeye ait olayları yakalamak için. // Tüm görüşmelerin olaylarını yakalamak için bu satırı yoruma alın
           }
           // Temsilci bağlantı yönetimi
           if(newEvent.type == .AgentConnected) {
               // TEMSİLCİ BAĞLANDI
               // GÖRÜŞME EKRANINA GEÇ
           }
           else if(newEvent.type == .Error){
               // showError = true
           }
        }
        // Görüşmeyi başlat
        await call?.start(dialCallParameters: dialCallParameters)
        
  4. CallScreen
    • Görüntülü görüşme arayüzü
    • SDK Entegrasyonu:
      • WebRTC bağlantısını yönetir
      • Video/ses akışlarını yönetir
      • Görüşme özelliklerini kontrol eder
      • Temel özellikler:
        // WebRTC kurulumu
        let webRtcConnection = videoCall?.connect()
        // Akış yönetimi
        localRenderer = webRtcConnection?.localStream
        remoteRenderer = webRtcConnection?.remoteStream
        // Görüşme kontrolleri
        func toggleLocalAudio()
        func toggleLocalVideo()
        func toggleFlashlight()
        func switchCamera()
        func switchViewRenderers()
        

SDK Sürüm Uyumluluğu

  1. ECV 1.75 Özellikleri
    • Kuyruk soketi desteği
    • Gelişmiş olay yönetimi
    • İyileştirilmiş temsilci bağlantı yönetimi
    • Daha iyi durum yönetimi
  2. ECV 1.5 Özellikleri
    • Geleneksel kuyruk yönetimi
    • Aralıklı temsilci bağlantısı
    • Temel olay yönetimi
    • Eski sürüm desteği

Olay Yönetim Sistemi

  1. Görüşme Olayları
    • Olay tipleri:
      • AgentConnected
      • CallEnded
      • Error
    • Olay yönetimi:
      ECVModules?.onCallEvent.append { (videoCall, newEvent, lastEvent) in
          switch newEvent.type {
          case .AgentConnected:
              // Temsilci bağlantısını yönet
          case .CallEnded:
              // Görüşme sonunu yönet
          case .Error:
              // Hataları yönet
          }
      }
      
  2. Durum Yönetimi
    • Görüşme durumu takibi
    • Bağlantı durumu izleme
    • Hata durumu yönetimi
    • Kuyruk durumu yönetimi

SDK Entegrasyonu için En İyi Uygulamalar

  1. Başlatma
    • SDK'yı yalnızca gerektiğinde başlatın
    • Yapılandırmayı doğru yönetin
    • SDK yaşam döngüsünü yönetin
    • Başlatma hatalarını yönetin
  2. Olay Yönetimi
    • Doğru olay filtreleme kullanın
    • Tüm olay tiplerini yönetin
    • Hata yönetimi uygulayın
    • Olay dinleyicilerini temizleyin
  3. Kaynak Yönetimi
    • Kaynakları doğru şekilde bırakın
    • Uygulama sonlandırıldığında temizlik yapın
    • Belleği verimli yönetin
    • Arka plan/ön plan geçişlerini yönetin
  4. Hata Yönetimi
    • Kapsamlı hata yönetimi uygulayın
    • Kullanıcıya geri bildirim verin
    • Ağ sorunlarını yönetin
    • SDK'ya özgü hataları yönetin

Sonuç

ECV175_iOS_DEMO uygulaması, ECV Video Call SDK kullanarak görüntülü görüşme işlevselliğini uygulamak için sağlam bir temel sunar. Bu kılavuzu takip ederek ve uygulamanın mimarisini anlayarak, kendi iOS uygulamalarınıza görüntülü görüşme özelliklerini etkili şekilde entegre edebilirsiniz.

Belirli özellikler veya uygulama detayları hakkında daha fazla bilgi için lütfen SDK dokümantasyonuna ve API referansına başvurun.

Olaylar ve Durum Yönetimi

Giriş

ECV iOS SDK’sı asenkron olarak çalışır. Uygulamanıza durum değişikliklerini, hataları ve diğer önemli olayları iletmek için olay (event) tabanlı bir mimari kullanır. Bu olayları anlamak, duyarlı ve sağlam bir kullanıcı arayüzü oluşturmak için çok önemlidir.

Bu kılavuz, SDK olaylarının yapısını, temel olay türlerini ve ilgili durum özelliklerini detaylandırır.

Olaylara Abone Olmak

Olayları sdk.modules.onCallEvent örneği üzerinden dinleyebilirsiniz:

sdk.modules.onCallEvent.append { (videoCall: VideoCall, newEvent: VideoCallEvent, lastEvent: VideoCallEvent) in
    if(videoCall.rtcId != call?.rtcId){
        return // Sadece mevcut çağrıya ait olayları yakaladığımızdan emin oluyoruz. // Tüm çağrıların olaylarını yakalamak için bu satırı yoruma alın.
    }

    if(newEvent.type == .Error){
        // Hata olayını işle
    }
    else if(newEvent.type == .AgentConnected) {
        // AgentConnected olayını işle
    }
    else {
        print("ECVModules?.onCallEvent üzerinden gelen: \(newEvent)")
    }
}

Detaylı kod örnekleri için Usage Guide içindeki "Video Call Event Handling" bölümüne bakın.

Olay Yapısı (VideoCallEvent)

Temel Alanlar:

  • type: VideoCallEventType: (Gerekli) Gerçekleşen olayın türünü gösteren enum değeri. Olayı nasıl işleyeceğinizi belirlemek için öncelikle bu alanı kontrol edersiniz.
  • detail: String?: (İsteğe bağlı) Olayla ilgili ek bilgi sağlar (ör. GotRtcId için rtcId, DialSuccess için etkileşim ID'si, CallEnded için neden bilgisi).
  • objData: Any?: (İsteğe bağlı) SignalingConnected sırasında WebRtcConnection, bazı hatalarda HTTP yanıt nesnesi gibi ilgili nesneleri içerebilir. Tür kontrolü (is) ile erişilmelidir.
  • data: [String: String]: (Genellikle boş) Olayla ilişkili olabilecek genel anahtar-değer haritası.
  • createdAt: Date: Olayın SDK içinde oluşturulduğu zaman.

Olay Türü Referansı (VideoCallEventType)

Aşağıda, genellikle çağrı sürecinin farklı aşamalarına göre gruplanmış yaygın olay türleri yer alır:

Aşama 1: Başlatma ve Arama

  • GotRtcId

    • Ne zaman: sdkInstance.createVideoCall() başarılı şekilde çağrı ID’si aldığında.
    • Veri: event.detail, rtcId içerir.
    • Tepki: rtcId’yi saklayın. Daha sonra çağrıyı başlatmak için gereklidir.
  • DialSuccess

    • Ne zaman: call.start() başarılı şekilde arama isteğini gönderdiğinde.
    • Veri: event.detail etkileşim ID’sini, event.objData ham JSON yanıtı içerebilir.
    • Tepki: Genellikle bekleme/queue durumuna geçilebilir.
  • Error (Başlatma/Arama sırasında)

    • Ne zaman: rtcId alınamazsa, call.start() hatalıysa, ağ veya sunucu hatası varsa.
    • Veri: event.error, event.detail, event.objData.
    • Tepki: Kullanıcıya hata mesajı gösterin. Çağrının ilerlemesini engelleyin. Gerekirse VideoCall’ı temizleyin.

Aşama 2: Bekleme ve Temsilci Bağlantısı

  • OnQueue

    • Ne zaman: Arama başarılı olduğunda ve kullanıcı temsilci beklerken.
    • Tepki: Bekleme ekranı gösterin.
  • AgentConnected

    • Ne zaman: Temsilci çağrıyı kabul ettiğinde.

    • Tepki: WebRTC bağlantısını başlatın:

      1. videoCall.connect()
      2. webRtcConnection.startRoom()
      3. CallScreen’e geçin.
  • Error (Queue sırasında)

    • Ne zaman: Queue zaman aşımı, ağ sorunu, backend hatası.
    • Tepki: Kullanıcıyı bilgilendirin, bekleme ekranından çıkın, videoCall.hangup() çağırın.
  • Hangup / CallEnded (Queue sırasında)

    • Ne zaman: Kullanıcı çağrıyı sonlandırırsa ya da temsilci bağlanmadan çağrı bitirilirse.
    • Tepki: Bekleme ekranından çıkın, arayüzü temizleyin.

Aşama 3: WebRTC Bağlantı Kurulumu

  • SignalingConnected: WebSocket bağlantısı kuruldu.

  • SignalingRegistered: Signaling sunucusuna başarıyla kayıt olundu.

  • JoinedRoom: /join isteği başarılı oldu, ICE sunucuları vs. geldi.

  • RtcPeerConnectionCreated: WebRTC PeerConnection nesnesi oluşturuldu.

  • GotOffer / SentOffer: SDP Offer alındı/gönderildi.

  • GotAnswer / SentAnswer: SDP Answer alındı/gönderildi.

  • WebRtcConnected

    • Ne zaman: WebRTC bağlantısı tamamen kuruldu.
    • Tepki: Medya akışı hazır. CallScreen’de yükleme göstergesi kaldırılabilir.
  • TextChannelConnected: Veri kanalı bağlandı.

  • WebRtcDisconnected / WebRtcFailed: WebRTC bağlantısı kesildi veya başarısız oldu.

Aşama 4: Aktif Çağrı ve Medya

  • GotLocalStream: Kamera yayını başladı.

  • GotRemoteStream: Karşı tarafın yayını geldi.

    • Tepki: Görüntü ekranına bağlayın.
  • AudioMuted / AudioUnmuted: Mikrofon durumu değişti.

    • Tepki: Sessize alma düğmesini güncelleyin.
  • VideoMuted / VideoUnmuted: Kamera durumu değişti.

    • Tepki: Önizleme göster/gizle.
  • RemoteAudioMuted / RemoteAudioUnmuted: Karşı taraf sesi kapattı/açtı.

    • Tepki: Göstergelerle kullanıcıyı bilgilendirin.
  • RemoteVideoMuted / RemoteVideoUnmuted: Karşı taraf kamerasını kapattı/açtı.

    • Tepki: Görsel efektlerle belirtin.
  • StartHold / EndHold: Çağrı beklemeye alındı/alınmadı.

    • Tepki: “Beklemede” ekranı gösterin/gizleyin.
  • TakePhotoOn / TakePhotoOff: Temsilci tarafından fotoğraf çekim işlemi başlatıldı/bitti.

    • Tepki: Gerekirse arayüzü ayarlayın.
  • TextChannelMessage: Veri kanalı üzerinden gelen mesaj.

    • Veri: event.detail ham mesaj içeriğidir.
    • Tepki: SDK standart komutları işler (HOLD, MUTE, FLASH). Özel mesajlar için kendi tepkilerinizi geliştirin.

Aşama 5: Çağrının Sonlandırılması

  • Hangup

    • Ne zaman: videoCall.hangup() çağrıldığında.
    • Tepki: Arayüz temizliğini başlatın. Asıl bitiş sinyali CallEnded’dır.
  • CallEnded

    • Ne zaman: Çağrı tamamen sonlandığında.

    • Veri: event.detail içinde neden bilgisi olabilir.

    • Tepki:

      1. UI’ı temizleyin.
      2. Çağrı ekranından çıkın.
      3. VideoCall’a ait kaynakları serbest bırakın.

Durum Özellikleri

Olaylar değişimi bildirirken, aşağıdaki mevcut durumlara da erişebilirsiniz:

  • VideoCall üzerinde:

    • rtcId: String: Çağrı ID’si (GotRtcId sonrası gelir).
    • dialResponse: [String: Any]?: DialSuccess sonrasında gelen yanıt.
    • agentConnected: Boolean: Temsilci bağlantısı gerçekleştiyse true.
    • webRtcConnection: WebRtcConnection?: connect() sonrası bağlantı nesnesi.

Not: Arayüzünüzü güncellemek için olaylara tepki vermek en iyi uygulamadır. Bu özellikleri yalnızca başlangıç durumu kontrolü gibi özel durumlar için kullanın.

Özelleştirme Kılavuzu

Giriş

Sağlanan Demo Uygulama (ECV175_iOS_DEMO), ECV SDK'nın temel işlevlerini sergiler. Ancak, üretim uygulamanızın kesinlikle farklı bir arayüz/deneyim gereksinimi, yapılandırma yöntemi ve veri ihtiyacı olacaktır. Bu kılavuz, SDK ve demo konseptlerini kendi uygulamanıza uyarlamanız için öneriler sunar.

1. Arayüz Uygulaması

Demo SwiftUI kullanır, ancak SDK'nın kendisi arayüzden bağımsızdır. Aşağıdaki platformlarda entegre edebilirsiniz:

  • SwiftUI
  • UIKit
  • Herhangi bir kombinasyon

Arayüzünüz için Temel Hususlar:

  • Kendi Arayüzünüzü Oluşturun: Demo arayüz ekranlarını doğrudan kopyalamayın. Uygulamanızın görünümüne, hissine ve kullanıcı akışına uygun ekranlar tasarlayın.
  • Temel SDK Etkileşimleri Aynı Kalır: Hangi arayüz aracını kullanırsanız kullanın, SDK ile temel etkileşimler değişmez:
    • İzinler: Görüşme başlatmadan önce Kamera, Mikrofon (ve S+ için Bluetooth Connect) izinlerini istemeli ve yönetmelisiniz.
    • Video Render'ları: Video göstermek için düzeninizde RTCMTLVideoView örnekleri sağlamalısınız.
    • Renderer Yaşam Döngüsü: Çok önemli. RTCVideoRenderer'ların yaşam döngüsünü doğru yönetmelisiniz:
      • UIView ile başlatın.
      • Yerel/uzak akışlara webRtcConnection.localVideoRenderer/remoteVideoRenderer ile ilişkilendirin.
    • Görüşme Durumu Gösterimi: SDK olaylarına göre arayüzünüzde mevcut görüşme durumunu yansıtın (ör. "Bağlanıyor...", "Temsilci bekleniyor...", "Bağlandı", "Beklemede").
    • Görüşme Kontrolleri: Şunlar için arayüz öğeleri (Butonlar, İkonlar) uygulayın:
      • Sesi Sessize Al/Aç (webRtcConnection.setAudioEnabled(...))
      • Videoyu Aç/Kapat (webRtcConnection.setVideoEnabled(...))
      • Kamera Değiştir (webRtcConnection.switchCamera(...))
      • Kapat (videoCall.hangup())
    • Olay Yönetimi: SDK olaylarını dinleyerek (bkz. Olaylar ve Durum Yönetimi) arayüz durumunu güncelleyin, ekranlar arasında geçiş yapın ve hataları yönetin.

2. Yapılandırma (ECVSdkConfiguration)

Demo'daki EnvironmentsScreen.swift, farklı arka uç ortamlarını kolayca test etmek için tasarlanmıştır. Üretim uygulamanızda bu ekrana muhtemelen ihtiyaç olmayacaktır.

Üretim Yapılandırma Stratejileri:

  1. Sabit Yapılandırma: Uygulamanız yalnızca bir arka uç ortamına bağlanacaksa (ör. prodüksiyon), ECVSdkConfiguration değerlerini SDK'yı başlatırken sabit olarak verebilirsiniz.
    // Örnek: Application.onCreate veya DI modülünde
    let prodConfig = ECVSdkConfiguration(
        name: "My App Prod",
        serviceUrl: "https://your-prod.ecv.ornek.com",
        useQueueSocket: true // Arka uç v1.75+ ise
        // ... gerekirse diğer parametreler ...
    )
    let sdkInstance = ECVSdk("MyAppProdInstance", prodConfig)
    
  2. Dinamik Yapılandırma: Yapılandırma detaylarını (ör. serviceUrl, webrtcUrl) kendi uygulama arka ucunuzdan SDK'yı başlatmadan önce çekin. Böylece uç noktaları merkezi olarak yönetebilir, uygulama güncellemesi gerektirmeden değiştirebilirsiniz.
    • Uygulamanız yapılandırmayı kendi sunucusundan çeker.
    • Alınan URL'lerle ECVSdkConfiguration oluşturur.
    • ECVSdk'yi başlatır.

Önemli: Seçtiğiniz ECVSdkConfiguration'daki useQueueSocket parametresinin hedef ECV arka ucunuzun yetenekleriyle uyumlu olduğundan emin olun (v1.5 için false, v1.75+ için true önerilir).

3. Görüşme Verisi (DialCallParameters)

Demo, Build.swift'teki selectableQueues ile seçilen ortama göre dinamik olarak açılır menüler (kuyruk seçimi) ekler. Bu, demo uygulamasının çoklu ortam yapısına özgüdür.

Kendi uygulamanızda, DialCallParameters'ı videoCall.start() çağrısından hemen önce ilgili bağlamsal verilerle doldurmalısınız.

Örnek:

// Kullanıcı profil verisi
let userId = "user123"
let accountType = "Premium"
let intent = "Fatura Sorgusu"
// Hedef kuyruk/skill
let targetQueue = "FaturaDestek"
// SDK örneğini al ve görüşme oluştur
let videoCall = sdkInstance.createVideoCall()
// ... GotRtcId bekle ...
// Uygulamaya özel verilerle parametreleri oluştur
let dialParams = DialCallParameters(
    callerName: "Kullanıcı \(userId)", // veya gerçek kullanıcı adı
    attributes: [
        "userId": userId,
        "accountType": accountType,
        "callIntent": intent
    ],
    acdAttributes: [
        "skill": "Fatura"
    ],
    queue: targetQueue, // Hedef kuyruğu açıkça belirt
    additionalHeaders: ["Authorization": "Bearer \(getUserAuthToken())"] // Örnek auth
)
// Görüşmeyi başlat
videoCall.start(dialParams)
// Kuyruk/Bekleme ekranına geç

4. Olay Yönetim Mantığı

Demo, olaylara nasıl abone olunacağını gösterir, ne yapılacağı ise uygulamaya özeldir. Kendi uygulamanızda anahtar olayları doğru şekilde yönettiğinizden emin olun:

  • Navigasyon: AgentConnected, CallEnded, Error olaylarında ekran değişimini tetikleyin.
  • Arayüz Güncellemeleri: Sessiz durumu, beklemede olma, bağlantı durumu değişikliklerini görsel olarak yansıtın.
  • Hata Gösterimi: Error olaylarında kullanıcıya anlaşılır mesajlar gösterin.
  • Kaynak Temizliği: Kesin sinyal olarak CallEnded'ı kullanarak arayüzü ve görüşmeye özel kaynakları temizleyin.

5. Gelişmiş Özelleştirme (Opsiyonel)

  • Özel Veri Kanalı Mesajları: Backend'iniz metin veri kanalı üzerinden standart komutlar dışında özel komutlar gönderiyorsa, TextChannelMessage olayını dinleyip event.detail'ı ayrıştırarak uygulamaya özel davranışlar ekleyebilirsiniz.
  • ConnectParameters Ayarı: Belirli ağ ortamları veya kalite gereksinimleri için, ConnectParameters'daki parametrelerle (ör. videoMaxBitrate, codec'ler, ICE filtreleme modları) oynayabilirsiniz. Gelişmiş seçenekler için WebRTC dokümantasyonuna bakın.
  • Ses Yönetimi: Varsayılanlar (useSpeakerPhone vb.) ConnectParameters'ta sağlansa da, daha karmaşık ses yönlendirme ihtiyaçları SDK'nın temel kullanımının ötesinde daha derin entegrasyon gerektirebilir.

6. İzinler

iOS'un en iyi uygulamalarını her zaman takip edin:

  • İzinleri yalnızca gerektiğinde isteyin (görüşme başlatmadan hemen önce).
  • Neden bu izinlerin (Kamera, Mikrofon) gerektiğini açıkça belirtin.
  • Kullanıcı izinleri reddederse durumu arayüzde uygun şekilde yönetin (ör. görüşme işlevini devre dışı bırakın, ayarlardan açmaları için bilgilendirin).

7. Ek Modüller

7.1 Çağrı Aktarma v1.0.18.45+

Bu modül, aktif ve devam eden bir çağrının farklı bir temsilciye veya kuyruğa yönlendirilmesini sağlar. Aktarılan bir çağrının yaşam döngüsü şu şekildedir:

  • Kaynak çağrı başlatılır (çağrı oluşturulur).

  • Kaynak çağrı kuyruğa alınır.

  • Kaynak çağrı bağlanır.

  • Temsilci çağrı aktarımını başlatır.

  • Aktarım, bir kuyruğa veya doğrudan başka bir temsilciye yapılabilir.

  • Temsilciye yapılan doğrudan aktarım, temsilci tarafından iptal edilebilir veya reddedilebilir.

  • ECVModules?.onCallEvent üzerinden bir "TransferPending" (Aktarım Bekleniyor) olayı alınır.

  • Bu olay alındığında, arayüzde kullanıcıya "Lütfen bekleyin, çağrınız birazdan aktarılacak" gibi bir mesaj gösterilebilir.

  • Bu olaydan sonra herhangi bir anda "TransferCancelled" (Aktarım İptal Edildi) olayı gelebilir. Bu olay alındığında gösterilen uyarı mesajı kaldırılmalıdır. Çağrı normal şekilde devam eder.

  • Temsilci, çağrıyı aktarmadan önce beklemeye (HOLD) almış olabilir, bu nedenle aktarım mesajı HOLD arayüzünün üzerinde gösterilmelidir.

  • Aktarım tamamlandığında, ECVModules?.onCallEvent üzerinden bir "TransferCompleted" (Aktarım Tamamlandı) olayı alınır. newEvent.data?["rtcId"] içinde, aktarılan çağrıya atanan yeni RtcId değeri yer alır.

  • Mevcut çağrı görünümü ve ilişkili tüm kaynaklar yok edilir.

  • Kullanıcı yeniden kuyruk sayfasına yönlendirilir, bu sefer yeni RtcId ile.

  • Kullanıcı, sanki yeni bir çağrı başlatılmış gibi kuyrukta bekletilir ve bir temsilci hazır olduğunda "AgentConnected" olayı ile çağrı bağlanır.

Notlar:
- Kuyruk ekranında bir aktarım tespit edilirse, var olan çağrı alınmamalı, yeni bir çağrı oluşturulmalıdır.

// Çağrı aktarım özelliği OLMADAN 
let call = appState.sdk?.getVideoCall(rtcId: rtcId!) 

// Çağrı aktarım özelliği İLE 
let call = isTransferred == true ? await appState.sdk?.createVideoCall(rtcId: rtcId) : appState.sdk?.getVideoCall(rtcId: rtcId!)

- Kuyruk ekranında beklenirken DialExRequest çağrılmamalıdır. Bu nedenle, Demo uygulamasında yazıldığı gibi, aşağıdaki kod kullanılmalıdır:

if(isTransferred == true) { // Çağrı Aktarımı, arama yapılmasına gerek yok, sadece kuyrukSocket beklenir 
  call?.isDialed = true 
  _ = await call?.createQueueSocket() 
  return 
}

Bu senaryoya ait bir örnek uygulama, demo uygulamasında mevcuttur.

 

Sorun Giderme Kılavuzu

Bu kılavuz, ECV iOS SDK'nın entegrasyonu veya kullanımı sırasında karşılaşılan yaygın sorunlar için çözümler ve hata ayıklama adımları sunar.

Yaygın Sorunlar & Çözümler

Derleme & Bağımlılık Hataları

  1. Hata: "Could not find module 'ECV175_iOS_SDK'"
    • Neden: Xcode gerekli framework dosyalarını bulamıyor.
    • Çözüm:
      • ECV SDK framework'ünün projenize doğru şekilde eklendiğinden emin olun.
      • Framework'ün hedefinizin "Frameworks, Libraries, and Embedded Content" bölümünde listelendiğini doğrulayın.
      • Proje ayarlarında framework arama yollarının doğru konumu içerdiğini kontrol edin.
      • Derleme klasörünü temizleyin (Cmd + Shift + K) ve projeyi yeniden derleyin.
  2. Hata: "Undefined symbols for architecture"
    • Neden: Gerekli bağımlılıklar eksik veya mimari uyumsuzluklar var.
    • Çözüm:
      • Tüm gerekli framework'lerin projeye doğru şekilde bağlandığından emin olun.
      • Uygulamanız ve SDK arasındaki hedef sürüm ve mimarilerin uyumlu olduğundan emin olun.
      • Bağımlılıkların uyumlu sürümlerini kullandığınızdan emin olun.
      • Projeyi temizleyip yeniden derleyin.
  3. Hata: "Code signing failed"
    • Neden: Kod imzalama veya profil sorunları.
    • Çözüm:
      • Apple Developer hesabınızın aktif olduğundan emin olun.
      • Profilinizin gerekli yetkilendirmeleri içerdiğini kontrol edin.
      • İmzalama sertifikanızın geçerli ve yüklü olduğundan emin olun.
      • Gerekirse profilleri güncelleyin.

Çalışma Zamanı Çöküşleri

  1. Çökme: "Thread 1: EXC_BAD_ACCESS"
    • Neden: Bellek erişim sorunları, genellikle WebRTC veya native kod ile ilgili.
    • Çözüm:
      • SDK'nın doğru şekilde başlatıldığından emin olun.
      • Kendi uygulamanızda bellek yönetimini kontrol edin.
      • Gerekli tüm izinlerin verildiğinden emin olun.
      • Hatanın tam noktasını bulmak için hata ayıklayıcıyı kullanın.
  2. Çökme: "Fatal error: Unexpectedly found nil while unwrapping an Optional value"
    • Neden: SDK nesnesine başlatılmadan veya temizlendikten sonra erişiliyor.
    • Çözüm:
      • SDK Başlatılmadı: ECVSdk.shared.initialize(...)'ın tüm SDK işlevlerinden önce çağrıldığından emin olun.
      • VideoCall Nil: rtcId'nin geçerli olduğundan ve görüşmenin sonlanmadığından emin olun.
      • WebRTC Connection Nil: AgentConnected olayı sonrası videoCall.connect()'in başarıyla çağrıldığından emin olun.
      • View Controller'lar: View controller yaşam döngüsünü doğru yönetin.
  3. Çökme: WebRTC veya Medya İşleme ile İlgili
    • Neden: WebRTC bileşenlerinin yaşam döngüsü yanlış yönetiliyor.
    • Çözüm:
      • WebRTC kaynaklarını deinit veya viewWillDisappear'da doğru şekilde temizleyin.
      • Kamera ve mikrofon izinlerinin verildiğinden emin olun.
      • Arka plan/ön plan geçişlerini doğru yönetin.
      • WebRTC işlemleri için doğru thread kullanımını kontrol edin.
  4. Çökme: "Permission Denial"
    • Neden: Gerekli izinler olmadan kamera veya mikrofona erişilmeye çalışılıyor.
    • Çözüm:
      • AVCaptureDevice.requestAccess ile doğru izin akışını uygulayın.
      • İzin durumunu kontrol etmeden görüşme işlevini başlatmayın.
      • İzin reddi durumunu arayüzde uygun şekilde yönetin.
      • Info.plist dosyanızda gerekli izin açıklamalarının olduğundan emin olun.

Medya Kalite Sorunları

  1. Kötü Video/Ses Kalitesi (Donma, Pikselleşme, Bozuk Ses)
    • Hata Ayıklama:
      • Ağ: Ağ bant genişliğini, gecikmeyi ve paket kaybını kontrol edin. Farklı ağlarda (Wi-Fi ve Mobil) test edin.
      • Cihaz Performansı: Eski cihazlar yüksek çözünürlükte kodlama/çözme işlemlerinde zorlanabilir.
      • Yapılandırma: Video çözünürlüğü, kare hızı veya bitrate ayarlarını düşürmeyi deneyin.
      • WebRTC İstatistikleri: Detaylı performans ölçümleri için WebRTC istatistiklerini etkinleştirin.

Belirli Özellik Sorunları

  1. Kamera Değiştirme Çalışmıyor
    • Hata Ayıklama:
      • webRTCConnection.switchCamera()'nın çağrıldığından emin olun.
      • Kamera değiştirme sırasında loglarda hata olup olmadığını kontrol edin.
      • Cihazda birden fazla kamera olduğundan emin olun.
      • Kamera başlatmasının doğru yapıldığını kontrol edin.
  2. Bekletme/Devam Otomatik Sessize Alma/Açma Çalışmıyor
    • Hata Ayıklama:
      • autoHandleHoldSideEffects'in yapılandırmada etkin olduğundan emin olun.
      • Bekletme/devam olaylarının doğru şekilde alındığını kontrol edin.
      • Metin kanalı bağlantı durumunu kontrol edin.
      • Olay yönetimi uygulamanızı kontrol edin.

Genel Hata Ayıklama Adımları

  1. Konsol Loglarını Kontrol Edin: Xcode'un konsolunu kullanarak SDK loglarını izleyin. İlgili etiketlerle filtreleyin, uyarı ve hatalara bakın.
  2. Yapılandırmayı Doğrulayın: ECVSdkConfiguration, DialCallParameters ve diğer özel parametrelerin ortam gereksinimlerinize uygun olduğundan emin olun.
  3. Ağ Bağlantısını Kontrol Edin: Cihazın gerekli uç noktalara erişebildiğinden emin olun. Farklı ağlarda test edin, güvenlik duvarı sorunlarını kontrol edin.
  4. Uygulamayı Basitleştirin: Temel yapılandırma ile başlayın, kademeli olarak karmaşıklık ekleyin ve sorunu izole edin.
  5. Aşamayı İzole Edin: Hatanın hangi aşamada olduğunu belirleyin: SDK başlatma, arama, kuyruk, WebRTC bağlantısı veya medya render'ı.
  6. Demo Uygulamasını Karşılaştırın: Özellikle olay yönetimi ve view controller yaşam döngüsü yönetimi konusunda kendi uygulamanız ile demo uygulamasını karşılaştırın.
  7. Tüm Olayları Loglayın: Olay yönetiminize log ekleyerek görüşme akışını izleyin, eksik veya beklenmeyen olayları tespit edin.

Destek ile İletişime Geçme

Destek ile iletişime geçerken lütfen aşağıdakileri sağlayın:

  • SDK Sürümü: (ör. ECV-175-iOS-SDK-v1.2.3)
  • Test Edilen Cihaz(lar): iPhone/iPad modeli, iOS sürümü
  • Arka Uç Sürümü: ECV v1.5 veya v1.75+
  • Yapılandırma: ECVSdkConfiguration, ilgili DialCallParameters ve özel parametreleriniz
  • Detaylı Sorun Açıklaması: Belirtiler, tekrar adımları, beklenen ve gerçek davranış
  • İlgili Konsol Logları: Sorun sırasında SDK ve uygulama loglarını yakalayın
  • Ekran Görüntüleri/Videolar: Sorunu göstermek için faydalıysa ekleyin