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

SwiftUI中用SwiftSMTP发调查复盘邮件遇认证错误及方案咨询

SwiftUI应用内调查邮件发送问题及解决方案

问题描述

我在SwiftUI应用中开发了一个简单的应用内调查,用户完成问题填写并提交邮箱后,需要向用户本人和管理员发送调查复盘邮件。使用OVH域名及邮箱,尝试通过SwiftSMTP实现时持续出现认证错误。已通过第三方SMTP测试工具验证服务器正常,但测试smtp.mail.ovh.net/ssl0.ovh.net服务器及587/465端口时,均返回以下错误:

error in connection_block_invoke_2: Connection invalid
Error sending email: The preferred authorization methods could not be found on ssl0.ovh.net, or your server is sending back a STARTTLS command and requires a connection upgrade.
Admin email sending failed

同时咨询两个问题:

  1. 是否有更简便的实现方式?
  2. 出于隐私考虑,此类功能是否无法实现?

相关代码:

// MODULE TO SEND EMAIL
func sendRecapEmail(to recipientEmail: String, surveyData: [String: Any], completion: @escaping (Bool) -> Void) {
    let smtp = SMTP(
        hostname: "ssl0.ovh.net",
        email: "XXXX@XXXXX.eu",
        password: "XXXXX",
        port: 465, 
        tlsMode: .normal
    )
    
    let sender = Mail.User(name: "XXXX@XXXXX.eu", email: "XXXX@XXXXX.eu")
    let recipient = Mail.User(email: recipientEmail)
    
    let surveyRecap = surveyData.map { "\($0.key): \($0.value)" }.joined(separator: "\n")
    let mail = Mail(
        from: sender,
        to: [recipient],
        subject: "Survey replies overview",
        text: "Thank you \n\nHere is a recap of what you submitted:\n\(surveyRecap)"
    )
    
    smtp.send(mail) { error in
        if let error = error {
            print("Error sending email: \(error)")
            completion(false)
        } else {
            print("Recap email sent successfully!")
            completion(true)
        }
    }
}
// SUBMIT FUNCTION
func handleSurveySubmission(
    surveyData: [String: Any],
    recipientEmail: String,
    completion: @escaping (Bool) -> Void
) {
    let adminEmail = "XXXX@XXXXX.eu" 
    
    // Send email to the admin
    sendRecapEmail(to: adminEmail, surveyData: surveyData) { adminSuccess in
        if !adminSuccess {
            print("Admin email sending failed")
            completion(false)
            return
        }
        
        // If admin email succeeds, send confirmation email to the user
        sendRecapEmail(to: recipientEmail, surveyData: surveyData) { userSuccess in
            if !userSuccess {
                print("User email sending failed")
                completion(false)
                return
            }
            
            // If both emails succeed
            print("Both emails sent successfully!")
            completion(true)
        }
    }
}

解决方案

1. 修复SwiftSMTP与OVH的连接问题

OVH SMTP服务器的端口与TLS模式必须严格对应,你的代码中TLS模式配置错误导致认证失败:

  • 端口587(OVH官方推荐):使用TLSMode.startTLS,需先建立明文连接再升级TLS加密
  • 端口465:使用TLSMode.implicitTLS,直接建立SSL加密连接

修改sendRecapEmail中的SMTP初始化代码:

// 587端口配置(推荐)
let smtp = SMTP(
    hostname: "smtp.mail.ovh.net",
    email: "XXXX@XXXXX.eu",
    password: "XXXXX",
    port: 587,
    tlsMode: .startTLS
)

// 或465端口配置
let smtp = SMTP(
    hostname: "ssl0.ovh.net",
    email: "XXXX@XXXXX.eu",
    password: "XXXXX",
    port: 465,
    tlsMode: .implicitTLS
)

额外检查项:

  • 确认OVH邮箱已开启SMTP服务(部分托管邮箱默认关闭)
  • 若开启了两步验证,需使用应用专用密码替代原登录密码
  • 确保密码是邮箱的独立登录密码,而非OVH控制台管理密码

2. 更简便的实现方案

客户端直接发送SMTP邮件存在配置复杂、安全隐患等问题,推荐以下替代方案:

  • 后端中转:开发简单后端接口(如Node.js/PHP),客户端将调查数据和邮箱发送到后端,由后端调用OVH SMTP发送邮件。此方案避免客户端硬编码邮箱密码,稳定性更高
  • 第三方邮件API:使用SendGrid、Mailgun等服务,客户端通过API提交数据,由服务商处理邮件发送。这类服务有免费额度,配置简单,还支持邮件送达统计
  • 系统邮件组件:调用iOS系统MFMailComposeViewController,让用户通过自身邮箱发送复盘邮件,但此方案无法保证邮件必达,用户体验较差

3. 隐私合规说明

此类功能完全可以实现,但需遵守隐私规范:

  • 必须在应用内明确告知用户邮箱收集用途,并在隐私政策中详细说明
  • 仅保留必要的用户数据,无需长期存储邮箱和调查内容
  • 绝对禁止在客户端硬编码邮箱密码,避免反编译泄露导致的安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:50:22