1

I am designing a chat application in iOS swift. I use a UICollectionView to display the chat messages. The problem I have has to do with sending messages. Currently I use the following code:

func handleSend() {
    if (inputTextField.text!.characters.count > 0) {
    sendButton.enabled = false
    let text = inputTextField.text
    inputTextField.text = ""
    print(inputTextField.text)

    let myUrl = NSURL(string: "http://****")
    let request = NSMutableURLRequest(URL:myUrl!);
    request.HTTPMethod = "POST";
    request.timeoutInterval = 10
    request.HTTPShouldHandleCookies=false

    if let user_id = NSUserDefaults.standardUserDefaults().stringForKey("userId") {
        let sender = user_id
        let chatID = self.chatId
        var postString = "sender=" + sender + "&chatID="
        postString = postString + chatID! + "&text=" + text!
        print(postString)
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            do {
                if (data != nil) {
                    do {
                        do {
                            let jsonArray = try NSJSONSerialization.JSONObjectWithData(data_fixed!, options:[])

                            if let errorToken = jsonArray["error"] as! Bool? {
                                if  !errorToken  {
                                    self.sendButton.enabled = true
                                    let newMessage = Message()
                                    newMessage.chat_ID = chatID

                                    self.chat_m.append(newMessage)
                                    let item = self.chat_m.count-1

                                    dispatch_async(dispatch_get_main_queue(), {
                                        let insertionAtIndexPath = NSIndexPath(forItem: item, inSection: 0)

                                            self.collectionView!.insertItemsAtIndexPaths([insertionAtIndexPath])

                                            self.collectionView!.scrollToItemAtIndexPath(insertionAtIndexPath, atScrollPosition: .Bottom, animated: true)


                                        self.inputTextField.text = nil


                                }
                                else {
                                    self.sendButton.enabled = tru
                                }
                            }
                            else {
                                self.sendButton.enabled = true
                            }
  }
          }
           task.resume()
    }
    }
    }

Now the problem with this is that the user must wait until his current message is sent until he can send the next one. What I would prefer to do is to immediately insert the message into the collectionView after the user hits the send button, and then upload it in the background. I could of course store an array of messages to be uploaded and then upload that every couple seconds, but I think that's a bit of a dirty solution; I would like to use a queue, such that the messages get pushed onto the queue and uploaded in the background, and as soon as one message gets uploaded, the next one uploads after it; but I'm not sure how to achieve this.

Alk
  • 5,215
  • 8
  • 47
  • 116
  • 1
    One way would be to wrap the `NSURLSessionTask` in an custom asynchronous subclass of `NSOperation`. (See http://stackoverflow.com/a/32322851/1271826 for example of how to do that with download ... the idea is the same for upload.) Then just add these upload operations to `NSOperationQueue` whose `maxConcurrentOperationCount` is equal to `1`. – Rob Sep 01 '16 at 19:07
  • http://stackoverflow.com/a/39203067/3400991 this may help – Shobhakar Tiwari Sep 01 '16 at 19:31

0 Answers0