Sending multiple messages in iMessage using Swift

1.2k views Asked by At

I'm writing an app for iMessage and would like to automatically send the message when the user taps on the imessage app screen.

The message is composed of a map of an address of a location.

Originally, I had tried using the message.url to contain the maps.apple.com url, so that when the receiver taps on the received message it'll open up maps.

But that doesn't seem to work. So I've tried to send the address separately: first the image then the address. The receiver can then tap on the address and maps will open.

I have the following code:

    if let image = createImageForMessage(), let conversation = activeConversation {

        let layout = MSMessageTemplateLayout()
        layout.image = image

        let message = MSMessage()
        message.layout = layout

        //conversation.insert(message, completionHandler: nil)
        //conversation.insertText("We are at:\n" + addressLabel, completionHandler: nil)

        conversation.send(message, completionHandler: nil)
        conversation.sendText("We are at:\n" + addressLabel, completionHandler: nil)

    }

Ideally, I want it so that only the initial tap is required, but using "send" and "sendText" only sends the first "send" instruction, "sendText" is ignored.

If I used the commented out "insert" and "insertText" then both instructions are executed but I have to tap "send" to send it.

I have tried:

        conversation.insert(message, completionHandler: nil)
        conversation.sendText("We are at:\n" + addressLabel, completionHandler: nil)

But that didn't work. Only the text was sent. The image doesn't show up at all.

Does anyone know how to send both messages with just one tap?

Or, does anyone know if I can combine both messages into one?

2

There are 2 answers

3
Steve On

After looking a bit more into this it appears as though the url var on message is used on macOS but appears to be ignored otherwise. It also looks like you might be able to put some logic into a few delegate methods to open view controllers where you might be able to put urls that you could then open although I'm not sure if that would mean that everyone you sent these messages to would need to have the extension installed (I assume you'd like to avoid that requirement). An interesting site to get some additional detail from (with an example project) can be found here: https://medium.com/swift-programming/learn-how-to-build-an-imessage-app-with-swift-7b106ce9b033

All of that being said I do have a "solution" although I can't say I recommend it (I'm not a fan of solutions that use delays). This will however successfully send the message you build followed by a message containing text. It also seems to behave almost identically to what you would see if you inserted a message and then inserted text and the user clicked send. So as much as I dislike the added delay to achieve this the end result seems correct.

        conversation.send(message, completionHandler: { _ in
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0, execute: {
                conversation.sendText("http://www.google.com", completionHandler: nil)
            })
        })

I hope this helps.

3
Tim Kokesh On

From looking at the documentation for MSConversation, it looks like you can not have two pending messages at the same time.

I would try:

    conversation.insert(message, completionHandler: ^{
        conversation.sendText("We are at:\n" + addressLabel, completionHandler: nil)
    })