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

Swift6重构:如何让UIActivity重写方法运行在@MainActor?

适配Swift6:解决SafariActivity的MainActor隔离问题

要解决UIApplication相关API的MainActor隔离报错,最直接的方案是将整个SafariActivity类标记为@MainActor,这样所有重写的UIActivity方法都会自动在主线程上下文执行,符合Swift6的并发安全要求。

修改后的完整代码如下:

import Foundation
import UIKit

@MainActor
public final class SafariActivity: UIActivity {

    var url: URL?
    
    // MARK: - UIActivity Implementation
    
    public override var activityType: UIActivity.ActivityType {
        .openInSafari
    }
    
    public override var activityTitle: String? {
        "Open in Safari"
    }
    
    public override var activityImage: UIImage? {
        UIImage(systemName: "safari")?.applyingSymbolConfiguration(.init(scale: .large))
    }
    
    public override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
        // 优化判断逻辑,避免强制解包
        activityItems.contains { item in
            guard let url = item as? URL else { return false }
            return UIApplication.shared.canOpenURL(url)
        }
    }
    
    public override func prepare(withActivityItems activityItems: [Any]) {
        // 用compactMap过滤出URL,再找到第一个可打开的
        url = activityItems.compactMap { $0 as? URL }.first { UIApplication.shared.canOpenURL($0) }
    }
    
    public override func perform() {
        if let url = url {
            UIApplication.shared.open(url)
        }
        activityDidFinish(true)
    }
}

extension UIActivity.ActivityType {
    static let openInSafari = UIActivity.ActivityType(rawValue: "openInSafari")
}

extension UIActivity {
    @MainActor public static let openInSafari = SafariActivity()
}

关键说明:

  • 类级别的@MainActor标记:将SafariActivity类标记为@MainActor后,所有属于该类的属性、方法都会自动纳入MainActor隔离上下文,重写的UIActivity方法自然也遵循这个规则,调用UIApplication.shared相关API时就不会再触发并发安全错误。
  • 优化判断逻辑:把原代码中的强制解包as! URL替换为可选绑定和compactMap,提升代码安全性,避免潜在的崩溃风险。
  • 保持扩展的@MainActor:原UIActivity扩展中的openInSafari静态属性已经标记了@MainActor,无需修改,确保实例创建在主线程上下文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:39:58