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

iOS端使用Swift调用Outlook发送带附件邮件的实现方法

实现说明

你当前使用的ms-outlook://compose URL Scheme仅支持to、cc、bcc、subject、body 5个基础查询参数,微软未开放该Scheme的附件传递能力,无法通过拼接URL的方式直接添加附件。
目前唯一稳定合规的实现方式是通过iOS系统级UIActivityViewController分享面板调起Outlook,系统会自动将附件、邮件基础信息传递给Outlook完成预填充。

具体实现步骤(Swift)
  • 前置配置:在项目Info.plist中添加Outlook URL Scheme白名单,否则无法检测Outlook安装状态
  • 将待发送附件写入App本地临时目录,获取可被系统读取的文件URL
  • 自定义UIActivityItemSource对象封装收件人、主题、正文等基础邮件信息
  • 初始化UIActivityViewController,将邮件信息对象、附件文件URL作为分享项传入
  • 过滤不需要的分享渠道,适配iPad端弹出样式后调起面板
核心代码示例

Info.plist白名单配置:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>ms-outlook</string>
</array>

Swift业务代码:

import UIKit

func sendEmailViaOutlookWithAttachment(
    to: [String],
    subject: String,
    body: String,
    attachmentData: Data,
    attachmentFileName: String,
    from viewController: UIViewController
) {
    // 提前判断Outlook是否安装
    guard let outlookUrl = URL(string: "ms-outlook://"),
          UIApplication.shared.canOpenURL(outlookUrl) else {
        print("未安装Outlook客户端")
        return
    }

    // 1. 将附件写入临时目录,生成系统可读取的文件URL
    let tempPath = NSTemporaryDirectory()
    let attachmentPath = (tempPath as NSString).appendingPathComponent(attachmentFileName)
    let attachmentUrl = URL(fileURLWithPath: attachmentPath)
    do {
        try attachmentData.write(to: attachmentUrl)
    } catch {
        print("附件写入临时目录失败: \(error.localizedDescription)")
        return
    }

    // 2. 构造邮件基础信息对象
    let emailContent = OutlookEmailItem(
        toRecipients: to,
        subject: subject,
        body: body
    )

    // 3. 初始化分享控制器
    let activityVC = UIActivityViewController(
        activityItems: [emailContent, attachmentUrl],
        applicationActivities: nil
    )

    // 4. 可选:过滤非必要分享渠道
    activityVC.excludedActivityTypes = [
        .mail,
        .message,
        .airDrop,
        .copyToPasteboard,
        .postToSocial
    ]

    // 适配iPad弹出样式
    if let popover = activityVC.popoverPresentationController {
        popover.sourceView = viewController.view
        popover.sourceRect = CGRect(x: viewController.view.bounds.midX, y: viewController.view.bounds.midY, width: 0, height: 0)
        popover.permittedArrowDirections = []
    }

    viewController.present(activityVC, animated: true)
}

// 自定义邮件信息传递对象
class OutlookEmailItem: NSObject, UIActivityItemSource {
    private let toRecipients: [String]
    private let subject: String
    private let body: String

    init(toRecipients: [String], subject: String, body: String) {
        self.toRecipients = toRecipients
        self.subject = subject
        self.body = body
        super.init()
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return body
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        // 仅向Outlook返回正文内容
        guard activityType?.rawValue == "com.microsoft.Office.Outlook.compose" else {
            return nil
        }
        return body
    }

    func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
        return subject
    }

    @available(iOS 13.0, *)
    func activityViewController(_ activityViewController: UIActivityViewController, emailToRecipientsForActivityType activityType: UIActivity.ActivityType?) -> [String]? {
        return toRecipients
    }
}
注意事项
  • 出于iOS沙盒安全限制,Outlook无法直接读取你App沙盒内的文件,任何尝试通过URL Scheme传递文件路径的方案都无法生效
  • 若需要添加多个附件,只需将所有附件对应的本地文件URL依次加入activityItems数组即可
  • 上述实现为微软官方适配的标准调用方式,不会随Outlook版本升级出现兼容问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:33:26