【问题标题】:canOpenURL failing for system-wide URL schemes系统范围的 URL 方案的 canOpenURL 失败
【发布时间】:2015-11-13 10:48:34
【问题描述】:

我正在运行 iOS 9b5。

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

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

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

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

我的 Info.plist 中有这个:

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

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

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

【问题讨论】:

  • 您是否收到“此应用不允许查询方案”错误?
  • 没错。似乎所有方案,即使是 iOS 中包含的方案,都需要列入白名单,但添加到白名单时系统不尊重该方案。
  • 我也遇到了与 iOS 9 beta 6 完全相同的问题
  • 您是在真机上试用还是在 sim 卡中试用?

标签: ios objective-c ios9 uiapplication


【解决方案1】:

到目前为止我发现的是,如果控制台记录-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>

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

【讨论】:

  • 是的,"This app is not allowed..." 错误告诉您将方案添加到应用程序的 .plist 文件中。但是,如果错误为 "(null)",则这是 Apple 错误 (openradar.me/23022383),不应出现
【解决方案2】:

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

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

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

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

【讨论】:

  • 那是因为模拟器没有tel URL方案。如果设备上不存在 URL 方案,似乎错误会记录到控制台
  • @jfeldman 我不想问为什么它在 sim 中不起作用。许多事情在模拟器中不起作用,这就是您在设备上进行测试的原因。原始海报尚未确认他们是否在设备上进行了测试。我提供了错误,以便其他人知道它的样子。
【解决方案3】:

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

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];
}

【讨论】:

  • 这对我有用,这是正确的答案。所有开发人员都应该使用此代码。无需添加 LSApplicationQueriesSchemes。谢谢,Anooj
【解决方案4】:

由于 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];
}

【讨论】:

  • 嗨,我不确定,何时使用 URLQueryAllowedCharacterSet ?还有很多其他可用的字符集。
【解决方案5】:

在 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];
    }

我的信息.plist

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

【讨论】:

    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      试试这个:

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

      【讨论】:

        猜你喜欢
        • 2020-04-09
        • 2016-03-23
        • 2016-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-29
        相关资源
        最近更新 更多