SiriKit (iOS 12) Custom Intent Handler Not Being Called - ios12

I have setup a custom intent and it all seems to be working fine except that the handler is not being called. Siri responds as if everything was successful but I don't see anything in the console output and none of my breakpoints are triggering... Here is the handler...
#implementation IntentHandler
- (id)handlerForIntent:(INIntent *)intent
{
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
NSLog(#"In handlerForIntent.");
if ([intent isKindOfClass:[TriggerSceneIntent class]])
{
return [SceneIntentsHandler sharedInstance];
}
return self;
}
#end
I have breakpoints at the if statement and both return statements. None of them are being hit. I also never see "In handlerForIntent" in the console log in xCode.
I'm guessing this is something fairly simple that I missed but I'm not seeing it. Welcome any suggestions?

I faced a same problem - handler wasn't called.
Finally I've found out, that although the project supports iOS 11.4, it initially set IntentExtension target to iOS 13. And my device, which I use for testing, has 12.4.
So my advice: check your deployment target for each target.

Related

Can Xamarin UITest backdoors return a value on iOS?

I'm writing automated tests for a Xamarin Forms mobile app. Since it's difficult to directly interact with an embedded Google/Apple map, I wrote a few backdoor methods designed to get all the information the map would provide to a human. However, on iOS, the method I wrote doesn't provide a return value, despite my instructions to the contrary.
So far, I've done all manner of things, including reducing the method to nothing but a stub returning a dummy string. It still refuses to do it. Nowhere in Microsoft's documentation indicates that a value can't be returned on iOS.
[Export("GetUnits:")]
public NSString GetUnits(NSString val) // param unused
{
return new NSString("TEST"); // returns this value in the app, but it doesn't ever make it to the test harness
}
The above code should return "TEST" to the test harness, which would then be printed in my REPL after I call app.Invoke("GetUnits:", ""), which always produces
[
]
instead of
[
"TEST"
]
The method is named properly and called properly; error messages occur if I don't call it properly (e.g. wrong number of parameters, wrong method name) and test code inserted into the method executes fine, so I know it's executing. It's just not returning the value to the test harness. The equivalent Android version of this method works perfectly.
I found one person on the Xamarin forums with the same problem, but his topic hasn't been touched in two years. I've read every pertinent thing I can find on the web, all to no avail.
Edited for formatting. (Whoops.)
Here's what we're using in our own integration tests to make sure we don't break this functionality:
This line is how we're calling the backdoor:
_app.Invoke("backdoorWithString:", stringArg).ToString().ShouldEqual(stringArg);
And in the app, the backdoor we're referencing is defined in a native app, so it's hard to compare:
- (NSString *) backdoorWithString:(NSString *) value {
I would advise changing your Export to the correct casing:
[Export("getUnits:")]
Also please check that this method is in your AppDelegate.cs file.

'ChromiumWebBrowser' does not contain a definition for 'NewScreenshot'

I'm just looking into CefSharp and am confused about NewScreenshot. I've found lots of references to it as well as example code, but none of it works. I found it marked as obsolete in the 63.0 docs...
Has NewScreenshot been removed? If so, what replaces it (how can I tell that the screen has rendered)? For my purposes a blocking (non-async) method would work fine.
Update:
Searching the source for the latest version of CefSharp I find no reference to NewScreenshot.
I started with the Minimal Example that #amaitland referred to. I made a few changes, adapting it for my use. As part of that change I moved the Shutdown() call to the program's destructor.
When I ran the project I received a mystifying error about calling Shutdown() from a thread different than the thread from which Initialize() was called.
Looking through the code I saw ScreenshotAsync and, as I wasn't (knowingly) using another thread, suspected it may be involved. I looked for another way to get my SVG image and found NewScreenshot. Which of course didn't solve my problem, which was that the GC was running my destructor in a different thread (I had no idea that could happen).
At any rate, by this time I'd shucked ScreenshotAsync for NewScreenshot which is how I ended up here.
I set a breakpoint in my handler (which I haven't included as it's never called). Here's what I hope is the relevant code. I've omitted the init code but I believe it's unchanged from the example.
public static void Main()
{
private const string url = "https://www.google.com/";
browser = new ChromiumWebBrowser();
browser.Paint += OnBrowserPaint;
browser.Load(url)
Console.ReadKey();
}
In stepping through the code in the debugger, I set a breakpoint on browser.Load(url). If I examine browser.Paint, I find errors:
Here's the tooltip for DeclaringMethod:
I have no idea if this is related to my event handler not firing, but want to point it out in the event it is involved.
I appreciate your other suggestions but feel I need to find out why an event that should be firing is not.
I'll be happy to reduce and upload the project if it will help. Oh, and thanks for your help!

Autofac SingleInstance() and Xamarin Forms

To start, let me say that I have read several questions here about SingleInstance, but still cannot find a direct answer that helps me. That said, I apologize if I missed anything.
Here's my question:
I am building a Xamarin Forms app for iOS and Android. I have a single AppInitializer class in a PCL where I register all of my interface dependencies using Autofac. I then assign the Container from the builder as a static property on the app class. The problem I encounter is that while I'm registering everything with .SingleInstance(), I'm not actually getting a single instance.
Init Logic Example:
var builder = new ContainerBuilder();
builder.RegisterType<ErrorHandler>().SingleInstance().As<IErrorHandler>();
…
builder.RegisterType<MemberViewModel>().SingleInstance().As<IMemberViewModel>();
…
AppContainer.Current = builder.Build();
I am letting Autofac handle resolving interfaces in my constructors. For example:
public MemberViewModel(ISettingsViewModel settings, IErrorHandler errorHandler, …) : base(settings, errorHandler){…}
I then use said model on a page as below:
Example page usage:
public ProfilePage()
{
InitializeComponent();
var displayModel = Model.CurrentMember;
…
}
…
**public IMemberViewModel Model =>
AppContainer.Current.Resolve<IMemberViewModel>();**
In this example I set Model.CurrentMember's properties immediately before arriving on this page. I've set breakpoints and know for a fact this is happening. However, when I resolve the instance of the model, the properties on CurrentMember are null.
Am I doing something wrong here or have I encountered a bug?
-Edit-
Made it clear that I'm using Autofac.
-Edit 2-
Adding more detail.
My implementation of the IMemberViewModel class has various properties on it, including an observable object called current member. It is declared as below:
public class MemberViewModel : ViewModelBase, IMemberViewModel
{
…
(see constructor above)
…
public MemberDisplay CurrentMember =>
m_CurrentMember ?? (m_CurrentMember = new MemberDisplay())
On the implementation of IMemberViewModel I have a method that sets the various properties on CurrentMember.
The order of operations is this:
The end user taps an image for a member. This fires a command on the (theoretically) singleton instance of the IMemberViewModel implementation. This command executes an async task that awaits an async call to the API to load the data for that member. After that data is loaded and the properties set on CurrentMember, the app navigates to the profile screen. The profile screen resolves IMemberViewModel (per above).
Expected Behavior:
The properties on CurrentMember from the resolved instance of IMemberViewModel are set to the values that have just been set from the load data method. This expectation arises from assuming that there is a single instance of IMemberViewModel.
Actual Behavior:
The CurrentMember's properties are at their default values, i.e. string.Empty, 0, null, etc.
The odd thing here is that this doesn't happen to every model. I have a message model that I am resolving in the same manner on the same screen and it seems to be fine.
This issue turned out to be caused by the way we were going about initializing everything. For posterity's sake, I will give a brief breakdown of what was happening and what I did to prevent it.
Previous App Flow:
App opens & constructor is called. This calls into the initialization routine above.
User logs in.
First instance of IMemberViewModel resolved using static container.
A message pops up asking the user for Push Notifications Permissions
When this happens, the app OnSleep is called (iOS)
After the user selects an answer, OnResume is called.
OnResume calls initialization routine
New container created.
Call to load data happens on old container, new pages reference new container.
Issue arises as described above.
Correction to the flow:
First, from what I can tell the init calls do not need to be made on resume and/or start if made in the app constructor. If the app is "killed" because other apps need the memory space, a fresh version of the app will be created on next launch (see the Android Activity Lifecycle and the iOS App Lifecycle).
Second, because I'm paranoid and because it can't hurt, in the app init routine I am now checking to determine whether the container exists and whether the interface is already registered.
public static void Init(ISetup setup)
{
if (Container != null && IsModelRegistered()) return;
RegisterDependencies(setup);
…
}
private static bool IsModelRegistered()
{
return Container.IsRegistered<IMemberViewModel>();
}

QSystemTrayIcon - showMessage() doesn't show message immediately

This is the code,
void MainWindow::start() { //a slot that responds to a button press
//...
trayIcon->setVisible(true);
trayIcon->showMessage(tr("Foo"),
tr("Foo fooo foooo fooooo foooooo baaaaar"),
QSystemTrayIcon::Information,
1000);
//...
}
But I don't see the message immediately after the button is pressed - it shows up after several seconds; sometimes it even doesn't show up at all. First, I tried removing all other statements in the function. But it didn't work. I tried QApplication::processEvents(); too, but in vain. I Googled but couldn't come up with any relevant solution. Does anyone know how to find out what's the problem?
What operating system do you use? According to the showMessage documentation:
Note that display of messages are dependent on the system
configuration and user preferences, and that messages may not appear
at all. Hence, it should not be relied upon as the sole means for
providing critical information.
Under Linux it works as expected. You could try calling qApp->processEvents() after the showMessage call.

Is this the right way to handle javascript alert dialogs using WebDriver?

It seems that in the ASP.NET WebDriver API, executing the following when there is no javascript alert present results in an exception:
browser.SwitchTo().Alert();
IE and FF both throw a WebDriverException, but Chrome throws an InvalidOperationException.
So far, this is the only code that seems to work:
try
{
var alert = browser.SwitchTo().Alert();
if (alert != null)
alert.Dismiss();
}
catch (WebDriverException)
{
// alert was not present in IE or FF
}
catch (InvalidOperationException)
{
// alert was not present in Chrome
}
Is there a way to check that an alert dialog is present, without having to catch an exception?
The actual answer here is no, you must always catch an exception. The logic behind the design of the API is that you should always be aware of what browser state you expect. If you expect an alert to appear, you should be able to use switchTo() to switch to it and handle it. If you expect an alert to appear, and use switchTo() and it is not present, that is an exceptional condition, and an exception is thrown. The normal (non-exceptional) case is to not expect an alert, and thus there is no corresponding method to look for an alert not being displayed. Incidentally, this is the same logic employed by findElement(). You can argue that the wrong logic is being employed by the API designers, but that is the way the current API is implemented.
Keeping in mind your excerpt :
Is there a way to check that an alert dialog is present, without
having to catch an exception?
This exception is likely being caused by the statement below, upon trying to perform a switch when there is no alert window present :
var alert = browser.SwitchTo().Alert();
I would suggest that you try:
Start by using the getWindowHandles api method and investigate the
presence/absence of the Alert i.e another window. You can either loop through or check
using a counter.
If the Alert window is present you can use its window handle and dismiss the same.
Else (i.e If the Alert window is not present ) skip the execution of the statement below
and thus avoid the exception.
var alert = browser.SwitchTo().Alert();
More info abt moving between windows and window handle provided here

Resources