You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用Swift实现:通话结束返回后触发弹窗询问的方案咨询

Swift实现通话结束返回应用后弹窗询问的方案

嘿,这个需求其实用CallKit框架结合应用激活通知就能很好解决,这也是苹果推荐的监听通话状态的方式,比旧的CoreTelephony更可靠。下面是具体的实现步骤和代码示例:

核心思路

  1. 用CallKit的CXCallObserver监听通话状态变化,标记是否有通话刚结束;
  2. 监听应用从后台回到前台的通知,当检测到刚结束通话时,弹出询问弹窗;
  3. 加入状态标记和延迟弹窗,避免误触发和提升用户体验。

具体代码实现

首先导入CallKit框架,然后在你的视图控制器(或者AppDelegate中)实现相关逻辑:

import CallKit
import UIKit

class MainViewController: UIViewController, CXCallObserverDelegate {
    // 初始化通话观察者
    private let callObserver = CXCallObserver()
    // 标记是否刚结束通话
    private var didEndCallRecently = false
    // 标记是否是当前应用发起的通话(可选,用于区分外部通话)
    private var isAppInitiatedCall = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置通话观察者代理
        callObserver.setDelegate(self, queue: DispatchQueue.main)
        // 监听应用激活通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleAppDidBecomeActive),
            name: UIApplication.didBecomeActiveNotification,
            object: nil
        )
    }

    // 监听通话状态变化
    func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        // 判断是否是当前应用发起的通话且已结束
        if call.hasEnded && isAppInitiatedCall {
            didEndCallRecently = true
            // 重置应用发起通话的标记
            isAppInitiatedCall = false
        }
    }

    // 应用回到前台时处理弹窗逻辑
    @objc private func handleAppDidBecomeActive() {
        guard didEndCallRecently else { return }
        
        // 延迟0.5秒弹窗,确保应用界面完全恢复
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            let alert = UIAlertController(
                title: "通话反馈",
                message: "请问本次通话体验如何?",
                preferredStyle: .alert
            )
            alert.addAction(UIAlertAction(title: "非常好", style: .default))
            alert.addAction(UIAlertAction(title: "一般", style: .default))
            alert.addAction(UIAlertAction(title: "不满意", style: .destructive))
            
            self.present(alert, animated: true)
            // 重置通话结束标记
            self.didEndCallRecently = false
        }
    }

    // 你的自动拨打电话方法
    func autoMakePhoneCall(phoneNumber: String) {
        guard let callURL = URL(string: "tel://\(phoneNumber)"),
              UIApplication.shared.canOpenURL(callURL) else {
            // 处理无法拨打电话的情况
            return
        }
        // 标记是当前应用发起的通话
        isAppInitiatedCall = true
        UIApplication.shared.open(callURL)
    }
}

关键细节说明

  • CallKit的优势:相比旧的CTCallCenter,CallKit的回调更稳定,即使应用在后台也能准确监听通话状态变化;
  • 状态标记:isAppInitiatedCall用于区分是当前应用发起的通话还是系统/其他应用的通话,避免无关通话结束后弹窗;
  • 延迟弹窗:加入0.5秒延迟是为了确保应用完全回到前台、界面渲染完成,避免弹窗出现时机突兀;
  • 权限配置:记得在Info.plist中添加NSPhoneUsageDescription,说明应用使用电话功能的原因,否则可能被App Store拒绝。

内容的提问来源于stack exchange,提问作者aero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:16:25