注意:2天前我试着在苹果开发者论坛发帖,也没有收到任何回复
我真的被困在我的项目的这一部分,因为我想镜像的方式苹果有他们的护理视图设置显示任务给用户。我出于某种原因,不能子类化'OCKSurveyTaskViewController'作为我得到的错误是:
在作用域"中找不到类型'OCKSurveyTaskViewController'
我通过SPM 2或三次重新安装了CareKit,我弄不清楚为什么我不能子类化它,即使我看到确切的OCKSurveyTaskViewController.swift文件,它在代码中作为CareKit/iOS/Task/ViewController目录中的开放类列出。
有没有人能给我一些指导,或者另一种方式来显示我每天以另一种方式为用户建立的ORKTasks ?我更喜欢苹果在wwdc21 CareKit代码中使用的方法,但唉,我已经在这上面停留了太长时间,这是我下一步所需要的。
这是我的文件代码:
import UIKit
import CareKit
import CareKitUI
import CareKitStore
import ResearchKit
import os.log
class StudyTaskFeedViewController: OCKDailyTasksPageViewController, OCKSurveyTaskViewController {}
下面是OCKSurveyTaskViewController.swift文件的代码:
#if !os(watchOS) && canImport(ResearchKit)
import CareKitStore
import CareKitUI
import ResearchKit
import UIKit
// MARK: OCKSurveyTaskViewControllerDelegate
public protocol OCKSurveyTaskViewControllerDelegate: AnyObject {
func surveyTask(
viewController: OCKSurveyTaskViewController,
for task: OCKAnyTask,
didFinish result: Result<ORKTaskViewControllerFinishReason, Error>)
func surveyTask(
viewController: OCKSurveyTaskViewController,
shouldAllowDeletingOutcomeForEvent event: OCKAnyEvent) -> Bool
}
public extension OCKSurveyTaskViewControllerDelegate {
func surveyTask(
viewController: OCKSurveyTaskViewController,
for task: OCKAnyTask,
didFinish result: Result<ORKTaskViewControllerFinishReason, Error>) {
// No-op
}
func surveyTask(
viewController: OCKSurveyTaskViewController,
shouldAllowDeletingOutcomeForEvent event: OCKAnyEvent) -> Bool {
return true
}
}
open class OCKSurveyTaskViewController: OCKTaskViewController<OCKTaskController, OCKSurveyTaskViewSynchronizer>, ORKTaskViewControllerDelegate {
private let extractOutcome: (ORKTaskResult) -> [OCKOutcomeValue]?
public let survey: ORKTask
public weak var surveyDelegate: OCKSurveyTaskViewControllerDelegate?
public convenience init(
task: OCKAnyTask,
eventQuery: OCKEventQuery,
storeManager: OCKSynchronizedStoreManager,
survey: ORKTask,
viewSynchronizer: OCKSurveyTaskViewSynchronizer = OCKSurveyTaskViewSynchronizer(),
extractOutcome: @escaping (ORKTaskResult) -> [OCKOutcomeValue]?) {
self.init(
taskID: task.id,
eventQuery: eventQuery,
storeManager: storeManager,
survey: survey,
viewSynchronizer: viewSynchronizer,
extractOutcome: extractOutcome
)
}
public init(
taskID: String,
eventQuery: OCKEventQuery,
storeManager: OCKSynchronizedStoreManager,
survey: ORKTask,
viewSynchronizer: OCKSurveyTaskViewSynchronizer = OCKSurveyTaskViewSynchronizer(),
extractOutcome: @escaping (ORKTaskResult) -> [OCKOutcomeValue]?) {
self.survey = survey
self.extractOutcome = extractOutcome
super.init(
viewSynchronizer: viewSynchronizer,
taskID: taskID,
eventQuery: eventQuery,
storeManager: storeManager
)
}
override open func taskView(
_ taskView: UIView & OCKTaskDisplayable,
didCompleteEvent isComplete: Bool,
at indexPath: IndexPath,
sender: Any?) {
guard isComplete else {
if let event = controller.eventFor(indexPath: indexPath),
let delegate = surveyDelegate,
delegate.surveyTask(
viewController: self,
shouldAllowDeletingOutcomeForEvent: event) == false {
return
}
let cancelAction = UIAlertAction(
title: "Cancel",
style: .cancel,
handler: nil
)
let confirmAction = UIAlertAction(
title: "Delete", style: .destructive) { _ in
super.taskView(
taskView,
didCompleteEvent: isComplete,
at: indexPath,
sender: sender
)
}
let warningAlert = UIAlertController(
title: "Delete",
message: "Are you sure you want to delete your response?",
preferredStyle: .actionSheet
)
warningAlert.addAction(cancelAction)
warningAlert.addAction(confirmAction)
present(warningAlert, animated: true, completion: nil)
return
}
let surveyViewController = ORKTaskViewController(
task: survey,
taskRun: nil
)
let directory = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
).last!.appendingPathComponent("ResearchKit", isDirectory: true)
surveyViewController.outputDirectory = directory
surveyViewController.delegate = self
present(surveyViewController, animated: true, completion: nil)
}
// MARK: ORKTaskViewControllerDelegate
open func taskViewController(
_ taskViewController: ORKTaskViewController,
didFinishWith reason: ORKTaskViewControllerFinishReason,
error: Error?) {
taskViewController.dismiss(animated: true, completion: nil)
guard let task = controller.taskEvents.first?.first?.task else {
assertionFailure("Task controller is missing its task")
return
}
if let error = error {
surveyDelegate?.surveyTask(
viewController: self,
for: task,
didFinish: .failure(error)
)
return
}
guard reason == .completed else {
return
}
let indexPath = IndexPath(item: 0, section: 0)
guard let event = controller.eventFor(indexPath: indexPath) else {
return
}
guard let values = extractOutcome(taskViewController.result) else {
return
}
let outcome = OCKOutcome(
taskUUID: event.task.uuid,
taskOccurrenceIndex: event.scheduleEvent.occurrence,
values: values
)
controller.storeManager.store.addAnyOutcome(
outcome,
callbackQueue: .main) { result in
if case let .failure(error) = result {
self.surveyDelegate?.surveyTask(
viewController: self,
for: task,
didFinish: .failure(error)
)
}
self.surveyDelegate?.surveyTask(
viewController: self,
for: task,
didFinish: .success(reason)
)
}
}
}
#endif
当我尝试从"恢复"中复制演示代码时,遇到了同样的问题。在我将我的项目设置与"恢复"进行比较后,我注意到我错过了添加"健康工具包"的功能。在我的目标应用的Sign&Capabilities。在我添加了这个功能之后,它工作了。