Data size limit in MSMessage?

I've been trying to create an iMessage companion app that makes it easier to share data from my main app, but I'm having trouble figuring out how to approach this.


I've tried using MSConversation's

insertAttachment(URL, withAlternateFilename: String?, completionHandler: ((NSError?) -> Void)? = nil)

method to send file attachments (whose extension my app is registered to open). The message sends and receives fine, but there seems to be no way to open custom attachments from Messages in my app. These files open my app just fine if loaded in Mail, Safari, etc...


Therefore, I turned to using MSMessage and having that interact with my iMessage app. It looks like the only way to send data with an MSMessage instance is to use the url property. I used NSURLComponents and NSURLQueryItems to encode data into the message's url object. However, when the length of the value property of any one of my NSURLQueryItems exceeds a certain amount, insert(message: MSMessage) fails with the following error:

The operation couldn’t be completed. (com.apple.messages.messagesapp-error error 8.)


This happens even though the NSURLComponents object was created just fine with data of any size I tried.


So I guess this leaves me with a few questions...

1: Is this a bug? If so, ignore the next questions and I'll be happy to submit a bug report.

2: If this isn't a bug and there is indeed a size limit for URL objects sent via MSMessage, why isn't it documented?

3: If this isn't a bug, why is there a size limit for MSMessages when the same amount of data can be send as attachments?


Thanks.


EDIT: The longest length string I was able to put into a MSMessage url query item without failing upon inserting that message is 5114 characters long. Strings with 5115 or more characters seem to fail consistently.

Replies

URLs usually have a maximum length limit but it is not standardized and depends on the server/proxy/browser etc. You're right, Apple should have documented the maximum length. This sounds like a good radar to file 🙂


As a solution, we ended up using a simple backend for our extension to transfer our custom files. The extension posts the attachment to our backend and inserts the url into the MSMessage. Not the most elegant solution but it works…

Indeed, there is an upper limit on the length of the URL that you can put in there. Filing a bug to get this documented would be great. Please post the bug number here once it's filed.

I just filed 27590757 for this. Cheers!

Thank you for the confirmation. So if this is intended behavior, why can we not send data in MSMessage objects? If it's a data usage concern, why are we allowed to send simple file attachments with no data size limit? This is problematic because Messages.app doesn't let the user open file attachments in apps that register with the proper file extensions, and I was hoping the new Messages framework would eliminate the need for that, but MSMessages can only send data via very limited URLs.

I have a feeling this is just the beginning, they will probably provide a way to add attachments in a future iOS release. But for now, I think they're focusing on getting the core features right, so I guess we'll have to make do with rolling our own cloud if we need to pass huge content around...

I kinda feel like they're likely to roll CloudKit shared containers together with MSMessage to achieve this, though that's entirely speculation. For those that don't have dedicated servers currently for use, those containers mixed with ekurutepe's solution might be an adaquate workaround...?

Yes that's what I thought as well but I think users need to be logged in to iCloud to be able to use CloudKit, so that is something to consider...

I ran into the same limit. The issue I see with a "simple" backend to transfer parts of the user's message is that it evades the end-to-end encryption that users have come to expect from iMessages. Unless there is a strong reason for the limit on the URL, I would opt to increase it significantly to reduce the incentive for developers to setup a backend that might not be using proper end-to-end encryption.

The documentation appears to be updated:


The URL property must use an http, https, or file scheme. Custom app schemes are not supported. Additionally, the URL cannot be longer than 5,000 characters.

I agree, this is a serious limitation. Right now I am uploading files to a server, but this raises the problem that the recipient may receive and open the message before the file upload has completed. I could prevent that by not inserting the messsage into the conversation until the upload has completed, but waiting for that would annoy the sender. Even once the file is uploaded, there may be a download delay when the user opens the message. It would be nice if the incoming message was not presented to the user until it was ready for consumption. That is what people expect of a messaging environment.

I’m really trying to reply to all in this thread because several are discussing how to deal with the size limit of a message. I’m dealing with a use case where >95% of the messages will be < 5k and the rest will likely never exceed perhaps 20k (smaller than the message’s image, for heaven’s sake). In considering all that has been discussed here, I’m exploring ways to address this limit for that minority of cases, and have a mixture of strategy, questions, and confusion.


1. I’m inclined to use CloudKit because of convenience. I’ve not used it before, sticking to more the UIDocument side of the fence, so some of this is borne of ignorance.


2. The record type, if I’m thinking correctly, would be two simple string fields – a string holding the unique session id as the index, and the query string (which is adequate for my data). Am I conceptually missing anything?


3. It seems that all the records would need to be saved to the app extension’s public data, because in a group message context, there is no single user whose private data to use. Do I understand that correctly?


4. Given that use of public data, it seems the app’s data size and transmission limits, and thus CloudKit cost, would be those of a single user, with no allowance for multiple users. That’s awkward.


5. Given the use of public data, it seems that I’d be technically able to see every record and the query string through the CloudKit dashboard. This is absolutely not my intent or desire, but I’m at a loss for how to work around this. Thoughts? Likewise, that query string is not encrypted. What are viable options?


6. There’d be no way to delete a record, as there’s no indication when a message is deleted or is abandoned. Thus, data usage would continually increase. This would seem to affect any database solution be/c how would you know the user wasn’t gonna use that particular data any more?


7. I wouldn’t need to subscribe to record changes, since Messages provides the group with notifications of changes to the message.


8. Not sure of the implications of now requiring iCloud usage and how that affects the user’s workflow. Is sign in required even if only using the app’s public data and no private user data?



Am I missing anything? It’s frustrating to have to go this route just be/c of the size limit affecting that minority of use cases. Trying to find an adequate approach. Thoughts? Thank you.

Or possibly one limit if building an http/https url and a larger limit if just data. I can see how browsers might care about the query string, but not why Messages would care about the length of the data, within reason, seeing as any image I'd include in message.layout.image would itself be much larger than the 5k.