2

When opening my ios app via an applink, as specified by associated domains feature, the AppArg is null.

The consecutive call of start() method, as described in this issue, does not occur. In my case, start() is called only once, with a null AppArg, and that's it.

The first thing a do, in the start() method, is call

Display.getInstance().getProperty("AppArg",null);

This works fine when opening the app via a custom scheme, but not when opening via an applink.

Note: I use the ios.glAppDelegateBody and ios.afterFinishLaunching build hints to handle app open via push notification. I figured this might interfere with AppArg reading so I removed those temporarily and tried again, but to no avail.

Currently, the only solution I see is to write some native code and try to get the opening url this way, but I'd very much like for the AppArg to work as it states.

I've tested on iphone 6s with ios 15.1.

Update 3:

This problem occurs due to the call of the facebook sdk in the didFinishLaunchingWithOptions which causes the method to return NO, and that prevents continueUserActivity to execute and retrieve the launch url. The offending code is this:

return [[FBSDKApplicationDelegate sharedInstance] application:application
                                didFinishLaunchingWithOptions:launchOptions];

This code gets executed if the facebook.appIdbuild hint is present in the codenameone settings.

After I removed it, things started working.

However, you won't be able to do this if you actually use facebook connect.

Update 2

I added the following snippet to the apple-app-site-association file hosted on my domain, as per the documentation here.

"activitycontinuation": {

"apps": [ <id of my app> ]

}

It didn't work still.

The same documentation also states the an associated domain entitlement like this: activitycontinuation:example.com should be added. So I added it to the ios.associatedDomains build hint, along with the applinks, looking like this:

ios.associatedDomains=applinks:mydomain.com,activitycontinuation:mydomain.com

It still didn't work. The build suceeded, but I'm not sure that codename one is actually doing something with activitycontinuation service.

So, the problem is still not solved!

Update:

So, the flow start,stop,start only happens when the app is in background and gets opened via an applink click, and both times start is called with the AppArg populated with the applink. All well in this case.

However, if the app is closed, and opepend via applink click, start is called only once and the AppArg is null. Problem!

The method shouldApplicationHandleURL is never called. I implemented it on the main app class, returning true.

I have also tried adding native code to try to get the applink, for the case when the app was previously closed. I tried to add the code below to the glAppDelegateBody build hint, but the build failed complaining that the continueUserActivity is duplicate. The code used was something like this:

- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
  restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {

    NSURL *url = userActivity.webpageURL;
    // Handle url
  
  return YES;
}

Currently, I'm running out of ideas. So, please, help. Thank you.

Adrian Ionescu
  • 441
  • 2
  • 8

3 Answers3

1

iOS uses a different mechanism for dealing with applinks than it does for custom app URL schemes, so it is likely that there is a race condition here -where start() is being called before the URL is provided to the app.

Try implementing the com.codename1.system.URLCallback interface in your main lifecycle class and implement the shouldApplicationHandleURL method. This should be called when an applink is processed.

steve hannah
  • 4,586
  • 11
  • 18
  • The method shouldApplicationHandleURL is never called. See the updated post. Thank you. – Adrian Ionescu Nov 17 '21 at 17:37
  • apparently the solution seems to be to use the launchOption UIApplicationLaunchOptionsUserActivityKey in the didFinishLaunchingWithOptions method. I have documented everything in this issue: https://github.com/codenameone/CodenameOne/issues/3529 – Adrian Ionescu Nov 18 '21 at 13:35
  • @stevehannah, For us, universal link works but only if the app was already open. The problem seems to be related to the extra stop() cycle. We see the following sequence: 1. init() 2. stop() 3. start() <-- here we see the correct URL for AppArg but then get an NPE. The stop() is called about 0.04 seconds after init() is called. The init() normally takes 4+ seconds so it's incomplete when the app gets to the start() so when start() tries to work on items not set up yet we get a NPE. No luck w/ Adrian's solution. Any suggestions on a fix? Thx! – Mike Clonts Jul 13 '23 at 20:28
0

The solution, in my case, was to remove the facebook.appId build hint from the condenameone_settings.properties. I wasn't using facebook anymore, but forgot about the build hint. After removing it, things started working.

Found about this here.

Adrian Ionescu
  • 441
  • 2
  • 8
0

By adding the following code to the ios.afterFinishLaunching build hint, the AppArg will be populated at start with the app launchUrl (if any), regardless of the fact that facebook sdk is used or not:

NSDictionary *activityDictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];
if (activityDictionary) {
    NSUserActivity *userActivity = [activityDictionary valueForKey:@"UIApplicationLaunchOptionsUserActivityKey"];
    if (userActivity != nil) {
           if ([NSUserActivityTypeBrowsingWeb isEqualToString:userActivity.activityType] && userActivity.webpageURL != nil) {
        JAVA_OBJECT launchUrlStr = fromNSString(CN1_THREAD_GET_STATE_PASS_ARG [userActivity.webpageURL absoluteString]);
        JAVA_OBJECT appArgKey = fromNSString(CN1_THREAD_GET_STATE_PASS_ARG @"AppArg");
        JAVA_OBJECT displayInstObj = com_codename1_ui_Display_getInstance__(CN1_THREAD_GET_STATE_PASS_SINGLE_ARG);
        
        com_codename1_ui_Display_setProperty___java_lang_String_java_lang_String(CN1_THREAD_GET_STATE_PASS_ARG displayInstObj, appArgKey, launchUrlStr);
        }
    }
}
Adrian Ionescu
  • 441
  • 2
  • 8