40

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.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • Have you tried setting both recipient and sender to nil? – jcaron Jan 01 '18 at 00:34
  • Where are you using `activity`? Looks like you just create it at the top and do nothing with it. – Mark Dec 19 '18 at 15:07
  • @Mark Good catch, thanks. Question is updated. – Tom Harrington Dec 19 '18 at 16:43
  • 1
    Can you post a screenshot of what it looks like when you create a brand new contact (with WhatsApp not running) and WhatsApp is an option? As well as a screenshot of when you select that option and thus launch WhatsApp. I'm wondering how it can be an option if the WhatsApp handle is not yet linked on the card. – Mark Dec 19 '18 at 21:53

2 Answers2

1

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)
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
  • This isn't what I'm trying to do. The WWDC session described a way to have third party apps appear as phone or message options within the contacts app. When someone is using Contacts, a third party app would show up there. I'm not trying to share data from my app, I'm trying to make it possible for someone to initiate a message in my app from Contacts. – Tom Harrington Mar 12 '19 at 19:21
1

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.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170