using and calling functions inside my view file

So I have the function: storeFaveArtwork and I am trying to action it in my button further down using: self.storeFaveArtwork(artwork.id)

I am getting the error at the top in my

var body: some View {

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Here is my code:

//
// ContentView.swift
// Shared
//
// Created by J*** B******* on 04/05/2022.
//

import SwiftUI
import Firebase

struct ContentView: View {
  private func storeFaveArtwork(artwork: Artwork) {
    guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
      return
    }
    let artData = ["id": artwork.id, "uid": uid] as [String : Any]
    FirebaseManager.shared.firestore.collection("favourites")
      .document(uid).setData(artData) { err in
        if let err = err {
          print(err)
          return
        }
        print("Success")
      }
  }
  @StateObject var viewAllArtwork = ViewAllArtwork()
  var body: some View {
    NavigationView {
      List {
        ForEach(viewAllArtwork.artworksData, id: \.self) { artwork in
          NavigationLink(destination: ContentDetail(item: artwork)) {
             
            HStack(alignment: .top, spacing: 3.0) {
              URLImage(urlString: "https://melvynbiddulph.co.uk/images/gallery/"+artwork.file)
               
              VStack(alignment: .leading, spacing: 3.0) {
                if(artwork.id != nil){
                  Text("\(artwork.id)")
                    .font(.caption2)
                    .fontWeight(.bold)
                    .padding(2.0)
                    .foregroundColor(Color.gray)
                    .frame(width: 32.0, height: 32.0)
                    .shadow(radius: 20)
                    .overlay(RoundedRectangle(cornerRadius: 20)
                              .stroke(Color.gray, lineWidth: 2))
                    .background(Color.white, in: RoundedRectangle(cornerRadius: 20)
                    ).position(x: -124, y: 20)
                }
                Text(artwork.title)
                  .font(.body)
                  .bold()
                  .frame(height: 36, alignment: .center)
                        .frame(maxWidth: .infinity)
                HStack(spacing: 2) {
                   
                  if (artwork.size != nil) {
                    Text(artwork.size)
                      .padding(4)
                      .font(.caption)
                      .background(Color.gray.opacity(0.2))
                      .cornerRadius(5)
                      .foregroundColor(Color.gray)
                      .frame(height: 25, alignment: .center)
                            .frame(maxWidth: .infinity)
                  }
                  if (artwork.price != 0) {
                    Text("£\(artwork.price)")
                      .fontWeight(.bold)
                      .padding(4)
                      .font(.caption)
                      .background(Color.green)
                      .cornerRadius(5)
                      .foregroundColor(Color.white)
                      .frame(width: .infinity)
                  }
                  Button {
                    self.storeFaveArtwork(artwork.id)
                  } label: {
                    HStack {
                      Spacer()
                      Text("Favourite")
                        .foregroundColor(.white)
                        .padding(.vertical, 10)
                        .font(.system(size: 14, weight: .semibold))
                      Spacer()
                    }.background(Color.blue)
                  }
                  Spacer()
                    .frame(width: 0.0, height: 60.0)
                }
                 
              }
              .frame(width: 150.0)
               
            }
          }
        }
      }
      .navigationTitle("Artwork")
      .onAppear {
        viewAllArtwork.fetch()
      }
    }
  }
}


struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

Accepted Reply

The line:

public func storeFaveArtwork(artwork) {

does not make sense.

I would expect something like:

public func storeFaveArtwork(artwork: Artwork) {

Replies

As the compiler says, you have put too much functionality into one View.
Even if the code is legal, it's not good practice.

Refactor, breaking up your functionality into smaller components.

You have made it a bit hard to be more specific, as your sample code includes a lot of external/undefined objects and functionality.

As a starting point, you could refactor the internal VStack and HStacks into separate Views.

You could factor out the Button, like this:

struct StoreFaveArtworkButtonView: View {
    
    let artwork: Artwork
    
    private func storeFaveArtwork(artwork: Artwork) {
        guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
            return
        }
        let artData = ["id": artwork.id, "uid": uid] as [String : Any]
        FirebaseManager.shared.firestore.collection("favourites")
            .document(uid).setData(artData) { err in
                if let err = err {
                    print(err)
                    return
                }
                print("Success")
            }
    }
    
    var body: some View {
        Button {
            storeFaveArtwork(artwork: artwork)
        } label: {
            HStack {
                Spacer()
                Text("Favourite")
                    .foregroundColor(.white)
                    .padding(.vertical, 10)
                    .font(.system(size: 14, weight: .semibold))
                Spacer()
            }.background(Color.blue)
        }
    }
}

So I tried a separate view, that didn't work, I still get: The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

how would it know what 'artwork ' is too?!

  • After refactoring into separate views, if the compiler still says that it is too complicated, then you need to refactor some more!

Add a Comment

ok so I created a separate view but now I am getting Cannot find type 'artwork' in scope on this line:

public func storeFaveArtwork(artwork) {

here is my view:

//
// SizePriceView.swift
// MBiddulph (iOS)
//
// Created by J** B****** on 05/06/2022.
//

import SwiftUI

struct SizePriceView: View {
  let artwork: Artwork
  var body: some View {
    HStack(spacing: 2) {
       
      if (artwork.size != nil) {
        Text(artwork.size)
          .padding(4)
          .font(.caption)
          .background(Color.gray.opacity(0.2))
          .cornerRadius(5)
          .foregroundColor(Color.gray)
          .frame(height: 25, alignment: .center)
                .frame(maxWidth: .infinity)
      }
      if (artwork.price != 0) {
        Text("£\(artwork.price)")
          .fontWeight(.bold)
          .padding(4)
          .font(.caption)
          .background(Color.green)
          .cornerRadius(5)
          .foregroundColor(Color.white)
          .frame(width: .infinity)
      }
        Button {
          storeFaveArtwork(artwork: artwork)
        } label: {
          HStack {
            Spacer()
            Text("Favourite")
              .foregroundColor(.white)
              .padding(.vertical, 10)
              .font(.system(size: 14, weight: .semibold))
            Spacer()
          }.background(Color.blue)
        }
      Spacer()
        .frame(width: 0.0, height: 60.0)
    }
    public func storeFaveArtwork(artwork) {
      guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
        return
      }
      let artData = ["id": artwork.id as Any, "uid": uid] as [String : Any]
      FirebaseManager.shared.firestore.collection("favourites")
        .document(uid).setData(artData) { err in
          if let err = err {
            print(err)
            return
          }
          print("Success")
        }
    }
  }
}
  • Where do you define "Artwork"?

Add a Comment

The line:

public func storeFaveArtwork(artwork) {

does not make sense.

I would expect something like:

public func storeFaveArtwork(artwork: Artwork) {