Search code examples
swiftxcodeswiftuiapple-musickit

Cannot use instance member 'searchQuery' within property initializer; property initializers run before 'self' is available


Newer to SwiftUI coding, and can't seem to figure out this whole initializer thing. I keep getting this error when putting a variable into my API call. I'm trying to get the values of a TextField to be what the term the API calls for. This is accessing MusicKit with a CatalogueRequest. It works when you manual input a name into the request, but not any variables. Any help would be appreciated! !(https://i.sstatic.net/QMWzq.png)(https://i.sstatic.net/kWdyH.png)

import SwiftUI 
import MusicKit

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 let request: MusicCatalogSearchRequest = {
    var request = MusicCatalogSearchRequest(term: "Cruel     Summer", types: [Song.self])
    request.limit = 25
    return request
}()

private func fetchMusic() {
    Task {
        //Request permission
        let status = await MusicAuthorization.request()
        switch status {
        case .authorized:
            do {
                let result = try await     request.response()
                self.songs = result.songs.compactMap({
                    return .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))
                })
                print(String(describing: songs[0]))
            } catch {
                print(String(describing: error))
            }
        default: break
            
        }
    }
}
}

#Preview {
    SearchView()
}

I've tried doing manual initializers, explicitly defining it as a string, and keep getting more and more errors.


Solution

  • I can't see the request property being used anywhere outside the fetchMusic function so I would make it a local variable inside that function instead.

    private func fetchMusic() {
        Task {
            //Request permission
            let status = await MusicAuthorization.request()
            switch status {
            case .authorized:
                var request = MusicCatalogSearchRequest(term: searchQuery, types: [Song.self])
                request.limit = 25
                do {
                    //... rest of code