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

SwiftUI中自定义Transferable类型的ShareLink无法使用问题排查

问题描述

在SwiftUI中尝试使用ShareLink分享Core Data存储的音频文件时,初始化ShareLink出现编译错误:No exact matches in call to initializer。已让Recording实体遵循Transferable协议,但问题仍存在。

相关代码

Recording实体扩展代码

extension Recording {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<Recording> {
        return NSFetchRequest<Recording>(entityName: "Recording")
    }

    @NSManaged public var date: Date
    @NSManaged public var id: UUID
    @NSManaged public var url: String
    @NSManaged public var title: String
}

extension Recording : Identifiable, Transferable {
    static var containerUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

    public static var transferRepresentation: some TransferRepresentation {
        FileRepresentation(exportedContentType: .audio) { audio in
            SentTransferredFile(URL(string: audio.url)!)
        }
    }
}

视图代码

struct AudioPlayerView: View {
    @ObservedObject var recording: Recording

    var body: some View {
        NavigationStack {
            VStack(spacing: 20){
                VStack {
                    Text(recording.title)
                        .font(.title)
                        .bold()
                    Text("\(recording.date, format: .dateTime)")
                        .foregroundColor(.secondary)
                }
             }
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                ShareLink(item: recording) { // 编译错误行
                    Image(systemName: "square.and.arrow.up")
                }
            }
        }
    }
}

解决方案

1. 让Recording遵循Sendable协议

ShareLink的item参数要求类型同时符合Transferable和Sendable,Core Data的NSManagedObject子类默认不遵循Sendable,需显式添加@unchecked Sendable(NSManagedObject本身并非线程安全,但在UI主线程使用场景下可安全使用)。

2. 修复Transferable实现的安全问题

原代码中URL(string: audio.url)!使用强制解包,若字符串无法转为URL会导致崩溃,需添加错误处理逻辑;同时建议指定具体的音频 contentType(如.audio.wav或.audio.mp3),提升兼容性。

修复后的Recording扩展代码

extension Recording : Identifiable, Transferable, @unchecked Sendable {
    static var containerUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

    public static var transferRepresentation: some TransferRepresentation {
        // 根据实际音频格式指定contentType,示例为wav
        FileRepresentation(exportedContentType: .audio.wav) { audio in
            guard let fileUrl = URL(string: audio.url) else {
                throw TransferError.invalidAudioURL
            }
            return SentTransferredFile(fileUrl)
        }
    }

    // 定义自定义错误类型
    enum TransferError: Error {
        case invalidAudioURL
    }
}

3. 验证ShareLink初始化

修改后ShareLink(item: recording)即可正常编译,因为Recording现在同时满足Transferable和Sendable协议要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:10:02