使用WKWebView创build自定义ORKStep
我对iOS开发比较陌生,目前使用Swift来开发一个原型的ResearchKit应用程序。 其中一个要求是在一个WKWebView
中embedded一个WKWebView
,包含三个步骤: ORKQuestionStep
, ORKWebViewStep
, ORKCompletionStep
。 我似乎无法find关于如何使用Swift子类化ORKStep
和ORKStepViewController
创build自定义步骤的很多信息。 有人可以指导我正确的方向如何子类ORKStep
和ORKStepViewController
显示使用Swift的WKWebView
?
先谢谢你!
Yuan Zhu在ResearchKit-Users邮件列表中的回答:
我想你可以:
- 创build一个
ORKActiveStep
并正确configuration它。- 实现
- (void)taskViewController:(ORKTaskViewController *)taskViewController stepViewControllerWillAppear:(ORKStepViewController *)stepViewController
委托方法。- 通过其
customView
属性将您的webView
注入到ORKActiveStepViewController
。
我已经build立了我自己的ORKWebView如下。 我很高兴评论如何改善这一点。
1.子类ORKActiveStep
class Javascript_Step : ORKActiveStep { static func stepViewControllerClass ( ) -> Javascript_Step_View_Controller.Type { return Javascript_Step_View_Controller.self } }
2.子类ORKActiveStepViewController
在这里你将修改你的WebView及其组件。 为了退出WebView并传递结果,我使用Javascript。
import Foundation import ResearchKit import WebKit class Javascript_Step_View_Controller : ORKActiveStepViewController, WKScriptMessageHandler { weak var webView: WKWebView! var html : String = "<!DOCTYPE html><html><head> <meta charset=\"UTF-8\"> <title>JS Widget</title> <style type=\"text/css\"> h1 { color: red } </style></head><body> <h1>Test</h1> <input type=\"button\" value=\"Say hello\" onClick=\"Finish_This_Widget('Result is String')\" /> <script type=\"text/javascript\"> function Finish_This_Widget(string) { App.Finish_Widget(string) } </script></body></html>" // Here the result message posted by Javascript can be handled func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) { if let result = message.body as? String { print("userContentController: \(result)") // With the incoming reult of your webview, the ORKActiveStep timer will be started start() } } override func viewDidLoad() { super.viewDidLoad() // Here you set the function name to call from javascript let controller = WKUserContentController() controller.addScriptMessageHandler(self, name: "Finish_Widget") let config = WKWebViewConfiguration() config.userContentController = controller let frame = CGRectMake(20, 20, 200, 200) let webView = WKWebView(frame: frame, configuration: config) self.customView = webView // Set the view constraints (warning message with following unproper settings) self.customView?.superview!.translatesAutoresizingMaskIntoConstraints = false view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": webView])) view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": webView])) // Load the html string webView.loadHTMLString(html, baseURL: NSBundle.mainBundle().bundleURL) webView.translatesAutoresizingMaskIntoConstraints = false self.webView = webView } }
3.使用WebViewStep加载任务
在步骤2中,我们看到了start()函数调用,我们需要能够完成该步骤并切换到下一个步骤。 这就是为什么我们希望计时器在启动后立即完成。
// This functions gives you the Step you can work with finanlly func Javascript_Widget_Step ( identifier : String, title : String, text : String ) -> ORKActiveStep { let active_Step = Javascript_Step(identifier: identifier) // Set title and text for the step (which is optional) active_Step.title = title active_Step.text = text // set stepduration to a minimum -> after javascript function call, step will be finished active_Step.stepDuration = 0.001 // if this is false, it will not switch to the next step after the javascript call automatically active_Step.shouldContinueOnFinish = true return active_Step }
打开问题
我怎样才能注入的HTML? 如果我不想要一个静态的WebView,并且始终使用相同的HTML,那么我可以从外部设置这个HTMLstring?