From 35b6f866f18f8c7e2085b44005aca3e63809c8d2 Mon Sep 17 00:00:00 2001 From: Eric Lewis Date: Tue, 19 Feb 2019 22:05:33 -0800 Subject: [PATCH] helpful error on canOpenURL for missing scheme (#23535) Summary: iOS 9 introduced a whitelist for schemes that apps are allowed to open / check against, the current behavior of React Native is to simple return `NO` when a scheme is missing from that whitelist. It would be more helpful to throw an error with a suggested fix for the problem: ``` Unable to open URL: asos://checkout, add asos to LSApplicationQueriesSchemes in Info.plist. ``` [iOS] [Changed] - canOpenURL throws when custom scheme isn't in LSApplicationQueriesSchemes. Pull Request resolved: https://github.com/facebook/react-native/pull/23535 Differential Revision: D14143005 Pulled By: cpojer fbshipit-source-id: 4ead5f073690e627b4a4bbe3fa5a6cb5af46b589 --- Libraries/LinkingIOS/RCTLinkingManager.m | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Libraries/LinkingIOS/RCTLinkingManager.m b/Libraries/LinkingIOS/RCTLinkingManager.m index 768f47edb063b4..47ac322f63ad6a 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.m +++ b/Libraries/LinkingIOS/RCTLinkingManager.m @@ -106,13 +106,23 @@ - (void)handleOpenURLNotification:(NSNotification *)notification return; } - // TODO: on iOS9 this will fail if URL isn't included in the plist - // we should probably check for that and reject in that case instead of - // simply resolving with NO - // This can be expensive, so we deliberately don't call on main thread BOOL canOpen = [RCTSharedApplication() canOpenURL:URL]; - resolve(@(canOpen)); + + NSString *scheme = [URL scheme]; + + // On iOS 9 and above canOpenURL returns NO without a helpful error. + // Check if a custom scheme is being used, and if it exists in LSApplicationQueriesSchemes + if (![[scheme lowercaseString] hasPrefix:@"http"] && ![[scheme lowercaseString] hasPrefix:@"https"]) { + NSArray *querySchemes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"LSApplicationQueriesSchemes"]; + if (querySchemes != nil && ([querySchemes containsObject:scheme] || [querySchemes containsObject:[scheme lowercaseString]])) { + resolve(@(canOpen)); + } else { + reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@. Add %@ to LSApplicationQueriesSchemes in your Info.plist.", URL, scheme], nil); + } + } else { + resolve(@(canOpen)); + } } RCT_EXPORT_METHOD(getInitialURL:(RCTPromiseResolveBlock)resolve