2

I have such a structure, this structure seems wrong to me as the approach I want to ask you. So when I want to use 2 models in 1 view, I have to put it in foreach in one view. This is what I want. Using the data I use in my user's profile on other pages I want. How should I do this? How do you guys do it?

Let me give an example for your better understanding:

I want to show my user's Username data on the Homepage, how should I do this?. In fact, after initializing my model once, I want to use it in other views. What is the right approach.

  import SwiftUI

struct ContentView: View {
    @StateObject var network = ProfileNetwork()
    var body: some View {
        TabView{
            ProfileView().tabItem { Image(systemName: "house") }
            ForEach(self.network.userprofile,id:\.id){a in
                ShopView(profile_model: a)
            }.tabItem { Image(systemName: "house") }
        }
    }
}

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


class ProfileNetwork : ObservableObject {
    @Published var userprofile : [UserPRofile] = [UserPRofile(name: "Test", coin: 1, id: "dsa")]
}

struct ProfileView : View {
    @StateObject var network = ProfileNetwork()
    var body: some View {
        ForEach(self.network.userprofile, id:\.id){ i in
            ProfileViewModel(profile_model: i)
        }
    }
}

struct ProfileViewModel : View {
    var profile_model : UserPRofile
    var body: some View {
        Text(self.profile_model.name)
    }
}

struct UserPRofile : Decodable{
    var name : String
    var coin : Int
    var id : String
}

class ShopeNetwork : ObservableObject {
    @Published var shop : [ShopStore] = [ShopStore(id: "sda", image: "dasd", price: 100, name: "sda")]
}

struct ShopView : View {
    @StateObject var network = ShopeNetwork()
    var profile_model : UserPRofile
    var body: some View {
        ForEach(self.network.shop, id:\.id){ c in
            ShopViewModel(shop_model: c, profile_model: profile_model)
        }
    }
}

struct ShopViewModel : View {
    var shop_model : ShopStore
    var profile_model : UserPRofile
    var body: some View {
        Text(profile_model.name)
        Text(self.shop_model.name)
    }
}


struct ShopStore : Decodable {
    var id : String
    var image : String
    var price : Int
    var name : String
}
1
  • What is the significance of the Home Page here? Commented Jan 16, 2021 at 12:57

2 Answers 2

2

A possible solution is to create an @EnvironmentObject and inject it at the root level:

class AppState: ObservableObject {
    @Published var userProfile: UserPRofile?
}
@main
struct TestApp: App {
    @StateObject private var appState = AppState()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appState)
        }
    }
}
struct ProfileView: View {
    @EnvironmentObject private var appState: AppState // access as an `@EnvironmentObject`
    @StateObject var network = ProfileNetwork()
    var body: some View {
        VStack {
            ForEach(self.network.userprofile, id: \.id) { i in
                ProfileViewModel(profile_model: i)
            }
        }
        .onAppear {
            appState.userProfile = network.userprofile.first // set `userProfile` globally
        }
    }
}
struct ShopView: View {
    @EnvironmentObject private var appState: AppState // use it in any other view
    ...
Sign up to request clarification or add additional context in comments.

Comments

1

Swift 5, iOS 14

Make the class a singleton so it becomes shareable easily.

class ProfileNetwork : ObservableObject {
    @Published var userprofile : [UserPRofile] = [UserPRofile(name: "Test", coin: 1, id: "dsa")]
    static var shared = ProfileNetwork()
}

And then refer to it with the shared handle.

struct ContentView: View {
  @StateObject var network = ProfileNetwork.shared
  var body: some View {

....
}

struct ProfileView : View {
  @StateObject var network = ProfileNetwork.shared 
  var body: some View {

....
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.