swift5学习之旅之简易聊天室

27 篇文章 0 订阅

swift5学习之旅------简易聊天室

在这里插入图片描述
在这里插入图片描述

  • 整体代码
    Github还没上传,先用着Dropbox(可能要翻墙),看完有收获的感谢点个赞👍,如果翻不了墙要代码可以私聊我
    https://www.dropbox.com/sh/5oyxgu8vwx0ypux/AAAJ_KACNiJXIdX77OT0srKUa?dl=0

Dropbox 简易聊天室

聊天室使用了Golang中的通信,可以参考别人的介绍
https://github.com/dariencdd/StudyLog/wiki/Golang中client-server模型
golang通信

  • 核心思想
  • 网络层
    要读取写入网络流数据,就要使用 CFReadStream,CFWriteStream

CFStreamCreatePairWithSocketToHost连接服务器
输入流:inputStream把硬盘文件中的数据,读取到内存中使用。对应的是readStream
输出流:outputStream把内存中的数据存到硬盘中,对应的是outputstream

//建立网络连接
    func setupNetworkCommunication(){
        //Unmanaged表示对不清晰的内存管理对象的封装
        var readStream: Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?
        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, "127.0.0.1" as CFString, 98, &readStream, &writeStream)
        
        inputStream = readStream!.takeRetainedValue()
        outputStream = writeStream!.takeRetainedValue()
        
        inputStream.delegate = self
        
        inputStream.schedule(in: .current, forMode: .common)
        outputStream.schedule(in: .current, forMode: .common)
        
        inputStream.open()
        outputStream.open()
    }

输出流outputStream:加入聊天时,需要对username的值进行传递,所以需要把username输出到服务器,服务器再广播给所有使用者
发送信息也是输出流,把msg输出到服务器,再广播给所有使用者

outputStream.write(pointer, maxLength: data.count)

我们对username的判断可以知道服务器传送给自己的是否为自己发送的信息,再通过这个不同来改变UI

输入流inputStream:接收数据时,就是输入流,根据服务器接收到的数据对message的更改

//有字节输入
      while stream.hasBytesAvailable {
        let numberOfBytesRead = inputStream.read(buffer, maxLength: maxReadLength)
        
        if numberOfBytesRead < 0, let error = stream.streamError {
          print(error)
          break
        }
        
          //构造消息对象
        if let message = processedMessageString(buffer: buffer, length: numberOfBytesRead) {
          // 通知
          delegate?.received(message: message)
        }
      }
  • UI层
    因为msg信息不知道有多长,所以我们需要根据msg的信息对cell的高度进行更改
    这是cell高度的判断
//静态方法确定高度
    //message高度
    static func height(for message: Message) -> CGFloat {
      let maxSize = CGSize(width: 2*(UIScreen.main.bounds.size.width/3), height: CGFloat.greatestFiniteMagnitude)
      let nameHeight = message.messageSender == .ourself ? 0 : (height(forText: message.senderUsername, fontSize: 10, maxSize: maxSize) + 4 )
      let messageHeight = height(forText: message.message, fontSize: 17, maxSize: maxSize)
      
      return nameHeight + messageHeight + 32 + 16
    }
    
    //文本的高度判断
    private static func height(forText text: String, fontSize: CGFloat, maxSize: CGSize) -> CGFloat {
      let font = UIFont(name: "Helvetica", size: fontSize)!
      let attrString = NSAttributedString(string: text, attributes:[NSAttributedString.Key.font: font,NSAttributedString.Key.foregroundColor: UIColor.white])
      let textHeight = attrString.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, context: nil).size.height

      return textHeight
    }

cell添加新信息时需要重新布局

func apply(message: Message) {
        nameLabel.text = message.senderUsername
        messageLabel.text = message.message
        messageSender = message.messageSender
        //需要重新布局
        setNeedsLayout()
    }

判断自己发的信息还是别人发的信息,发送者messageSender肯定是自己,所以直接为ourself

enum MessageSender {
  case ourself
  case someoneElse
}
var messageSender: MessageSender = .ourself

文本信息的判断
根据自己的名字来判断

let messageSender: MessageSender = (name == self.username) ? .ourself : .someoneElse

UI显示的不同

if messageSender == .ourself {
        nameLabel.isHidden = true
        
        messageLabel.center = CGPoint(x: bounds.size.width - messageLabel.bounds.size.width/2 - 16, y: bounds.size.height/2)
        messageLabel.backgroundColor = #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)
      }
  • 怎么使用
    直接使用肯定是不行的,需要golang的编译
    定位到server.go的文件夹,在终端运行在这里插入图片描述
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值