Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Inter-App Communications in xamarin.ios and Why Openurl Freezes for 10+ Sec

DZone's Guide to

Inter-App Communications in xamarin.ios and Why Openurl Freezes for 10+ Sec

Deep links are awesome to use, but who cares when they stall your app? Find out how to get around this in Xamarin.

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

Inter-App Communications

Mobile apps are meant to communicate using multiple channels, but the most popular, recommended, and widely used is using Scheme Uri. If you have not used Scheme URI then you should consider adding them to your app, it takes less than a minute to add support to your app, and it provides you a great way to get users to your app.

Setting the Stage

One scenario that I had was App A was launching App B and querying data, App B was, in turn, looking up the request, and returning data to App A. This is a common practice and can be seen in the diagram below.

Image titleScheme URI iOS

The Investigation

The problem here was that App B was freezing for up to 10+ sec before returning the result to App A. At first, I thought that this might be because the app initialisation or the data lookup taking a long time, so I added diagnostic trace statements like below to time the operation and see where the time is spent.

public class AppDelegate
{
...

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Console.WriteLine("FinishedLaunching started: " + DateTime.Now.ToString("F"));

...

Console.WriteLine("FinishedLaunching complete: " + DateTime.Now.ToString("F"));
}

public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
Console.WriteLine("OpenUrl started: " + DateTime.Now.ToString("F"));

...


Console.WriteLine("OpenUrl complete: " + DateTime.Now.ToString("F"));
}
}

I found that my app was starting in less than 1 Sec, which is quite impressive, and I am very happy about  but the problem was in returning the data to the launching app (App A). The traces were like these:

Image title


Launch Services application launch failed – timeout waiting – Trace logs

This is telling me that App B was not able to launch App A to return back the data, which was quite surprising. I found that if you move that code to your pages/viewControllers things work fine. I thought that this was a bizarre situation, then I found this StackOverflow post, which explained the problem.

The Solution

Apparently, the iOS was having a race-condition like in trying to launch an app while the app itself was not fully launched. So the suggested solution was to add some delay or run it on another thread. Running the launch of App A on another thread would not work as it needs to be on the mainUiThread, so here is the solution I came up with:

public class AppDelegate
{
...

public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
// handle opening url and look up data

...

Task.Delay(500).ContinueWith(_ => 
{
this.InvokeOnMainThread( () => 
{
var uri = NSUrl.FromString(callbackUri);
UIApplication.SharedApplication.OpenUrl(uri);

});

});

return true;

}
}

: LaunchServices: application launch failed – timeout waiting for launch.

This works like a charm :). First, we got rid of the launch service error (see below). Second, App B is now returning the results to App A in less than 3 sec. If App B is in the background then it would return the data in less than 1 sec. Otherwise, it would take up to 3 sec to return the data. Yayyy!

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:
xamarin ,mobile ,ios ,android

Published at DZone with permission of Has Altaiar. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}