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: Create a new SwiftUI app with the below code as ContentView.swift.
Edit Info.plist to include NSUserActivityTypes: ["INSendMessageIntent"]
Add a share extension target; edit the target to add INSendMessageIntent under Supported Intents.
Run the app on a device. (Share sheet suggestions don't seem to work in the simulator.)
Try clicking the buttons to donate intents, and then clicking the share button to activate the share sheet.
ContentView.swift:
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()
}
}