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

SwiftUI实现短信发送时messageComposeViewController未被调用问题求助

问题原因
  • 核心问题是你初始化MFMessageComposeViewController后没有绑定delegate,系统无法将用户的取消、发送等操作回调到你实现的messageComposeViewController方法中
  • 次要有优化点:updateUIViewController会在视图状态更新时重复触发displayMessageInterface,可能导致多次弹出短信编辑弹窗
修复方案

第一步 给MFMessageComposeViewController设置delegate

修改SMSMessageViewController中的displayMessageInterface方法,补充delegate绑定,同时新增变量避免重复弹窗:

class SMSMessageViewController : UIViewController, MFMessageComposeViewControllerDelegate {
    var delegate : MessagesViewDelegate?
    var recipients : [String]?
    var body :String?
    // 新增标识:是否已经弹出过短信编辑页
    private var hasPresented = false

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func displayMessageInterface(){
        // 已经弹出过就不再重复执行
        guard !hasPresented else { return }
        hasPresented = true
        
        let composeVC = MFMessageComposeViewController()
        composeVC.body = body ?? ""
        composeVC.recipients = recipients
        // 补充这一行,绑定delegate为当前控制器
        composeVC.delegate = self
        
        if MFMessageComposeViewController.canSendText(){
            self.present(composeVC,animated:true,completion: nil)
        }else{
            self.delegate?.messageCompletion(result: MessageComposeResult.failed)
        }
    }
    func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
        print("回调触发成功")
        self.delegate?.messageCompletion(result: result)
        controller.dismiss(animated: true, completion: nil)
    }
}

第二步 优化UIViewControllerRepresentable的更新逻辑

如果不需要后续动态修改收件人、短信内容,可以把displayMessageInterface的调用放到makeUIViewController里,避免updateUIViewController重复触发:

func makeUIViewController(context: Context) -> SMSMessageViewController {
    let controller = SMSMessageViewController()
    controller.delegate = context.coordinator
    controller.recipients = recipients
    controller.body = body
    // 移到这里调用,只执行一次
    controller.displayMessageInterface()
    return controller
}

func updateUIViewController(_ uiViewController: SMSMessageViewController, context: Context) {
    // 不需要动态更新短信内容/收件人这里可以留空
}
注意事项
  • 短信发送功能仅支持在真实iOS设备上测试,iOS模拟器没有短信模块,会直接走发送失败逻辑
  • 首次调用时系统会弹出权限申请弹窗,需要用户允许APP访问短信功能才能正常使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:54:04