SwiftUI中使用searchQuery初始化MusicCatalogSearchRequest报错求助
解决SwiftUI中
Cannot use instance member 'searchQuery' within property initializer错误 问题根源
你把request定义成了视图的存储属性,在视图初始化阶段就会执行闭包创建实例,但此时视图的self还未完全初始化,无法访问@State属性searchQuery,这就是报错的核心原因。
解决方案
移除静态的request属性,改为在fetchMusic函数内部,根据当前的searchQuery动态创建MusicCatalogSearchRequest实例。这样每次触发搜索时,都会使用最新的输入关键词生成请求。
修改后的完整代码:
import SwiftUI import MusicKit struct songInfo: Identifiable { // List要求元素遵循Identifiable协议,补充实现 let id = UUID() let name: String let artist: String let artworkColor: Color? let imageURL: URL? let imageURLSmall: URL? let imageURLLarge: URL? } struct SearchView: View { @State var songs = [songInfo]() @State var searchQuery = "" var body: some View { VStack { TextField("Search", text: $searchQuery, onCommit: { fetchMusic() }) .padding() NavigationView { List(songs) { song in HStack { AsyncImage(url: song.imageURL) .frame(width: 75, height: 75, alignment: .center) VStack(alignment: .leading) { Text(song.name) .font(.title3) Text(song.artist) .font(.footnote) } .padding() } } } .onAppear { // 初始加载可注释,避免无关键词的无效请求 // fetchMusic() } } } private func fetchMusic() { // 过滤空关键词,避免无效请求 guard !searchQuery.trimmingCharacters(in: .whitespaces).isEmpty else { songs = [] return } Task { let status = await MusicAuthorization.request() switch status { case .authorized: do { // 每次搜索时用当前searchQuery创建请求 var request = MusicCatalogSearchRequest(term: searchQuery, types: [Song.self]) request.limit = 25 let result = try await request.response() songs = result.songs.compactMap({ .init(name: $0.title, artist: $0.artistName, artworkColor: $0.artwork?.backgroundColor, imageURL: $0.artwork?.url(width: 75, height: 75), imageURLSmall: $0.artwork?.url(width: 256, height: 256), imageURLLarge: $0.artwork?.url(width: 1028, height: 1028)) }) songs.first.map { print($0) } } catch { print("搜索出错:\(error.localizedDescription)") } default: print("未获得音乐库访问权限") } } } } #Preview { SearchView() }
额外优化点
- 给
songInfo补充Identifiable协议实现,满足List的元素要求 - 增加空关键词过滤逻辑,避免无意义的API请求
- 优化错误信息打印,便于调试
- 注释掉初始加载的搜索调用,可根据需求自行开启
内容的提问来源于stack exchange,提问作者Boomarov
相关产品推荐
相关产品推荐

