最近在家里研究了一下用swift5开发一个混合编程的app
app主要界面和功能是用h5来实现,用到native编码的就是二维码扫描
碰到了了一些问题做一下记录:
1、如何定义自己的ViewController并且能绑定xib视图文件
1) 新建文件选择 Cocoa Touch Class,下一步时勾选also create XIB file
2)选中xib文件如图可以看到是否已关联,也可以通过这个单独创建并关联
2、两个ViewController导航切换:
1)这个app需要两个ViewController,一个为MainViewController和ScaningViewController。先要配一个rootViewController
前面版本是在AppDelegate.swift文件里配,但swift5在SceneDelegate.swift里配置,
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
window?.rootViewController = UINavigationController(rootViewController: MainViewController())
guard let _ = (scene as? UIWindowScene) else { return }
}
2)两个页面切换代码
从MainViewController跳转到ScaningViewController
let vc=ScaningViewController()
navigationController?.pushViewController(vc, animated: true)
从ScaningViewController返回到 MainViewController
navigationController?.popViewController(animated: true)
3)数据从ScaningViewController返回到 MainViewController中
MainViewControllerx定义回调方法
//扫描返回
func someFunctionThatTakesAClosure(string:String) -> Void {
print("string :"+string)
self.navigationController?.setNavigationBarHidden(true, animated: false)
self.theWebView!.evaluateJavaScript("iosCallback(true,'(string)')",
completionHandler: nil)
}
跳转设置
//打开扫描二维码页面
func qrcode(){
print("qrcode")
let vc = ScaningViewController()
vc.initWithClosure(closure: someFunctionThatTakesAClosure)
navigationController?.pushViewController(vc, animated: true)
}
ScaningViewController中定义闭包
//声明一个闭包
var myClosure:sendValueClosure?
//下面这个方法需要传入上个界面的someFunctionThatTakesAClosure函数指针
func initWithClosure(closure:sendValueClosure?){
//将函数指针赋值给myClosure闭包,该闭包中涵盖了
//someFunctionThatTakesAClosure函数中的局部变量等的引用
myClosure = closure
}
在二维码收到字符串的地方,把字符串返回给MainViewController
if (myClosure != nil){
//闭包隐式调用someFunctionThatTakesAClosure函数:回调。
myClosure!("\(k)")
}
navigationController?.popViewController(animated: true)
3、js调用webview
MainViewController中
import UIKit
import WebKit
class MainViewController: UIViewController ,WKScriptMessageHandler{
//定义webview
var theWebView:WKWebView?
//定义本地网页路径
let path = Bundle.main.path(forResource: "index", ofType: ".html",
inDirectory: "public")
//app页面装载
override func viewDidLoad() {
super.viewDidLoad()
//隐藏首页的导航栏 true 有动画
self.navigationController?.setNavigationBarHidden(true, animated: false)
//加载页面
initWebView()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 隐藏首页的导航栏 true 有动画
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 跳转页面的导航 不隐藏 false
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
//webview初始设置
func initWebView(){
let url = URL(fileURLWithPath:path!)
let request = URLRequest(url:url)
//创建供js调用的接口
let theConfiguration = WKWebViewConfiguration()
theConfiguration.userContentController.add(self, name: "jsbridge")//网页端用这个
//将浏览器视图全屏(在内容区域全屏,不占用顶端时间条)
let frame = CGRect(x:0, y:20, width:UIScreen.main.bounds.width,
height:UIScreen.main.bounds.height-20)
theWebView = WKWebView(frame:frame, configuration: theConfiguration)
//禁用页面在最顶端时下拉拖动效果
theWebView!.scrollView.bounces = false
//加载页面
theWebView!.load(request)
self.view.addSubview(theWebView!)
}
//js与swift交互
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
let sentData = message.body as! Dictionary
print("hello")
if(sentData["method"] == "qrcode"){
qrcode()
}
}
//打开扫描二维码页面
func qrcode(){
print("qrcode")
let vc = ScaningViewController()
vc.initWithClosure(closure: someFunctionThatTakesAClosure)
navigationController?.pushViewController(vc, animated: true)
}
//扫描返回
func someFunctionThatTakesAClosure(string:String) -> Void {
print("string :"+string)
self.navigationController?.setNavigationBarHidden(true, animated: false)
self.theWebView!.evaluateJavaScript("iosCallback(true,'\(string)')",completionHandler: nil)
}
}
html测试代码
plist中加权限配置