无法避免字符串打印语句的optional()?

时间:2017-09-20 03:53:51

标签: swift

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

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()
        }

然后转到新控制器(将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()

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

1 个答案:

答案 0 :(得分:1)

事实证明,其原因源自loadMessageData的函数。使用String(describing: results.string(forColumn:)需要展开{​​{1}}。此问题在整个应用程序的整个数据修改过程中传播,并导致我看到的打印语句的results.String(forColumn:)!包装。