「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,进行监听操作

相关推荐
struggle202515 小时前
Ollmao (OH-luh-毛程序包及源码) 是一款原生 SwiftUI 应用程序,它与 Ollama 集成,可在 Mac 上本地运行强大的 AI 模型
ios·swiftui·swift
货拉拉技术1 个月前
货拉拉用户端SwiftUI踩坑之旅
ios·swiftui·swift
ZacJi1 个月前
巧用 allowsHitTesting 自定义 SignInWithAppleButton
ios·swiftui·swift
刘争Stanley1 个月前
SwiftUI 是如何改变 iOS 开发游戏规则的?
ios·swiftui·swift
1024小神1 个月前
在swiftui中使用Alamofire发送请求获取github仓库里的txt文件内容并解析
ios·github·swiftui
大熊猫侯佩1 个月前
SwiftUI 撸码常见错误 2 例漫谈
swiftui·xcode·tag·tabview·preview·coredata·fetchrequest
东坡肘子2 个月前
肘子的 Swift 周报 #063|异种肾脏移植取得突破
swiftui·swift·apple
恋猫de小郭2 个月前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
靴子学长2 个月前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
hxx2212 个月前
iOS swift开发系列--如何给swiftui内容视图添加背景图片显示
ios·swiftui·swift