ios 系统范围的 URL 方案的 canOpenURL 失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32107315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:20:46  来源:igfitidea点击:

canOpenURL failing for system-wide URL schemes

iosobjective-cios9uiapplication

提问by djibouti33

I'm running iOS 9b5.

我正在运行 iOS 9b5。

In my app, if a device can make a phone call, I want to color the text blue so it looks tappable. If not, I leave it black.

在我的应用程序中,如果设备可以拨打电话,我想将文本着色为蓝色,使其看起来可点击。如果没有,我将其保留为黑色。

In order to determine the device capabilities, I use:

为了确定设备功能,我使用:

[[UIApplcation sharedApplication] canOpenURL:@"telprompt://5555555555"]  

As we all know, iOS 9 requires we whitelist any URL schemes we'll be using in our app as a privacy measure.

众所周知,iOS 9 要求我们将我们将在我们的应用程序中使用的任何 URL 方案列入白名单,以作为隐私措施。

I have this in my Info.plist:

我的 Info.plist 中有这个:

<key>LSApplicationQueriesSchemes</key>  
<array>  
  <string>telprompt</string>  
</array>  

No matter what I do, I still get canOpenURL: failed for URL: "telprompt://" - error: "(null)". I've tried tel:// and sms:// and I can't seem to avoid that syslog warning.

无论我做什么,我仍然得到 canOpenURL: failed for URL: "telprompt://" - error: "(null)"。我试过 tel:// 和 sms:// 并且我似乎无法避免那个系统日志警告。

Does anybody know of a way to detect whether or not a device can make a phone call wtihout triggering these warnings?

有没有人知道一种方法来检测设备是否可以在不触发这些警告的情况下拨打电话?

回答by endowzoner

What I discovered so far is, that if the console logs -canOpenURL: failed for URL: "xxx://" - error: "(null)", it actually works. As soon as there is any other error than null, it may not work. If the error is "This app is not allowed to query for scheme xxx", then you have to add this scheme to your app's .plist:

到目前为止我发现的是,如果控制台记录-canOpenURL: failed for URL: "xxx://" - error: "(null)",它实际上可以工作。一旦出现除 之外的任何其他错误null,它可能无法正常工作。如果错误是"This app is not allowed to query for scheme xxx",那么您必须将此方案添加到您的应用程序的 .plist 中:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>xxx</string>
</array>

Strange behavior that the console output looks like an error although there is none, indeed.

控制台输出看起来像错误的奇怪行为,尽管确实没有。

回答by Polar Bear

I think you might need to try this on an actual device, or just try it again. I just got this working on my iPhone 5, it looks like you don't even need to add it to the LSApplicationQueriesSchemes. If the app is built with Xcode 7 Beta 6 and you use canOpenURL or openURL like below it seems to work just fine on device.

我认为您可能需要在实际设备上尝试此操作,或者再试一次。我刚刚在我的 iPhone 5 上使用了这个,看起来你甚至不需要将它添加到 LSApplicationQueriesSchemes。如果应用程序是使用 Xcode 7 Beta 6 构建的,并且您使用 canOpenURL 或 openURL 如下所示,它似乎在设备上运行良好。

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel:555-555-5555"]]

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel:555-555-5555"]]

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:555-555-5555"]]

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:555-555-5555"]]

On the iOS sim I still get the error:
LaunchServices: ERROR: There is no registered handler for URL scheme tel
-canOpenURL: failed for URL: "tel:555-555-5555" - error: "This app is not allowed to query for scheme tel"

在 iOS sim 上,我仍然收到错误:
LaunchServices:错误:URL 方案没有注册处理程序 tel
-canOpenURL:URL 失败:“tel:555-555-5555” - 错误:“不允许查询此应用程序对于计划电话"

回答by Anooj VM

I got the same error in IOS9 devices. So I have used below code snippet to avoid this error.

我在 IOS9 设备中遇到了同样的错误。所以我使用了下面的代码片段来避免这个错误。

NSString *cleanedString = [[[PHONE NUMBER] componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *phoneURLString = [NSString stringWithFormat:@"telprompt:%@", escapedPhoneNumber];
NSURL *phoneURL = [NSURL URLWithString:phoneURLString];

if ([[UIApplication sharedApplication] canOpenURL:phoneURL]) {
    [[UIApplication sharedApplication] openURL:phoneURL];
}

回答by Steve Forbes

As iOS9 deprecates stringByAddingPercentEscapesUsingEncoding, the following can be used to clean the telprompt: URL.

由于 iOS9 不赞成使用 stringByAddingPercentEscapesUsingEncoding,因此可以使用以下内容来清理 telprompt: URL。

NSString *cleanedString = [[[PHONE NUMBER] componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
//NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *phoneURLString = [NSString stringWithFormat:@"telprompt:%@", escapedPhoneNumber];
NSURL *phoneURL = [NSURL URLWithString:phoneURLString];

if ([[UIApplication sharedApplication] canOpenURL:phoneURL]) {
    [[UIApplication sharedApplication] openURL:phoneURL];
}

回答by Rincha

In iOS9 I'm using this code and it works:

在 iOS9 中,我正在使用此代码并且它有效:

NSString *assistanceNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"AssistanceCallMISDN"];
    assistanceNumber= [[assistanceNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
    assistanceNumber = [assistanceNumber stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


    NSURL *phoneUrl = [NSURL URLWithString:[@"telprompt://" stringByAppendingString:assistanceNumber]];
    NSURL *phoneFallbackUrl = [NSURL URLWithString:[@"tel://" stringByAppendingString:assistanceNumber]];

    if ([UIApplication.sharedApplication canOpenURL:phoneUrl]) {
        [UIApplication.sharedApplication openURL:phoneUrl];
    } else if ([UIApplication.sharedApplication canOpenURL:phoneFallbackUrl]) {
        [UIApplication.sharedApplication openURL:phoneFallbackUrl];
    } else
    {
        [[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"No se ha podido realizar la llamada a través de la aplicación. Puede llamar usted al %@", assistanceNumber] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
        [_viewEmergency setHidden:YES];
    }

My Info.plist

我的信息.plist

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>telprompt</string>
    <string>tel</string>
</array>

回答by maxkonovalov

Try running this on a real device instead of simulator. No need to add LSApplicationQueriesSchemesfor the telscheme.

尝试在真实设备而不是模拟器上运行它。无需LSApplicationQueriesSchemestel方案添加。

回答by Jabbar

try this one:

试试这个:

NSString *phone_number = [[yourPhoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"telprompt://%@", phone_number]]];