carekit-apple / CareKit

CareKit is an open source software framework for creating apps that help people better understand and manage their health.
https://www.researchandcare.org
Other
2.41k stars 444 forks source link

Updating Tasks in OCKDailyPageViewController #633

Closed matchstick462 closed 3 years ago

matchstick462 commented 3 years ago

Hi All,

Another newbie question.. I really am green (Sorry!).. I am learning a lot though and some things are starting to click 🤓

I have successfully implemented the OCKDailyPageViewController with a fetch query for tasks by groupIdentifier (Hooray! - Thank you to the awesome post response in #476 @erik-apple -> That lead me in the right direction :raised_hands:

I am struggling and confused about how to update the store once a task's event occurs / is actioned.

Each time I run the app, I am able to click on the task button and it reflects in the rings and adherence charts/ graphs. I then exit the app but next time its like it was never stored and shows the task hadn't been completed in the view. I'm thinking that somehow I have to get the synchronizers (OCKChecklistTaskSynchonizer / OCKChecklistTaskSynchronizer) invoked? Not sure how to do this with the current query but gave it a go.

What am I missing here? Stumped :disappointed:

class DailyTaskViewController: OCKDailyPageViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func dailyPageViewController(_ dailyPageViewController: OCKDailyPageViewController,
                                          prepare listViewController: OCKListViewController, for date: Date) {

        //TaskQuery for groupIdentiifers
        var query = OCKTaskQuery(for: date)
        let identifiers = ["Daily Medication", "Daily Activity"]
        query.excludesTasksWithNoEvents = true
        query.groupIdentifiers = identifiers

        storeManager.store.fetchAnyTasks(query: query, callbackQueue: .main) { result in
            switch result {
            case .failure(let error): print("Error: \(error)")
            case .success(let tasks):

                for task in tasks {

                      if !task.impactsAdherence {
                        let OCKButtonTask = OCKButtonLogTaskViewController(viewSynchronizer: OCKButtonLogTaskViewSynchronizer(), task: task, eventQuery: .init(for: date), storeManager: self.storeManager)
                        listViewController.appendViewController(OCKButtonTask, animated: true)

                        // Else default to the grid
                  } else {
                    let OCKGridTask = OCKGridTaskViewController(viewSynchronizer: OCKGridTaskViewSynchronizer(), task: task, eventQuery: .init(for: date), storeManager: self.storeManager)
                  //  card.controller.fetchAndObserveEvents(forTaskQuery: OCKTaskQuery, eventQuery: OCKEventQuery)

                    listViewController.appendViewController(OCKGridTask, animated: false)

                    }

                    if #available(iOS 14, *), let walkTask = tasks.first(where: { $0.id == "steps" }) {

                        let view = NumericProgressTaskView(
                            task: walkTask,
                            eventQuery: OCKEventQuery(for: date),
                            storeManager: self.storeManager)
                            .padding([.vertical], 10)

                        listViewController.appendViewController(view.formattedHostingController(), animated: false)
             }

                }
            }
        }
    }
}

private extension View {
    func formattedHostingController() -> UIHostingController<Self> {
        let viewController = UIHostingController(rootView: self)
        viewController.view.backgroundColor = .clear
        return viewController
    }
}
gavirawson-apple commented 3 years ago

I am learning a lot though and some things are starting to click

Glad to hear! We can always try and be here as a resource to help guide you.

I then exit the app but next time its like it was never stored and shows the task hadn't been completed in the view.

The good news is that there's likely a simple fix! Check out the place where the store is first created. There are two options when creating a store - in memory or persisted on device. I believe the former is the option we use in the sample app, and may be causing the behavior you're seeing.

// This store will clear out each time the app is re-launched
let store = OCKStore(
    name: "ock-store",
    type: .inMemory
)

// This store will persist between app launches
let store = OCKStore(
    name: "ock-store",
    type: .onDisk()
)

Let me know if that's it!

matchstick462 commented 3 years ago

@gavirawson-apple - You're a legend!! Thank you! This was really annoying and such a simple thing to miss. Closing this issue.