In Xcode 11.4/iOS 13.4 I'm finding that NSUserActivity doesn't always respond to setSuggestedInvocationPhrase

262 views Asked by At

I have a project that used to successfully create and update NSUserActivity objects to provide Siri shortcuts and Handoff. I returned to this code for the first time in a while today and was a little surprised to find that if I have a debug build on a device and I run it from the Springboard it crashes with an unrecognized selector message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSUserActivity setSuggestedInvocationPhrase:]: unrecognized selector sent to instance 0x280083580'

This exact same binary is fine, when I run it attached to the debugger. I'm at a fair loss to see what the issue is. I created a dead simple test app and it exhibits the same behavior. Here's a simple SwiftUI view that demonstrates the problem:

import SwiftUI  
import Intents  

struct ContentView: View {  
    var body: some View {  
        if testForSelector() {  
            return Text("You can call setSuggestedInvocationPhrase")  
        } else {  
            return Text("setSuggestedInvocationPhrase will crash if you call it.")  
        }  
    }  
}  

extension ContentView {  
    func testForSelector() -> Bool {  
        let activity = NSUserActivity(activityType: "Testing Activity")  

        return activity.responds(to: #selector(setter: INIntent.suggestedInvocationPhrase))  
    }  
}

I'd think this code should always display "You can call setSuggestedInvocationPhrase" and it does when I run it from the debugger. But if I launch the app standalone I get "setSuggestedInvocationPhrase will crash if you call it." instead.

Has anybody else seen anything like this? If so, did it start occurring after you upgraded to Xcode 11.4 and/or to iOS 13.4 on the hardware? I've been able to reproduce this now on an iPod Touch, an iPhone 11 Pro Max, and in the simulator on an iPhone 8.

At the moment I'm working around this by explicitly checking for respondsToSelector before setting the phrase, but that's not a very good solution long term.

1

There are 1 answers

0
Timothy Sanders On BEST ANSWER

I submitted a Feedback Assistant request and Apple Engineering responded to me. I hadn't explicitly linked Intents.framework in the target. It used to work without that, but it is now failing. I'm not sure why attaching the debugger pulls in Intents, but at any rate it's clear that I should explicitly link it and it fixes this problem.