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

Swift报错:Type '()'无法符合'AccessibilityRotorContent'及CoreData存储疑问

问题解决:CoreData存储API数据及遍历报错处理

一、报错原因及解决方法

你遇到的Type '()' cannot conform to 'AccessibilityRotorContent'错误,核心原因是**ForEach是SwiftUI专用于视图渲染的组件,仅能在View结构体内部使用**,不能在ViewModel的异步回调逻辑里用来遍历数据执行存储操作。这里直接用普通的for-in循环替代即可。

修改后的performSearch方法:

func performSearch() {
    guard let gUrl = URL(string: "https://api.artic.edu/api/v1/artworks") else { return }

    Task {
        do {
            let (data, _) = try await URLSession.shared.data(from: gUrl)
            let response = try JSONDecoder().decode(ResponseData.self, from: data)
            DispatchQueue.main.async { [weak self] in
                guard let self = self, let fetchedResults = response.data else { return }
                self.results = fetchedResults
                // 用普通for-in循环遍历存储
                for item in fetchedResults {
                    self.coreDM.saveResult(title: item.title ?? "")
                }
            }
        } catch {
            print("*** ERROR ***: \(error.localizedDescription)")
        }
    }
}

额外优化点:

  • 增加guard let self = self避免可选值反复解包,同时防止循环引用
  • 直接用response.data的非可选值遍历,不用依赖已赋值的self.results
  • 错误打印时输出具体信息,方便定位问题

二、CoreData是否适合作为存储位置?

完全适合,理由如下:

  • 若需要离线访问艺术品数据,CoreData能提供可靠的本地持久化能力
  • 后续若数据结构扩展(比如增加作者、分类等关联字段),CoreData的实体关联、查询能力比普通文件存储或UserDefaults更灵活
  • 数据量较大时,CoreData的批量操作、分页查询性能更优

如果只是临时缓存少量简单数据,UserDefaults也可备选,但CoreData的扩展性更强,更适合长期维护的项目。

三、完整代码参考

HomeViewModel

import Foundation
import CoreData
import SwiftUI

class HomeViewModel: ObservableObject {
    @Published var results = [ResultItem]()
    let coreDM: PersistenceController = PersistenceController()

    func performSearch() {
        guard let gUrl = URL(string: "https://api.artic.edu/api/v1/artworks") else { return }

        Task {
            do {
                let (data, _) = try await URLSession.shared.data(from: gUrl)
                let response = try JSONDecoder().decode(ResponseData.self, from: data)
                DispatchQueue.main.async { [weak self] in
                    guard let self = self, let fetchedResults = response.data else { return }
                    self.results = fetchedResults
                    for item in fetchedResults {
                        self.coreDM.saveResult(title: item.title ?? "")
                    }
                }
            } catch {
                print("*** ERROR ***: \(error.localizedDescription)")
            }
        }
    }
}

Data Model

import Foundation

// MARK: - 响应数据结构
struct ResponseData: Codable, Hashable {
    let data: [ResultItem]?
}

// MARK: - 艺术品条目
struct ResultItem: Codable, Hashable {
    var id: Double?
    var title: String?
}

CoreData 核心方法

func saveResult(title: String) {
    let result = Item(context: container.viewContext)
    result.title = title

    do {
        try container.viewContext.save()
    } catch {
        print("CoreData存储错误: \(error.localizedDescription)")
    }
}

func getResult() -> [Item] {
    let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest()

    do {
        return try container.viewContext.fetch(fetchRequest)
    } catch {
        print("CoreData查询错误: \(error.localizedDescription)")
        return []
    }
}

内容的提问来源于stack exchange,提问作者New iOS Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:27:26