Creating dynamic stickers for iMessage

An iMessage extension is a mechanism that allows an iOS app to surface content to users in the iMessage SMS/messaging application.

Implementing an iMessage extension is an excellent way to engage users on an app surface frequented regularly by users.

A core feature of iMessage extensions is the ability to create stickers in conversations. Stickers have pre-requisite requirements: they must be less than 500KB is size and they should optimally be one of a fixed set of dimensions:

    • Small: 300 x 300 px
    • Medium: 408 x 408 px
    • Large: 618 x 618 px

In this post we will tackle the challenge of converting an arbitrary UIImage to a MSSticker in Swift. If you would like to try an iMessage app using dynamically created stickers checkout Emojoy on the AppStore.

The first step is to find the appropriate sticker dimensions. We want to avoid scaling to a larger dimension as this introduces fuzziness and/or pixelation.

Next want to aspect fit the image to the closest smaller dimensions. This will avoid any stretching or cropping of the image. If the source image is smaller than the smallest optimal sticker size we will leave it as-is. The Message framework will handle sizing it itself. The key benefit of performing this sizing step is to ensure we meet the 500KB maximum file size requirement for a MSSticker.

The third step is to attempt to create a lossless image file for the sticker from the adjusted UIImage. If the file meets the size requirement then we are done!

If the file size is too large we have 2 options: attempt to create a sticker with a smaller dimension or use a lossy (JPEG) encoding for the sticker file. We would prefer the latter however this is not possible if the source UIImage has an alpha channel (a JPEG encoding does not support an alpha transparency channel for images).

Finally, with all this implemented within a UIImage extension we can create a MSSticker from a UIImage easily without worrying about the details.

View the complete code listing here.