Fix For Type '()' cannot conform to 'View' Error?

See sample code

@State private var citiesList: [City]?

var body: some View {
    if let cities {
      content(cities)
    }
    else {
      AsyncView(
        operation: { try await getData(()) },
        content: { cities in           
          contentView(cities)
        }
      )
    }
  }

So this works ok. my issue is when adding a code above contentView(cities) since it seems this kind of closure only accepts 1 line, returning a view and does not accept any other code?

like if i add the line

citiesList = cities contentView(cities)

it will say Type '()' cannot conform to 'View'

What is the solution for this?

Or is it possible that the "cities in" part, i can assign it to the citiesList, so that citiesList will be passed to the content(citiesList) method instead of content(cities) ?

Accepted Answer

it seems this kind of closure only accepts 1 line

That's not the point. But you need to have views only.

The code does not compile at all because it is very incomplete, so very hard to understand what you need precisely.

  • You do not tell how cities is defined at top for if let cities
  • what is content ? do you mean ContentView ?
  • what is AsyncView ? Is it something you imported form here : https://www.ralfebert.com/ios-app-development/swiftui/asyncview/

Several ways to solve it such as:

  • add this code in a modifier as .onAppear
        if let cities {
            contentView(cities)
                .onAppear { citiesList = cities }
        }

But please explain more the context of this part of code.

@Claude31, under asyncView there is the part "cities in " which cities is passed to the content function. I wish to set this to the citiesList variable, so i will pass it as content(citiesList)

import SwiftUI

struct CityListView: View {
   
  private let MAX_DISPLAY_PER_FETCH = 20
  private var cityUrl: String?
   
    @State private var citiesList: [City]?
    @State private var html: String?
    @State private var index = 0
    @State private var showFooter = true
   
  init(cities: [City]? = nil) {
    self.citiesList = cities
    setupData()
  }
   
  var body: some View {
    if let citiesList {
      content(citiesList)
    }
    else {
      AsyncView(
        operation: { try await getCities() },
        content: { cities in
          content(cities)
        }
      )
    }
  }
   
  func content(_ cities: [City]) -> some View {
    return GeometryReader { geometryProxy in
      ScrollView {
        LazyVStack(alignment: .leading, spacing: 0) {
          if cities.count > 0 {
            ForEach(cities) { city in
              HStack {
                Text(city.header)
                  .bold()
                  .foregroundColor(.white)
                  .textCase(.uppercase)
                  .padding(.all, 8)
                Spacer()
              }
              .background(Color(UIColor(named: PrefTool.instance.getBoolean(Keyword.DARK_MODE) ? "DarkerGray" : "DarkGray")!))
             
              ForEach(city.businesses) { business in
                Text(business.name)
                 
                Divider()
              }
            }
          }
          else {
            Text("Empty List")
          }
        }
        .safeAreaInset(edge: .bottom, spacing: 0) {
          if showFooter {
            VStack {
              Text("Footer")
            }
            .padding()
            .frame(maxWidth: .infinity)
            // The background will extend automatically to the edge
            .background(Color.green)
            .onBecomingVisible {
              Task {
                do {
                  let moreList = try await getMoreCities(index)
                  showFooter = false
                  if !moreList.isEmpty {
                    citiesList?.append(contentsOf: moreList)
                    showFooter = true
                  }
                } catch {
                  showFooter = false
                }
              }
            }
          }
        }
      }
    }
  }
   
  func getCities() async throws -> [City] {
    let cachedIndex = index
    html = try await Web.getRequest(url)
    index = index + MAX_DISPLAY_PER_FETCH
    self.citiesList = CityParser.getCities(html ?? "", cachedIndex, MAX_DISPLAY_PER_FETCH)
    return self.citiesList ?? []
  }
   
  func getMoreCities(_ from: Int) async throws -> [City] {
    let cachedIndex = index
    index = index + MAX_DISPLAY_PER_FETCH
    return CityParser.getCities(html ?? "", cachedIndex, MAX_DISPLAY_PER_FETCH)
  }
   
}

Thanks.

Did you try what I proposed:

        content: { cities in
          content(cities)
             .onAppear { citiesList = cities }
        }
Fix For Type '()' cannot conform to 'View' Error?
 
 
Q