I'm trying to get a messaging app integrated with the iOS Contacts app, so that users can initiate messages via the app directly from Contacts. This was covered in WWDC 2016 session 240 but apparently some details were omitted.
Following the WWDC example, I have:
Added the activity type to the app's Info.plist
:
<key>NSUserActivityTypes</key> <array> <string>INSendMessageIntent</string> </array>
Implemented application(_:continue:restorationHandler:)
in my app delegate.
Created and donated an interaction
let activity = NSUserActivity(activityType: "com.example.message") activity.title = "Send CB Test Message" activity.expirationDate = Date.distantFuture let recipient = INPerson( /* recipient with an email address in my Contacts database */ ) let sender = INPerson( /* me */ ) let intent = INSendMessageIntent(recipients: [recipient], content: nil, groupName: nil, serviceName: "CB Test Chat", sender: sender) let response = INSendMessageIntentResponse(code: .success, userActivity: activity) let interaction = INInteraction(intent: intent, response: response) interaction.direction = .outgoing interaction.donate { (error) in print("Donated") if let error = error { print("Donate error: \(error)") } }
This sort of works. The app shows up as an option on the one recipient's card in Contacts. Tapping it in Contacts launches my app with an NSUserActivity
. That's good but it's not enough.
The WWDC session used WhatsApp as an example. WhatsApp shows up as an option on all of my contacts, even those without WhatsApp accounts. I thought maybe WhatsApp had created and donated interactions for everyone. But if I create a new contact while WhatsApp isn't running, it's immediately an option on that contact. I experimented a little, setting the recipient argument to nil or to an empty array, but that had no effect.
So what am I missing here? I'm close, maybe? But it seems like donating interactions might not be what I actually need.
Update, in response to @Mark: Clarified the use of activity
. I've tried this using response
(which uses activity
) and with a nil value for response
but neither worked.
In “Privacy,” tap “Contacts.” Next, you'll see a list of every installed app that has requested access to your contacts in the past. Beside each one, you'll see a switch that is either turned on or off. If the switch is set to “on,” the app can access your contacts.
The Contacts app comes built-in to every iPhone and iPad and can't be uninstalled. Whether you want to call, iMessage, email, or FaceTime someone, the Contacts app for iOS is your central repository for staying in touch with the people that matter most to you.
I asked about this at WWDC 2019 and was told that this kind of mass donation only works for VOIP apps, not for messaging apps. The code in this question would in theory work for VOIP-- maybe or maybe not exactly as presented. I haven't tried because I don't work on the right kind of app.
Simply use UIActivityViewController. You can instantiate it with text or any object. You can also exclude all types besides messaging if that's all you want.
let objectsToShare = [textToShare, otherObject] as [Any] let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil) //New Excluded Activities Code activityVC.excludedActivityTypes = [UIActivityType.addToReadingList] activityVC.popoverPresentationController?.sourceView = sender as? UIView present(activityVC, animated: true, completion: nil)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With