「SwiftUI」监听回调方法

前言:SwiftUI页面写法不再是像UIKit有ViewController,所以通常会在xxxx.delegate = self处报错,没有办法设置delegate,这也从而导致了监听回调函数全部无法使用,而回调函数在很多情况下都需要使用并且可以减少大量的能耗

实现在SwiftUI情况下可以正常使用delegate

ps:拿实现WebSocket功能为例,(WebSocket是一种客户端、服务端可以双向主动通信的网络协议,所以WebSocket需要监听是否有收到相应事件或消息)

  1. 下载添加WebSocket常用第三方库:Starscream

github链接:github.com/daltoniam/S...

  1. 查看GitHub使用方法
swift 复制代码
//使用方式
var request = URLRequest(url: URL(string: "http://localhost:8080")!)
request.timeoutInterval = 5
socket = WebSocket(request: request)
socket.delegate = self
socket.connect()

它出现了让我们头疼的socket.delegate = self

swift 复制代码
//监听回调函数
func didReceive(event: WebSocketEvent, client: WebSocket) {
	switch event {
	case .connected(let headers):
		isConnected = true
		print("websocket is connected: \(headers)")
	case .disconnected(let reason, let code):
		isConnected = false
		print("websocket is disconnected: \(reason) with code: \(code)")
	case .text(let string):
		print("Received text: \(string)")
	case .binary(let data):
		print("Received data: \(data.count)")
	case .ping(_):
		break
	case .pong(_):
		break
	case .viabilityChanged(_):
		break
	case .reconnectSuggested(_):
		break
	case .cancelled:
		isConnected = false
	case .error(let error):
		isConnected = false
		handleError(error)
	}
}
swift 复制代码
//发送String给服务端
socket.write(string: "Hi Server!") 
//example on how to write text over the socket!
  1. 在项目中搭建swift文件,将上述方法都添加进去
    但为了代码可以成功编译,所以将socket.delegate = self注释掉,稍做修改可以成功运行
Swift文件相应代码:
cpp 复制代码
import Foundation
import Starscream

var request = URLRequest(url: URL(string: "ws://192.168.1.110:8001")!)
let socket = WebSocket(request: request)
var isConnected = false


func connect(){
//    socket.delegate = self
    request.timeoutInterval = 5
    socket.connect()
}

// MARK: - WebSocketDelegate
func didReceive(event: WebSocketEvent, client: WebSocket) {
    switch event {
    case .connected(let headers):
        isConnected = true
        print("websocket is connected: \(headers)")
    case .disconnected(let reason, let code):
        isConnected = false
        print("websocket is disconnected: \(reason) with code: \(code)")
    case .text(let string):
        print("Received text: \(string)")
    case .binary(let data):
        print("Received data: \(data.count)")
    case .ping(_):
        break
    case .pong(_):
        break
    case .viabilityChanged(_):
        break
    case .reconnectSuggested(_):
        break
    case .cancelled:
        isConnected = false
    case .error(let error):
        isConnected = false
        handleError(error)
    }
}

func handleError(_ error: Error?) {
    if let e = error as? WSError {
        print("websocket encountered an error: \(e.message)")
    } else if let e = error {
        print("websocket encountered an error: \(e.localizedDescription)")
    } else {
        print("websocket encountered an error")
    }
}

// MARK: Write Text Action
func start(){
    socket.write(string: "start")
}

func end(){
    socket.write(string: "end")
}

可以实现发数据给服务端,但是服务端发送的信息,客户端无法收到,问题应该就在没有添加delegate,导致监听函数没有起作用

解决办法:

新建一个xxWebSocket类,并设置为NSObject, WebSocketDelegate类,直接贴代码

相应xxWebSocket类
swift 复制代码
import Foundation
import Starscream

class xxWebSocket:NSObject, WebSocketDelegate{
    var socket:WebSocket?
    
    //收到事件回调
    func didReceive(event: WebSocketEvent, client: WebSocketClient) {
        debugPrint("didReceive event")
        switch event {
        case .connected(let headers):
            isConnected = true
            debugPrint("websocket is connected: \(headers)")
            debugPrint("socket connect")
        case .disconnected(let reason, let code):
            isConnected = false
            print("websocket is disconnected: \(reason) with code: \(code)")
        case .text(let string):
            print("Received text: \(string)")
        case .binary(let data):
            print("Received data: \(data.count)")
        case .ping(_):
            break
        case .pong(_):
            break
        case .viabilityChanged(_):
            break
        case .reconnectSuggested(_):
            break
        case .cancelled:
            isConnected = false
        case .error(let error):
            isConnected = false
            handleError(error)
        }
    }
   
   
   public func connectServer(urlStr:String){
       var request = URLRequest(url: URL(string: urlStr)!)
       request.timeoutInterval = 5
       socket = WebSocket(request: request)
       socket?.delegate = self
       socket?.connect()
   }
   
   public func disconnect(){
       socket?.disconnect()
   }
   
   public func sendData(data:Data){
       socket?.write(data: data) {
           debugPrint("sendData callback")
       }
   }
   
   public func sendString(str:String){
       socket?.write(string: str) {
           debugPrint("send string completion \(str)")
       }
   }
}

还可以写一个自定义方法类的Delegate,实现监听操作自定义

方法类:
swift 复制代码
protocol xxWebSocketDelegate : NSObjectProtocol{
     func websocketDidConnect(socket: xxWebSocket, data: Any)
    
     func websocketDidDisconnect(socket: xxWebSocket, error:NSError?)
    
     func websocketDidReceiveMessage(socket:xxWebSocket, text: String)
    
     func websocketDidReceiveData(socket: xxWebSocket, data: NSData)
}

//需要在xxWebSocket类中进行weak var webSocketDelegate: xxWebSocketDelegate?弱引用
//然后就可以在xxWebSocket中进行调用该自定义监听方法

以上方法即可实现在SwiftUI情况下也使用delegate,进行监听操作

相关推荐
袁代码6 天前
SwiftUI开发教程系列 - 第1章:简介与环境配置
开发语言·ios·swiftui·swift·ios开发
今天也想MK代码9 天前
在Swift开发中简化应用程序发布与权限管理的解决方案——SparkleEasy
前端·javascript·chrome·macos·electron·swiftui
東三城14 天前
【ios】---SwiftUI开发从入门到放弃
ios·swiftui·swift·1024程序员节
今天也想MK代码17 天前
基于swiftui 实现3D loading 动画效果
ios·swiftui·swift
胖虎118 天前
SwiftUI(五)- ForEach循环创建视图&尺寸类&安全区域
ios·swiftui·swift·foreach·安全区域
zyosasa24 天前
SwiftUI 精通之路 11: 栅格布局
前端·swiftui·swift
小溪彼岸1 个月前
【iOS小组件实战】灵动岛实时进度通知
swiftui·swift
提笔忘字的帝国1 个月前
【ios】SwiftUI 混用 UIKit 的 Bug 解决:UITableView 无法滚动到底部
swiftui·bug·xcode
zyosasa1 个月前
SwiftUI 精通之路 09:ForEach 视图构造器的基础应用
swiftui·swift
提笔忘字的帝国1 个月前
【ios】在 SwiftUI 中实现可随时调用的加载框
ios·swiftui·xcode·swift