GO FURTHER, FASTER: Try the Swift Career Accelerator today! >>

SOLVED: Distributing Fetched Data to Multiple Views in watchOS App

Forums > watchOS

Hey everyone!

I'm working on a watchOS app to track my golf stats. I've got the UI set up, but I'm running into problems when trying to get data to show up in the different views. Here's my pseudo code to give you an idea of how I've structured things. Each View is its own script, with the Main Menu View being the main one.

Main Menu View
    Add course Button
        Text Input Field
        Confirm and Cancel Buttons
    List of CourseCellViews
        Populated from save data

Course Cell View
    Navigation Link to Course View
        HStack
            Course Name
            Course Average Score

Course View
    Nav Title: Course Name
    Text Course Average
    List of Round Cell Views
        Populated from save data

RoundCellView
    Navigation Link to Round View
        HStack
            Round Date
            Hole Count
            Round Average

Round View
    Nav Title: Course Name, round data
    List of Hole Cell View
        Populated from save data

Hole Cell View
    Navigation Link to Hole View
        HStack
            Hole #
            Par
            Strokes
            Score (eg: -1 / - / +1)

Hole View
    VStack
        Course Name
        Round Date
        Hole Number
    HStack
        Picker for Par
        Picker for Strokes
    Navigation Link “Submit” to previous Round View

I'm using Core Data and I've set up all the entities with attributes and one to many relationships: course, rounds, holes. I can get the course name to load in the main ContentView, but I'm stuck on how to send this data to other parts like Course Cell View or Round Cell View.

I've saved and loaded data with JSON before, my experience mostly lies in working with Unity in C#. But I'd like to use Core Data in this app.

I've watched a lot of the videos from the 'Hacking with Swift' 100 days course, and tried to implement that code into my project, but it's just not working, I'm missing some overarching understanding, and I'm just getting more mixed up.

I've tried using @State, @Binding, @ObservedObject, @EnvironmentObject, and I've googled them to figure out what they are, but I'm just not getting it. The tutorials I've found online just don't seem an exact match for my use case, or I'm just not understanding it.

I'm sorry if this has been asked before or if I'm going over old ground. I'm just not sure what to do now.

Anyone have any advice / ideas / tips on how I can save, fetch, and disseminate data in my app using CoreData?

Thanks for any help you can give!

3      

@Olorin has shanked a ball into the rough...

I've watched a lot of the videos from the 'Hacking with Swift' 100 days course,
and tried to implement that code into my project, but it's just not working,
I'm missing some overarching understanding, and I'm just getting more mixed up.

Welcome to Hacking WIth Swift!

Most students follow the course a day-at-a-time to pick up concepts, work thru the assignements, confirm their understanding, and build on their knowledge as they progress.

Then there's folks like you who have a bunch of programming on their resume and are looking for the HackingWithSwift - Fast Pass course. This course, as you found out thru the YouTubes, doesn't exist and you're frustrated because you're missing some overarching understanding.

Bad luck though, you've also come to HackingWIthSwift at a time when the lastest versions of Swift and SwiftUI had significant updates in June and our host @twoStraws hasn't updated his course videos yet. (In progress!)

See -> What's New in Swift?

In particular, @ObservedObject and @EnvironmentObject have changed, in a Big Way™️. So it's a bit of a problem to describe how these used to work, then try to explain the new syntax, especially since there aren't new videos released yet.

But let's see if I can bridge some of the overarching understanding with some simple examples.

@State

Think of a room in your house, your computer room perhaps. What's the state of the overhead fan? Is it on or off? What's the state of the room's window? Is it open or closed? @State variables only track the state of variables in a single view. You do not access one room's state from other parts of your house.

@Binding

Maybe your room object has a sub-view you've designed to use in other rooms. A fancy wall switch, for example. When you flip the switch up or down, you want to take the state of the switch, and push the switch's state to the overhead fan. In this case, you'll define the fan state in your Room object, and bind that state to the on-off state in the switch subview. This way when you flip the switch, the actual value that is changing is the fan's state in the room.

@ObservedObject & @ObservableObject

Your house may have a central control panel that you'd like to use to control lights and fans in the entire house. In this case, you'll define a class object with the states of electrical devices in your home. Because it's a class, the object will stay in memory as long as some part of your program has a pointer to the class. Also, because it's a class, all objects linking to it will share the one object. You'll need to mark properties as @Published to make them available to other parts of your house. All the rooms should have a reference to this one control panel object.

You define the class as being an @ObservableObject. When you reference the class in a view, you'll mark it as an @ObservedObject. That is, this thing can be observed. And I am a view that will be observing that object for changes.

Whenever the state of one of the published properties changes (turn on the bubbles in the HotTub), any object that is observing the shared ControlPanel object will have the opportunity to react. In this case, your computer room will be notified that the ControlPanel object was updated, but will ignore the notification because it involves the outdoor hot tub. On the otherhand, the outdoor deck space might respond by queuing up your favorite smoooooooth jazz playlist and dimming the lights.

@EnvironmentObject still feels like a mystery to me. I think it's an ugly way to inject the control panel into your entire house rather than to just the rooms where you might need it. This might be a way to Get Quick Results™️, so I won't judge you if you just use it as a global variable dispatch mechanism.

CoreData vs SwiftData

Also, keep in mind that CoreData was written dog's years ago for ObjectiveC programmers. It was quite clunky to use, and had a steep learning curve for many wanna-be app developers. This year, Apple introduced a Swiftier version of CoreData named SwiftData. This was a welcome relief to many. Now we don't have to learn CoreData and can start fresh with an easier-to-use native framework for persistence. Donny Wals has a great series (and a terriffic book!) about CoreData. But think hard! Do you really want to start this path? If you're new to SwiftUI and iWatch programming, perhaps is just best to let CoreData wallow in the sandtrap. Instead, tee-up on a brand new Par-3 on the front 9.

HackingWithSwift Live!

@twoStraws held a terriffic live event on June 26th and 27th. He spent most of the second day going through the new syntax for SwiftData and developed a SwiftData-based app in that session. I think that session is available to HackingWIthSwift+ members. If you have disposable income for an iWatch and a sleeve of Calloway soft-centers, you can join HWS+ for a few months and get your euros-worth of videos with complete walk-throughs.

So Far, So Good?

Well if this helps get you back on the green, great. Now that you're selecting your next iron, we're changing the course. The fairway is a little straighter, and there are fewer sandtraps.

Rule Changes

@ObservedObject has been deprecated. Don't use it anymore, learn the new way.
@Bindable and @Binding have also changed.
@Published isn't necessary anymore.
@Attribute helps you with uniquing your SwiftData objects.
@FetchResults? Bhuh-bye! Now you use @Query to keep your app in sync with your data source.
@Model is simply magical for defining SwiftData models. Why even mess with entities in an xcDataModeld file?? @EnvironmentObject? Yup, that also got a makeover. I wouldn't try to croggle a new app until you research the latest sweet syntax.

@twoStraws relayed to his followers that he's updating the course. It will, naturally, have better examples, and will explain the syntax in full. But his is a work in progress.

In the meantime, FloCodes, Karin Prater, Stewart Lynch, Code WIth Chris, Vincent Pradeilles, Swiftful Thinking, and many other Swift bloggers have posted snips, vids, and commentary on the latest SwiftUI syntax. And aren't you lucky!? Sean Allen just dropped a new 30 minute SwiftData tutorial this week.

Keep Coding

Please go find your answers, then come back here, share your findings, contribute to the lessons, and provide links to your app in the AppStore.

3      

Thank you for the detailed response.

That makes sense that I'm having issues as a new version was just released and I'm using older tutorials.

I might sub to HWS+ to view that live event on SwiftData. Also will eagerly await new tutorials for the newest version of Swift.

I appreciate the time you took to respond, and the details you provided for @State, @Binding, etc.. So helpful in understand their use cases.

I will practice more and come back stronger. haha

Thanks again!

3      

Breaking News


Just as I posted, @twoStraws released a new SwiftData series on 30 September! Hope you have subscribed and tapped the bell for notifications!

See -> HWS SwiftData Series

Also, if you found this to be useful, please mark your thread as "Solved" !

4      

Fantastic! I've been watching the tutorial and am learning alot.

But his tutorial has given me a question.

Currently I have been structuring my data as such:

A course has rounds, and rounds have holes. So a class for Course, a class for Round, and a class for Hole.

That way the user will be able to select which course they are playing on, and can add a round to it when they play.

However, his tutorial made me think; should there just be rounds, and each round has a course name? Then I can simply sort the Rounds by Course name on the main screen?

I guess my question is, how should I be structuring this data? What do you more experienced coders think?

Thanks again!

3      

The problem appears to lie in the data flow between the views of your watchOS app. Although the structure is in place, the data is not being transmitted to the sub-views. Instead of using JSON, concentrate on Core Data. Here's the solution:

Utilize @FetchRequest in your Course Cell View and Round Cell View to directly fetch relevant data from Core Data based on the selected Course or Round in the parent view. Pass the selected course/round object via Navigation Links rather than just names. In the Hole View, you can retrieve data from the passed object for Course Name, Round Date, etc. Implement Pickers to modify the Core Data object and save changes using Core Data methods. Emphasize @FetchRequest for data retrieval and object passing to facilitate data flow between views. Rest assured, this is not a redundant question, and this method should address your data transfer issues.

   

Hacking with Swift is sponsored by Essential Developer.

SPONSORED Transform your career with the iOS Lead Essentials. This Black Friday, unlock over 40 hours of expert training, mentorship, and community support to secure your place among the best devs. Click for early access to this limited offer and a free crash course.

Save your spot

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.