用swift5開發一個混合編程的app

 

 

最近在家裏研究了一下用swift5開發一個混合編程的app

app主要界面和功能是用h5來實現,用到native編碼的就是二維碼掃描

碰到了了一些問題做一下記錄:

1、如何定義自己的ViewController並且能綁定xib視圖文件

     1) 新建文件選擇 Cocoa Touch Class,下一步時勾選also create XIB file

圖1

     2)選中xib文件如圖可以看到是否已關聯,也可以通過這個單獨創建並關聯

    圖2

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 }
    }

圖3

  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中加權限配置

圖4

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章