我正在为iOS开发React Native应用。
此应用必须能够打开深层链接,并且在后台打开该应用时可以正常工作。 关闭应用程序后,本机iOS代码(Objective-C)无法获取打开应用程序所用的URL。
据我了解它是如何工作的,我必须检查launchOptions的NSDictionary,以查看该应用程序是否已通过URL启动。如果存在与URL初始化相对应的密钥,则我返回true以执行以下代码
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [RCTLinkingManager application:application openURL:url options:options];
return YES;
}
必须执行此函数才能获取已打开应用程序的初始Url。这是我的应用程序didFinishWithLaunchOptions的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([launchOptions objectForKey:UIApplicationLaunchOptionsURLKey]) {
return true;
}
}
答案 0 :(得分:1)
虽然肯定不是一个答案,但我已经(通过可怕的方法)通过更改(或者如果您还没有的话,请添加)来解决此问题(至少直到找到规范的解决方案为止) - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
中的AppDelegate.m
到:
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
NSURL *url = [userActivity webpageURL];
BOOL result = [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
if([userActivity webpageURL]){
#if DEBUG
float seconds = 3.5;
#else
float seconds = 1.5;
#endif
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(seconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSURL *newUrl = [NSURL URLWithString:[NSString stringWithFormat:@"MYAPPSCHEME:/%@", url.path]];
[[UIApplication sharedApplication] openURL:newUrl options:@{} completionHandler:nil];
});
}
return result;
}
它基本上检查是否有导致启动的URL,并在“问题解决”之后调用对应用程序的打开URL调用(因为在调试模式下,加载需要更长的时间,我已更改为3.5秒处理得很好)。相应地更改seconds
,当然还要更改MYAPPSCHEME
。是的,在MYAPPSCHEME:
后有一个单斜杠(/),而不是两倍,因为url.path
似乎已经有一个斜杠。用我的应用方案替换http[s]
的原因是由于某种原因,如果我离开http[s]://
,它会启动Safari而不是处理深层链接(在应用为已经运行并已处理网址)。我的应用程序使用常规http链接处理自定义方案的方式相同,因此效果很好,但是请确保对其进行相应设置以使其正常工作。
进行上述更改并重新编译后(不要忘记您在Objective-C部分,而不是JS / React Native),它可以正常工作。我希望看到一个实际的解决方案,而不是棘手的解决方法,但是在此之前,这对我来说已经解决了。
答案 1 :(得分:0)
对讲机不为我处理深层链接的核心问题是,react-native-intercom
不会通过didFinishLaunchingWithOptions
将初始URL传递给应用程序,如果它是从后台打开的。
相反,react-native-intercom
在应用程序启动后立即调用openURL
方法,并且应用程序的react-native
部分错过了此事件。
解决方案是在openURL
方法中创建一个新线程。锁定它以停止执行,然后在React应用程序向本机代码发出信号,表明它已准备好处理深层链接时,将其解锁。该修复程序有些复杂,因此我创建了一个单独的存储库,描述了问题和解决方案。
核心思想可以用代码描述为:
dispatch_queue_t queue = dispatch_queue_create("<yourAppName>.openUrlQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
while (!DeepLink.canHandleDeepLinks) {
[DeepLink.canHandleDeepLinksLock wait];
}
[DeepLink.canHandleDeepLinksLock unlock];
dispatch_async(dispatch_get_main_queue(), ^{
// This method call will trigger the Linking event with URL to be dispatched to your 'javascript' code
[RCTLinkingManager application:application openURL:url options:options];
});
});
我已经创建了repository来解决此问题。去,看看吧。