gpt4 book ai didi

ios - 从应用程序委托(delegate)调用时未加载调用工具包 ui

转载 作者:搜寻专家 更新时间:2023-10-31 22:58:34 29 4
gpt4 key购买 nike

我无法触发来自应用程序委托(delegate)的调用套件 UI 来电。我该怎么做呢?我尝试了扬声器盒示例,但没有帮助。当我在 ViewController 中运行 reportIncomingCall 方法时,它起作用了。当我在 AppDelegate 中运行 reportIncomingCall 时,它不起作用。我需要它在 Appdelegate 中运行,以便我可以发送 VoIP 通知来报告来电。

这是我的应用委托(delegate):

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, PKPushRegistryDelegate {

class var shared: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}

var window: UIWindow?

var providerDelegate: ViewController?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

return true
}

func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {

//register for voip notifications
let voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
voipRegistry.desiredPushTypes = Set([PKPushType.voIP])
voipRegistry.delegate = self;
}

func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenForType type: PKPushType) {

NSLog("token invalidated")

}

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, forType type: PKPushType) {

//print out the VoIP token. We will use this to test the notification.
NSLog("voip token: \(credentials.token)")

print("didUpdatePushCredentials: %@ - Type: %@", credentials.token, type)
var token: String = ""
for i in 0..<credentials.token.count {
token += String(format: "%02.2hhx", credentials.token[i] as CVarArg)
}

print(token)

}

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

print("notification receivd!")
guard type == .voIP else { return }

let uuidString = payload.dictionaryPayload["UUID"] as? String!
let roomName = payload.dictionaryPayload["roomName"] as? String!
print("uuid", uuidString!)
print("roomName", roomName!)


providerDelegate?.performStartCallAction(uuid: UUID(), roomName: "Test")

}

//Intents
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
guard let viewController = window?.rootViewController as? ViewController, let interaction = userActivity.interaction else {
return false
}

var personHandle: INPersonHandle?

if let startVideoCallIntent = interaction.intent as? INStartVideoCallIntent {
personHandle = startVideoCallIntent.contacts?[0].personHandle
} else if let startAudioCallIntent = interaction.intent as? INStartAudioCallIntent {
personHandle = startAudioCallIntent.contacts?[0].personHandle
}

if let personHandle = personHandle {
viewController.performStartCallAction(uuid: UUID(), roomName: personHandle.value)
}

return true
}

}

在 ViewController 类中:

extension ViewController : CXProviderDelegate {

func providerDidReset(_ provider: CXProvider) {
logMessage(messageText: "providerDidReset:")

localMedia?.audioController.stopAudio()
}

func providerDidBegin(_ provider: CXProvider) {
logMessage(messageText: "providerDidBegin")
//_ = Timer.scheduledTimerWithTimeInterval(15, target: self, selector: #selector(ViewController.expireCall), userInfo: nil, repeats: false)
}

func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
logMessage(messageText: "provider:didActivateAudioSession:")

localMedia?.audioController.startAudio()
}

func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
logMessage(messageText: "provider:didDeactivateAudioSession:")
}

func provider(_ provider: CXProvider, timedOutPerforming action: CXAction) {
logMessage(messageText: "provider:timedOutPerformingAction:")
}

func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
logMessage(messageText: "provider:performStartCallAction:")

localMedia?.audioController.configureAudioSession(.videoChatSpeaker)

callKitProvider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: nil)

performRoomConnect(uuid: action.callUUID, roomName: action.handle.value)

// Hang on to the action, as we will either fulfill it after we succesfully connect to the room, or fail
// it if there is an error connecting.
pendingAction = action
}

func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
logMessage(messageText: "provider:performAnswerCallAction:")

// NOTE: When using CallKit with VoIP pushes, the workaround from https://forums.developer.apple.com/message/169511
// suggests configuring audio in the completion block of the `reportNewIncomingCallWithUUID:update:completion:`
// method instead of in `provider:performAnswerCallAction:` per the Speakerbox example.
// localMedia?.audioController.configureAudioSession()

performRoomConnect(uuid: action.callUUID, roomName: self.roomTextField.text)

// Hang on to the action, as we will either fulfill it after we succesfully connect to the room, or fail
// it if there is an error connecting.
pendingAction = action
}

func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
NSLog("provider:performEndCallAction:")

localMedia?.audioController.stopAudio()
room?.disconnect()

action.fulfill()
}

func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
NSLog("provier:performSetMutedCallAction:")
toggleMic(sender: self)
action.fulfill()
}

func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
NSLog("provier:performSetHeldCallAction:")

let cxObserver = callKitCallController.callObserver
let calls = cxObserver.calls

guard let call = calls.first(where:{$0.uuid == action.callUUID}) else {
action.fail()
return
}

if call.isOnHold {
holdCall(onHold: false)
} else {
holdCall(onHold: true)
}

action.fulfill()
}
}



extension ViewController {



func performStartCallAction(uuid: UUID, roomName: String?) {
let callHandle = CXHandle(type: .generic, value: roomName ?? "")
let startCallAction = CXStartCallAction(call: uuid, handle: callHandle)
let transaction = CXTransaction(action: startCallAction)

callKitCallController.request(transaction) { error in
if let error = error {
NSLog("StartCallAction transaction request failed: \(error.localizedDescription)")
return
}

NSLog("StartCallAction transaction request successful")

let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = callHandle
callUpdate.supportsDTMF = false
callUpdate.supportsHolding = true
callUpdate.supportsGrouping = false
callUpdate.supportsUngrouping = false
callUpdate.hasVideo = true

self.callKitProvider.reportCall(with: uuid, updated: callUpdate)
}
}

func reportIncomingCall(uuid: UUID, roomName: String?, completion: ((NSError?) -> Void)? = nil) {
let callHandle = CXHandle(type: .generic, value: roomName ?? "")

print("calling!")
let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = callHandle
callUpdate.supportsDTMF = false
callUpdate.supportsHolding = true
callUpdate.supportsGrouping = false
callUpdate.supportsUngrouping = false
callUpdate.hasVideo = true

callKitProvider.reportNewIncomingCall(with: uuid, update: callUpdate) { error in
if error == nil {
NSLog("Incoming call successfully reported.")

// NOTE: CallKit with VoIP push workaround per https://forums.developer.apple.com/message/169511
self.localMedia?.audioController.configureAudioSession(.videoChatSpeaker)
} else {
NSLog("Failed to report incoming call successfully: \(error?.localizedDescription).")
}

completion?(error as? NSError)
}
}

func performEndCallAction(uuid: UUID) {
let endCallAction = CXEndCallAction(call: uuid)
let transaction = CXTransaction(action: endCallAction)

callKitCallController.request(transaction) { error in
if let error = error {
NSLog("EndCallAction transaction request failed: \(error.localizedDescription).")
return
}

NSLog("EndCallAction transaction request successful")
}
}

}

编辑

如以下评论所述,很明显我没有设置委托(delegate)。我在 vc 中有以下初始化。当我尝试在 didFinishLaunchingWithOptons 函数中设置它时,它要求我添加参数编码器。

ViewController init
required init?(coder aDecoder: NSCoder) {
let configuration = CXProviderConfiguration(localizedName: "TestApp")
configuration.maximumCallGroups = 1
configuration.maximumCallsPerCallGroup = 1
configuration.supportsVideo = true
if let callKitIcon = UIImage(named: "iconMask80") {
configuration.iconTemplateImageData = UIImagePNGRepresentation(callKitIcon)
}

callKitProvider = CXProvider(configuration: configuration)
callKitCallController = CXCallController()

super.init(coder: aDecoder)

callKitProvider.setDelegate(self, queue: nil)

}

Appdelegate/didFinishLoadingWithOptions

providerDelegate = ViewController(coder: NSCoder) //this is where its messing up.

最佳答案

如果对你有帮助,试试这个方法

将在 AppDelegate 中使用的我的 Call Ui 类

class CallUI : NSObject {  
static var shared = CallUI()
var callControllerClass = CallUIController()

func initCall(payloadResponse Response: [AnyHashable:Any]) {
callControllerClass.getDataSortedFromPayload(PayloadResponse: Response)
}
}

用于处理调用 Kit Delegates 的类

class CallUIController : UIViewController, CXProviderDelegate {

var payloadResponse : [AnyHashable:Any]?
var notificationTypeRx : CallNotificationType?
var providerName : String?

let provider = CXProvider(configuration: CXProviderConfiguration(localizedName: SAppName))
let update = CXCallUpdate()
var uuidUsed : UUID?
var providerConfiguration : CXProviderConfiguration?

func getDataSortedFromPayload(PayloadResponse Response: [AnyHashable:Any]) {
if let APSData = Response["aps"] as? [String:Any] {
if let notifyType = APSData["type"] as? String {
if notifyType == "calling" {
self.notificationTypeRx = .StartCall
self.showCallUI(ProviderName: nameUsed ?? "")
}
else if notifyType == "disconnectCalling" {
/// Need to Disconnect Call
self.notificationTypeRx = .Endcall
/// Dismiss if any Loaded UI
}
else{
print("Type of notification wasn't found")
}
}
}
else{
print("Aps Data was not found")
}
}

func showCallUI(ProviderName Name: String) {

provider.setDelegate(self, queue: nil)
uuidUsed = UUID()
update.hasVideo = true
update.remoteHandle = CXHandle(type: .phoneNumber, value: Name)
provider.reportNewIncomingCall(with: uuidUsed!, update: update, completion: { error in })
}

func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
/// Accept Action
}

func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
/// Decline Action
}


func providerDidReset(_ provider: CXProvider) {
print("Declined Status")
}

}

AppDelegate 用法

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
print("Payload API Response \(payload.dictionaryPayload)")
if UIApplication.shared.applicationState == .background {
CallUI.shared.initCall(payloadResponse: payload.dictionaryPayload)
}
}

关于ios - 从应用程序委托(delegate)调用时未加载调用工具包 ui,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40777196/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com