Researchkit:如何从UIWebView手动切换到下一步

时间:2016-06-24 16:17:22

标签: ios swift swift2 researchkit

我想实现我自己的ResearchKit步骤,包括一个WebView,其中一个按钮可以切换到下一步。

因此可以

1)手动切换到下一步?

2)操纵结果,从我的WebView接收一些数据?

出于学习目的,我创建了以下内容,包括我自己的ActiveStep:

import UIKit
import ResearchKit
class DemoView: UIWebView {

}
class DemoStepViewController : ORKActiveStepViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let demoView = UIWebView()
        demoView.loadHTMLString("<html><body><p>Hello!</p></body></html>", baseURL: nil)
        demoView.translatesAutoresizingMaskIntoConstraints = false
        self.customView = demoView
        self.customView?.superview!.translatesAutoresizingMaskIntoConstraints = false
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": demoView]))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": demoView]))
    }
}
class DemoStep : ORKActiveStep {
    static func stepViewControllerClass() -> DemoStepViewController.Type {
        return DemoStepViewController.self
    }
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, ORKTaskViewControllerDelegate {
    var window: UIWindow?
    var taskResultFinishedCompletionHandler: (ORKResult -> Void)?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let activeStep = DemoStep(identifier: "webstep")
        activeStep.title = "Demo Step"
        var endStep = ORKCompletionStep(identifier: "endstep")
        endStep.title = "Well done"
        endStep.text = "thank you"
        let task = ORKOrderedTask(identifier: "orderedtask", steps: [activeStep, endStep])
        let taskViewController = ORKTaskViewController(task: task, taskRunUUID: nil)
        taskViewController.delegate = self
        taskViewController.outputDirectory = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String, isDirectory: true)
        window?.rootViewController = taskViewController
        return true
    }
    func taskViewController(taskViewController: ORKTaskViewController, didFinishWithReason reason: ORKTaskViewControllerFinishReason, error: NSError?) {
        taskResultFinishedCompletionHandler?(taskViewController.result)
        taskViewController.dismissViewControllerAnimated(true, completion: nil)
    }
}

1 个答案:

答案 0 :(得分:1)

我解决了这个问题:

1)使用从javascript接收结果的WKWebView scriptmessagehandler。一旦消息处理程序收到结果,它就会启动ActiveTask的计时器,该计时器被设置为一个非常小的值。

你可以在这里看到我的实现作为另一个stackoverflow问题的答案: Creating custom ORKStep with WKWebView

2)要将步骤结果包含在任务中,我只需在步骤视图控制器中覆盖result属性。

  var JS_Answer = ORKTextQuestionResult()

   override var result : ORKStepResult? {
    let step_Result = super.result!
    step_Result.results = [JS_Answer] // result will look up the answer here
    return step_Result
  }

  // Handle the message posted by Javascript
  func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
    if let widget_Result = message.body as? String {
      JS_Answer.identifier = step!.identifier
      // write the answer from WebView to JS_Answer, which will be accessed by result
      JS_Answer.textAnswer = widget_Result 
      start()
    }
  }