Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main app is not opened on iOS 13 #67

Closed
NiklasMerz opened this issue Sep 3, 2019 · 6 comments · Fixed by #69
Closed

Main app is not opened on iOS 13 #67

NiklasMerz opened this issue Sep 3, 2019 · 6 comments · Fixed by #69
Labels

Comments

@NiklasMerz
Copy link
Collaborator

I tested my app which is perfectly working on iOS 12 on a iOS 13 beta device. The main app is not opened after sharing. If I open the app manually the handler is called and the file exists.

This is the error on the Xcode console

2019-09-03 16:24:28.710199+0200 ShareExt[456:13928] -[__NSDictionary0 universalLinksOnly]: unrecognized selector sent to instance 0x1d08f9568
2019-09-03 16:24:28.710707+0200 ShareExt[456:13928] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionary0 universalLinksOnly]: unrecognized selector sent to instance 0x1d08f9568'
*** First throw call stack:
(0x194bf3b64 0x19491c0a4 0x194af7658 0x194bf7f48 0x194bf9cec 0x198248b54 0x194bf9e90 0x194ac9ef8 0x10256eba8 0x10256f2d0 0x194fe93f0 0x1948c0610 0x1948c1184 0x19486d464 0x19486de58 0x194877340 0x194910fa4 0x194913ae0)
libc++abi.dylib: terminating with uncaught exception of type NSException

Looks like the opening of the URL does not work. The strange thing is the error with "universalLinksOnly". Does this means we must switch from a custom scheme to a Universal link. I guess the problem is somewhere in the URL open method:

- (void) openURL:(nonnull NSURL *)url {
SEL selector = NSSelectorFromString(@"openURL:options:completionHandler:");
UIResponder* responder = self;
while ((responder = [responder nextResponder]) != nil) {
NSLog(@"responder = %@", responder);
if([responder respondsToSelector:selector] == true) {
NSMethodSignature *methodSignature = [responder methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
// Arguments
NSDictionary<NSString *, id> *options = [NSDictionary dictionary];
void (^completion)(BOOL success) = ^void(BOOL success) {
NSLog(@"Completions block: %i", success);
};
[invocation setTarget: responder];
[invocation setSelector: selector];
[invocation setArgument: &url atIndex: 2];
[invocation setArgument: &options atIndex:3];
[invocation setArgument: &completion atIndex: 4];
[invocation invoke];
break;
}
}
}

@j3k0 Do you know some more about that method from the initial development? Something must have changed on iOS 13.

Does anybody else have this issue?

@NiklasMerz
Copy link
Collaborator Author

More details about the crash:

Application Specific Information:
abort() called

Last Exception Backtrace:
0   CoreFoundation                	0x194bf3b64 __exceptionPreprocess + 220
1   libobjc.A.dylib               	0x19491c0a4 objc_exception_throw + 55
2   CoreFoundation                	0x194af7658 -[NSObject+ 194136 (NSObject) doesNotRecognizeSelector:] + 139
3   CoreFoundation                	0x194bf7f48 ___forwarding___ + 1323
4   CoreFoundation                	0x194bf9cec _CF_forwarding_prep_0 + 91
5   UIKitCore                     	0x198248b54 -[UIScene openURL:options:completionHandler:] + 131
6   CoreFoundation                	0x194bf9e90 __invoking___ + 143
7   CoreFoundation                	0x194ac9ef8 -[NSInvocation invoke] + 259
8   ShareExt                      	0x102afdd00 -[ShareViewController openURL:] + 23808 (ShareViewController.m:107)
9   ShareExt                      	0x102afe830 __36-[ShareViewController didSelectPost]_block_invoke + 26672 (ShareViewController.m:173)
10  Foundation                    	0x194fe93f0 __95-[NSItemProvider _loadItemOfClass:forTypeIdentifier:options:coerceForCoding:completionHandler:]_block_invoke_2.309 + 155
11  libdispatch.dylib             	0x1948c0610 _dispatch_call_block_and_release + 23
12  libdispatch.dylib             	0x1948c1184 _dispatch_client_callout + 15
13  libdispatch.dylib             	0x19486d464 _dispatch_lane_serial_drain$VARIANT$mp + 607
14  libdispatch.dylib             	0x19486de58 _dispatch_lane_invoke$VARIANT$mp + 419
15  libdispatch.dylib             	0x194877340 _dispatch_workloop_worker_thread + 587
16  libsystem_pthread.dylib       	0x194910fa4 _pthread_wqthread + 275
17  libsystem_pthread.dylib       	0x194913ae0 start_wqthread + 7

The openURL [UIScene openURL:options:completionHandler:] is called on UIScene which seems to be new since iOS 13 beta. The property universalLinksOnly that appears to be missing is part of this new class. I can't find any other information that this for now.

@NiklasMerz
Copy link
Collaborator Author

NiklasMerz commented Sep 4, 2019

I think I found something. iOS 13 seems to expect a different options parameter here. An empty dictionary crashes on iOS 13. The problem is this requires Xcode 11. I can create a PR when I find a reliable and tested solution for our app.

//iOS 13 changed the options and will crash with the old empty options
if (@available(iOS 13.0, *)) {
   UISceneOpenExternalURLOptions * sceneOptions = [UISceneOpenExternalURLOptions alloc];
   sceneOptions.universalLinksOnly = false;
   [invocation setArgument: &sceneOptions atIndex:3];
}

@EternallLight
Copy link

I can confirm that the issue takes place. Going to investigate on this, as well. @NiklasMerz thanks for pointing out a possible solution!

@NiklasMerz
Copy link
Collaborator Author

Great. I appreciate any help for this. I think this is the solution but I need fix some other issue with Xcode 11 first. Doing this changes in a backwards compatible way did not really work at first. @available behaves strangely. @EternallLight Maybe you find the correct syntax.

@EternallLight
Copy link

I managed to get it to work using the deprecated openURL signature:

- (void) openURL:(nonnull NSURL *)url {

    SEL selector = NSSelectorFromString(@"openURL:");

    UIResponder* responder = self;
    while ((responder = [responder nextResponder]) != nil) {
        NSLog(@"responder = %@", responder);
        if([responder respondsToSelector:selector] == true) {
            NSMethodSignature *methodSignature = [responder methodSignatureForSelector:selector];
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];

            [invocation setTarget: responder];
            [invocation setSelector: selector];
            [invocation setArgument: &url atIndex: 2];

            [invocation invoke];
            break;
        }
    }
}

It's definitely not the best solution, but at least it works on iOS 13. I tried many times with openURL:options:completionHandler and it all ended app either with EXC_BAD_ACCESS or another uncaught error. For now, I'm going to use this one until a proper fixed arrives.

@NiklasMerz
Copy link
Collaborator Author

Changing the option like posted above did work for me. But this gives a warning since this is only available in iOS 13 and Xcode 11. The PR needs to be well thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants