ios 解包时意外发现nil ... MessageKit

cvxl0en2  于 2023-02-20  发布在  iOS
关注(0)|答案(1)|浏览(130)

我为消息设置了一个结构体,每次我在应用程序中加载消息时,我都会在这行代码中意外地发现nil错误--〉

var chatPartnerId: String {
        return isFromCurrentUser ? toID! : fromID! // where I get the error
    }

我不知道我到底做错了什么

以下是课程设置:

struct Message: MessageType {
  let id: String?
    
  var messageId: String {
    return id ?? UUID().uuidString
  }
    
    var content: String?
    var toID: String?
    var fromID: String?
    var isFromCurrentUser = Bool()
    
    var chatPartnerId: String {
        return isFromCurrentUser ? toID! : fromID!
    }
    
  let sentDate: Date
  let sender: SenderType
  var image: UIImage?
  var downloadURL: URL?
    
  var kind: MessageKind {
    if let image = image {
      let mediaItem = ImageMediaItem(image: image)
      return .photo(mediaItem)
    } else {
        return .text(content ?? "")
    }
  }

    init(user: User, content: String, fromID: String, toID: String) {
    sender = Sender(senderId: user.uid!, displayName: user.name!)
    self.content = content
        self.fromID = fromID
        self.toID = toID
    sentDate = Date()
    id = nil
  }

  init(user: User, image: UIImage) {
    sender = Sender(senderId: user.uid!, displayName: user.name!)
    self.image = image
    content = ""
      fromID = ""
      toID = ""
    sentDate = Date()
    id = nil
  }

  init?(document: QueryDocumentSnapshot) {
    let data = document.data()
    guard
      let sentDate = data["created"] as? Timestamp,
      let senderId = data["senderId"] as? String,
      let fromID = data["fromID"] as? String,
      let toID = data["toID"] as? String,
      let senderName = data["senderName"] as? String
    else {
      return nil
    }

    id = document.documentID
    self.sentDate = sentDate.dateValue()
    sender = Sender(senderId: senderId, displayName: senderName)
      self.isFromCurrentUser = fromID == Auth.auth().currentUser?.uid
    

    if let content = data["content"] as? String {
      self.content = content
      downloadURL = nil
    } else if let urlString = data["url"] as? String, let url = URL(string: urlString) {
      downloadURL = url
      content = ""
    } else {
      return nil
    }
      
      
  }
}

// MARK: - DatabaseRepresentation
extension Message: DatabaseRepresentation {
  var representation: [String: Any] {
    var rep: [String: Any] = [
      "created": sentDate,
      "senderId": sender.senderId,
      "fromID": fromID,
      "toID": toID,
      "senderName": sender.displayName
    ]

    if let url = downloadURL {
      rep["url"] = url.absoluteString
    } else {
      rep["content"] = content
    }

    return rep
  }
}

// MARK: - Comparable
extension Message: Comparable {
  static func == (lhs: Message, rhs: Message) -> Bool {
    return lhs.id == rhs.id
  }

  static func < (lhs: Message, rhs: Message) -> Bool {
    return lhs.sentDate < rhs.sentDate
  }
}
knsnq2tg

knsnq2tg1#

toIDfromID都是可选项,可能是nil。避免强制展开可选项(实际上也避免强制展开其他任何项,只有极少数例外),就像您在有问题的语句中所做的那样。
相反,您可以:
1.不要害怕返回可选的:

var chatPartnerId: String? { // <-- returns optional
    return isFromCurrentUser ? toID : fromID
}

在许多情况下,将nil作为一个条件来处理会更好,这样可以帮助您了解应用的状态。例如,nil可能意味着您应该跳过对此类消息的处理。
1.您可以返回默认的伪ID或空字符串:

var chatPartnerId: String { 
    guard let id = isFromCurrentUser ? toID : fromID else {
        return "" // <-- returns bogus ID
    }
    return id
}

1.您可以将属性更改为必填:

var toID: String // <-- not optional
    var fromID: String // <-- not optional

看看你所有的init,我发现它们都不允许这些参数是nil,所以你不需要把它们设为可选的。

相关问题