gpt4 book ai didi

swift - 无法避免 optional() 用于字符串打印语句?

转载 作者:可可西里 更新时间:2023-11-01 02:01:03 24 4
gpt4 key购买 nike

我有一个包含一些字符串参数的数据结构。结构如下:

struct pulledMessage{
var convoWithUserID: String
var convoWithUserName: String
}

我有一个函数,它根据特定 pulledMessage 中的值为变量赋值。由于某些更复杂、超出问题范围的原因,这些值来自 [pulledMessage] 数组。 pulledMessage 在实际函数中总是会发生变化,但为了便于说明,我将其写为常量:

var messageArray = [pulledMessage]()


func assignValues(){
messageArray.append(pulledMessage(convoWithUserID: "abc123", convoWithUserName: "Kevin"))
let convoWithUserID = messageArray[0].convoWithUserID
let convoWithUserName = messageArray[0].convoWithUserName
print(convoWithUserID) //returns optional("abc123")
print(convoWithUserName) // returns optional("Kevin")
}

我尝试添加 ! 以不同方式解包值:

messageArray[0]!.convoWithUserID

这告诉我一个错误,我无法打开非可选类型的 pulledMessage

messageArray[0].convoWithUserID!

这给了我一个错误,我无法打开非可选类型的字符串。
This stack question建议利用 if let 摆脱可选的:

if let convoWithUserIDCheck = messageArray[0].convoWithUserID{
convoWithUserID = convoWithUserIDCheck
}

这给了我一个警告,没有理由对非可选类型的字符串执行 if let。我不知道如何让它停止返回 optional() 包装的值。

更新:更复杂、更完整的代码

SQL 数据库函数:

class FMDBManager: NSObject {
static let shared: FMDBManager = FMDBManager()


let databaseFileName = "messagesBetweenUsers.sqlite"

var pathToDatabase: String!

var database: FMDatabase!

override init() {
super.init()

let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString) as String
pathToDatabase = documentsDirectory.appending("/\(databaseFileName)")
}
func loadMessageData(){//will need a struct to load the data into a struct


if openDatabase(){
let query = "select * from messages order by messageNumber asc"
do{
print(database)
let results: FMResultSet = try database.executeQuery(query, values: nil)

while results.next(){

let message = pulledMessage(convoWithUserID: String(describing: results.string(forColumn: "convoWithUserID")), convoWithUserName: String(describing: results.string(forColumn: "convoWithUserName")), messageString: String(describing: results.string(forColumn: "messageString")), senderID: String(describing: results.string(forColumn: "senderID")), timeSent: String(describing: results.string(forColumn: "timeSent")), messageNumber: Int(results.int(forColumn: "messageNumber")))
if messagesPulled == nil{
messagesPulled = [pulledMessage]()
}
messagesPulled.append(message)
print("The message that we have pulled are \(message)")
}

}
catch{
print(error.localizedDescription)
}

database.close()
}


}
}

在应用启动时运行数据填充:

    func applicationDidBecomeActive(_ application: UIApplication) {
// if FMDBManager.shared.createDatabase() {
// FMDBManager.shared.insertMessageData()
// }else{
// print("Not a chance, sonny")
// FMDBManager.shared.insertMessageData()
// }
FMDBManager.shared.loadMessageData()
}

按顺序组织 SQL 数据:

struct pulledMessage{//global struct
var convoWithUserID: String
var convoWithUserName: String
var messageString: String
var senderID: String
var timeSent: String
var messageNumber: Int
}

var messagesPulled: [pulledMessage]!

var messageConvoDictionary = [String: [pulledMessage]]()
//For the individual message convos
var fullUnorderedMessageArray = [[pulledMessage]]()
var fullOrderedMessageArray = [[pulledMessage]]()

//For the message table
var unorderedLastMessageArray = [pulledMessage]()
var orderedLastMessageArray = [pulledMessage]()




//For the table messages... FROM HERE..........................................
func organizeSQLData(messageSet: [pulledMessage]){
var i = 0
var messageUserID = String()
while i < messageSet.count{
if (messageSet[i]).convoWithUserID != messageUserID{
print("It wasn't equal")
print(messageSet[i])
messageUserID = messageSet[i].convoWithUserID
if messageConvoDictionary[messageUserID] != nil{
messageConvoDictionary[messageUserID]?.append(messageSet[i])
}else{
messageConvoDictionary[messageUserID] = []
messageConvoDictionary[messageUserID]?.append(messageSet[i])
}
i = i + 1
}else{
messageConvoDictionary[messageUserID]?.append(messageSet[i])
i = i + 1
}
}

}


func getLastMessages(messageSet: [String:[pulledMessage]]){

for (_, messages) in messageSet{
let orderedMessages = messages.sorted(by:{ $0.timeSent.compare($1.timeSent) == .orderedAscending})
let finalMessage = orderedMessages[0]
unorderedLastMessageArray.append(finalMessage)
}
print(unorderedLastMessageArray)
}

func orderLastMessage(messageSet: [pulledMessage]){
orderedLastMessageArray = messageSet.sorted(by:{ $0.timeSent.compare($1.timeSent) == .orderedDescending})
messagesListTableView.reloadData()
print("It wasn't\(orderedLastMessageArray)")
}


func getMessagesReady(){//for observer type function calls
organizeSQLData(messageSet: messagesPulled)
getLastMessages(messageSet: messageConvoDictionary)
orderLastMessage(messageSet: unorderedLastMessageArray)
//This one is for the individual full convos for if user clicks on a cell... its done last because its not required for the page to show up
orderedFullMessageConvos(messageSet: messageConvoDictionary)
let openedMessageConversation = fullOrderedMessageArray[(indexPath.row)]//not placed in its appropriate location, but it is just used to pass the correct array (actually goes in a prepareforSegue)

}
override func viewDidLoad() {
super.viewDidLoad()
getMessagesReady()
}

然后转到新 Controller (将 openedMessageConversation 传递给 messageConvo)并在单击按钮时运行此过程:

let newMessage = pulledMessage(convoWithUserID: messageConvo[0].convoWithUserID, convoWithUserName: messageConvo[0].convoWithUserName, messageString: commentInputTextfield.text!, senderID: (PFUser.current()?.objectId)!, timeSent: String(describing: Date()), messageNumber: 0)
messageConvo.append(newMessage)
let newMessageSent = PFObject(className: "UserMessages")
newMessageSent["convoWithUserID"] = newMessage.convoWithUserID
newMessageSent["convoWithUserName"] = newMessage.convoWithUserName
newMessageSent["messageString"] = newMessage.messageString
newMessageSent["senderID"] = newMessage.senderID
let acl = PFACL()
acl.getPublicWriteAccess = true
acl.getPublicReadAccess = true
acl.setWriteAccess(true, for: PFUser.current()!)
acl.setReadAccess(true, for: PFUser.current()!)
newMessageSent.acl = acl
newMessageSent.saveInBackground()

newMessageSent["convoWithUserID"]newMessageSent["convoWithUserName"]在数据库中用optional()读取。

最佳答案

原来这个原因源于loadMessageData运行的函数。 String(describing: results.string(forColumn:) 的使用需要对 results.String(forColumn:)! 进行解包。此问题在整个数据修改过程中传播整个应用程序并导致我看到的打印语句的 optional() 包装。

关于swift - 无法避免 optional() 用于字符串打印语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46313019/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com