INSendMessageIntent suggestions always show "1 person", even for multiple recipients

I'm trying to donate an INSendMessageIntent for multiple recipients in a group. No matter what I do, the share sheet shows "1 Person" and a maximum of 1 profile image.

How can I get it to show the correct number of people, and all of the profile images I set?

Example screenshot: i.stack.imgur.com/VRf5i.png
Sample code follows.
  • Click "Donate Group Without Images" => share sheet suggestion shows 3 bubbles but says "1 Person"

  • Click "Donate Group With Individual Images" => share sheet suggestion shows the first person's image (the letter A), not all 3 images, and still says "1 Person"

  • Click "Donate Group with One Image" (...using undocumented setImage:forParameterNamed:...) => share sheet suggestion correctly shows the single group image, but still says "1 Person".


Steps to reproduce:
  1. Create a new SwiftUI app with the below code as ContentView.swift.

  2. Edit Info.plist to include NSUserActivityTypes: ["INSendMessageIntent"]

  3. Add a share extension target; edit the target to add INSendMessageIntent under Supported Intents.

  4. Run the app on a device. (Share sheet suggestions don't seem to work in the simulator.)

  5. Try clicking the buttons to donate intents, and then clicking the share button to activate the share sheet.


ContentView.swift:
Code Block
import SwiftUI
import Intents
import IntentsUI
struct ActivityVC: UIViewControllerRepresentable {
  func makeUIViewController(context: Context) -> some UIViewController {
    return UIActivityViewController(activityItems: [UIImage(systemName: "photo")!], applicationActivities: nil)
  }
  func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
}
struct ContentView: View {
  @State var showActivityVC = false
   
  var body: some View {
    VStack(spacing: 24) {
      Button("Donate Single Without Image") {
        let person1 = INPerson(personHandle: INPersonHandle(value: "Aid", type: .unknown), nameComponents: nil, displayName: "A", image: nil, contactIdentifier: nil, customIdentifier: "Aid")
         
        let intent = INSendMessageIntent(recipients: [person1], outgoingMessageType: .outgoingMessageText, content: nil, speakableGroupName: INSpeakableString(spokenPhrase: "Single"), conversationIdentifier: "1", serviceName: nil, sender: nil, attachments: nil)
         
        INInteraction(intent: intent, response: nil).donate { (err) in
          print("Donated single without image: \(err as Any)")
        }
      }
      Button("Donate Group Without Images") {
        let person1 = INPerson(personHandle: INPersonHandle(value: "Aid", type: .unknown), nameComponents: nil, displayName: "A", image: nil, contactIdentifier: nil, customIdentifier: "Aid")
        let person2 = INPerson(personHandle: INPersonHandle(value: "Bid", type: .unknown), nameComponents: nil, displayName: "B", image: nil, contactIdentifier: nil, customIdentifier: "Bid")
        let person3 = INPerson(personHandle: INPersonHandle(value: "Cid", type: .unknown), nameComponents: nil, displayName: "B", image: nil, contactIdentifier: nil, customIdentifier: "Cid")
         
        let intent = INSendMessageIntent(recipients: [person1, person2, person3], outgoingMessageType: .outgoingMessageText, content: nil, speakableGroupName: INSpeakableString(spokenPhrase: "NoImages"), conversationIdentifier: "2", serviceName: nil, sender: nil, attachments: nil)
         
        INInteraction(intent: intent, response: nil).donate { (err) in
          print("Donated group without images: \(err as Any)")
        }
      }
      Button("Donate Group With Individual Images") {
        let person1 = INPerson(personHandle: INPersonHandle(value: "Aid", type: .unknown), nameComponents: nil, displayName: "A", image: INImage(uiImage: UIImage(systemName: "a.circle.fill")!), contactIdentifier: nil, customIdentifier: "Aid")
        let person2 = INPerson(personHandle: INPersonHandle(value: "Bid", type: .unknown), nameComponents: nil, displayName: "B", image: INImage(uiImage: UIImage(systemName: "b.circle.fill")!), contactIdentifier: nil, customIdentifier: "Bid")
        let person3 = INPerson(personHandle: INPersonHandle(value: "Cid", type: .unknown), nameComponents: nil, displayName: "C", image: INImage(uiImage: UIImage(systemName: "c.circle.fill")!), contactIdentifier: nil, customIdentifier: "Cid")
         
        let intent = INSendMessageIntent(recipients: [person1, person2, person3], outgoingMessageType: .outgoingMessageText, content: nil, speakableGroupName: INSpeakableString(spokenPhrase: "SeparateImages"), conversationIdentifier: "3", serviceName: nil, sender: nil, attachments: nil)
         
        INInteraction(intent: intent, response: nil).donate { (err) in
          print("Donated group with individual images: \(err as Any)")
        }
      }
      Button("Donate Group with One Image") {
        let person1 = INPerson(personHandle: INPersonHandle(value: "Aid", type: .unknown), nameComponents: nil, displayName: "A", image: nil, contactIdentifier: nil, customIdentifier: "Aid")
        let person2 = INPerson(personHandle: INPersonHandle(value: "Bid", type: .unknown), nameComponents: nil, displayName: "B", image: nil, contactIdentifier: nil, customIdentifier: "Bid")
         
        let intent = INSendMessageIntent(recipients: [person1, person2], outgoingMessageType: .outgoingMessageText, content: nil, speakableGroupName: INSpeakableString(spokenPhrase: "OneGroupImage"), conversationIdentifier: "4", serviceName: nil, sender: nil, attachments: nil)
         
        // This "forParameterNamed: \.speakableGroupName" is totally undocumented, but following the example from: https://developer.apple.com/documentation/foundation/app_extension_support/supporting_suggestions_in_your_app_s_share_extension
        intent.setImage(INImage(uiImage: UIImage(systemName: "g.circle.fill")!), forParameterNamed: \.speakableGroupName)
         
        INInteraction(intent: intent, response: nil).donate { (err) in
          print("Donated group with one image: \(err as Any)")
        }
      }
      Button("Delete All") {
        INInteraction.deleteAll { (err) in
          print("Deleted: \(err as Any)")
        }
      }
       
      Spacer().frame(height: 24)
       
      Button(action: { showActivityVC = true }) {
        Image(systemName: "square.and.arrow.up")
      }
    }
    .sheet(isPresented: $showActivityVC) {
      ActivityVC()
    }
  }
}
struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

I also noticed that if you set speakableGroupName: nil in the "Donate Group With Individual Images" section, it actually says 0 People despite also listing >2 people's names. Screenshot: i.stack.imgur.com/uGDyh.png

Somehow, this works properly for iMessage...

I should also note that I see some log messages that look like this, but they seem harmless:
Code Block text
2021-01-26 16:15:43.083330-0600 SiriTest[53006:5155728] [Intents] -[INCache cacheableObjectForIdentifier:] Unable to find cacheable object with identifier intents-remote-image-proxy:?proxyIdentifier=C92EBC81-3F68-18E6-DF81-8818E0C80E9F.png&storageServiceIdentifier=com.apple.Intents.INImageServiceConnection in cache.

Also filed FB8982187 to track this issue.
Any updates regarding this? I'm dealing with the same issue.

An update? Hit by same issue.

hi even i copy your code to my contentView class , share sheet can not show any suggestion contact item. What am i missed?

INSendMessageIntent suggestions always show "1 person", even for multiple recipients
 
 
Q