Since its introduction in 2011, Siri has been steadily learning more and more skills. Every year, Apple introduces changes to Siri that allow developers to use more of its power, and WWDC 2018 saw some of the most exciting updates.
Pre-WWDC 2018, to integrate with Siri, developers had to choose the type of request — known as intents — that they’d be making, and they only had a handful of intent types to choose from. If your app didn’t fall under one of those categories, then it was impossible to integrate with Siri. However, at WWDC, Apple introduced two new additions to SiriKit that made it possible to integrate Anghami into Siri: Media Intents and Custom Intents.
1. Media Intents
Media intents provide a convenient way to add media-related actions to Siri. The way they work is simple. First, an INMediaItem object is created, which is customized by a few parameters including an identifier, a title, a type, and artwork.
let container = INMediaItem(identifier: identifier, title: title, type: type, artwork: image)
In our case at Anghami, the type can be anything from a playlist, to an artist, to a song, and the identifier would be the item’s unique ID.
After that’s done, an INPlayMediaIntent object is created, which is the actual intent we want to provide to Siri.
let intent = INPlayMediaIntent(mediaItems: nil, mediaContainer: mediaContainer, playShuffled: shuffled, playbackRepeatMode: .all, resumePlayback: nil)
Finally, the intent itself is suggested to Siri, and then Apple provides a UI that allows the user to assign any custom phrase to that action.
After the user invokes the action, the following function is called in our app delegate:
- (void)application:(UIApplication *)application handleIntent:(INIntent *)intent completionHandler:(void (^)(INIntentResponse * _Nonnull))completionHandler;
Here a check is made to see if the intent is an INMediaIntent, the mediaItem is retrieved from the object, and then we can easily retrieve the music object (playlist, artist, song, etc.) related to that mediaItem and play it.
And the great thing is, this all happens in the background, so the user does not need to unlock their phone to run the action. They simply tell Siri what they want and it’s done.
2. Custom Intents
Media intents are great for playing music, but what if we want to do more with Siri? At Anghami, we also wanted to make it easy to do things including liking songs, downloading songs, checking a song’s lyrics, invoking search, etc. That’s where custom intents come in.
To create a custom intent, first the intent should be defined. This is done in an intent definition file (naturally). A new custom intent is created, and then some parameters have to be defined.
The category param has options like “Do”, “Run”, “Buy”, and more. This is used to help Siri know how to talk about this action when run by the user. Then some more apparent parameters are defined, like title and description. Finally, parameters can be added to the custom intent. These would be provided to Siri when the intent is created.
Just like the media intent, an intent object is created and then provided to Siri. This is made easy since, after defining the intent, Apple automatically generates class objects related to the new custom intent.
The drawback of custom intents, is that they can only be run in two ways, either in the app’s foreground, or in the background of a separate target. What that means is, if we want the intent to work without opening Anghami, we have to do that while not having access to a lot of helpful classes and files we have in the main Anghami app target.
The easy solution would’ve been to just make custom intents open up the Anghami app. It would just be one more step to the user, but it felt wrong to do that when we knew that a little extra work could eliminate that step.
So we made it work. Our main problem was that we wanted to communicate to the app that we wanted this certain action to be done to the currently playing song. Whether that was downloading the current song, liking it, or playing more like it didn’t matter. If we got the app to figure out we wanted something to happen now, then the hard part was done.
The way it was handled was with the help of the shared container. The shared container is basically a bucket where files/data can be saved and would be shared between the main app and all its extensions, and that included the Intents extension. So we had a way to communicate data with the app, sort of.
The other point that helped was realizing that if a user wanted to perform an action on the current song, then music is probably playing through Anghami, which means that our app is already running in the background.
So what we did was simply write the ID of the current song to a shared file, keeping it always updated, and when the intent is called, that same ID is written to a different file depending on the type of action that’s being called (download, like, play more like this, etc.). The app is then constantly checking those files, and if there’s a new ID written in either, the app makes sure the ID is consistent with the currently playing song, and then runs the action on that song. It’s not the ideal solution, but it is the best we could do given the constraints and our vision for Siri intents.
One more thing that would be interesting to mention is how we’re allowing full control over what’s shown in our Siri page. A system was built that allowed our API to send a JSON array of dictionaries, each describing a certain Siri intent. This would allow for per-user customization of what Siri intents we should display.
For example, if one of our users is heavily invested in the band LCD Soundsystem, then we could suggest a “Play LCD Soundsystem” action for that user only. These small yet significant extra steps are what give our implementation of Siri a genuine feel of care.
Working on Siri Intents was an interesting challenge. There’s a lot to like about how they’re implemented by Apple, but also a lot more to crave. If there was one thing that could be added, it’s the ability for custom intents to run code in our app in the background. It would make a lot of tasks so much simpler to do, and it’s exciting to think about what developers would be able to create if given that power.
But for now, we’re proud of what we were able to provide to the user regardless of all the constraints. And as always, we’re psyched about what we’re going to be able to provide next.
At Anghami, we’ll always hiring. Join our team! https://anghami.com/careers/