最近在家裏研究了一下用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<String,String>
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測試代碼
<!DOCTYPE HTML>
<html>
<body>
<script>
function callback(success,code){
document.getElementById("qr").innerHTML=code;
}
function scanQrcode(){
if(window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.jsbridge){
var message = {"method":"qrcode"};
window.iosCallback=callback;
window.webkit.messageHandlers.jsbridge.postMessage(message);
}
}
</script>
<button style="width:100px;height:50px;margin-left:100px;margin-top:200px;font-size:30px;" οnclick="scanQrcode()">scan</button>
<div id="qr" style="width:250px;height:250px;margin-left:100px;margin-top:250px;font-size:30px;">
</div>
</body>
</html>
plist中加權限配置