canOpenURL не работает для общесистемных схем URL

У меня 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://" - ошибка: "(null)". Я пробовал tel:// и sms:// и не могу избежать этого предупреждения системного журнала.

Кто-нибудь знает способ определить, может ли устройство сделать телефонный звонок без срабатывания этих предупреждений?


person djibouti33    schedule 19.08.2015    source источник
comment
Вы получаете сообщение об ошибке Этому приложению не разрешено запрашивать схему?   -  person saagarjha    schedule 20.08.2015
comment
Точно. Кажется, что все схемы, даже включенные в iOS, должны быть внесены в белый список, но система не учитывает схему при добавлении в белый список.   -  person djibouti33    schedule 20.08.2015
comment
Я также получаю точно такую ​​​​же проблему с iOS 9 beta 6   -  person Abhishek    schedule 07.09.2015
comment
Вы пробовали это на реальном устройстве или это было в симе?   -  person Polar Bear    schedule 26.09.2015


Ответы (7)


Что я обнаружил до сих пор, так это то, что если консоль регистрирует -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>

Странное поведение, вывод консоли выглядит как ошибка, хотя на самом деле ее нет.

person endowzoner    schedule 09.10.2015
comment
Да, ошибка "This app is not allowed..." говорит вам добавить схему в файл .plist приложения. Однако если в сообщении об ошибке указано "(null)", это ошибка Apple (openradar.me/23022383). не появляться - person jimmyjudas; 12.02.2016

Я думаю, вам, возможно, придется попробовать это на реальном устройстве или просто попробовать еще раз. Я только что заработал на своем 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 я все еще получаю сообщение об ошибке:
LaunchServices: ОШИБКА: нет зарегистрированного обработчика схемы URL-адреса tel
-canOpenURL: сбой для URL-адреса: "tel:555-555-5555" - ошибка : "Этому приложению не разрешено запрашивать телефон схемы"

person Polar Bear    schedule 26.08.2015
comment
Это связано с тем, что в симуляторе нет схемы URL-адресов tel. Кажется, что ошибка регистрируется в консоли, если схема URL отсутствует на устройстве. - person jfeldman; 25.09.2015
comment
@jfeldman Я не хочу задавать вопрос, почему это не работает в симуляторе. Многие вещи не работают в симуляторе, поэтому вы тестируете их на устройстве. Оригинальный постер до сих пор не подтвердился, тестировался ли он на устройстве. Я предоставил ошибку, чтобы другие знали, как она выглядит. - person Polar Bear; 26.09.2015

У меня такая же ошибка на устройствах 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];
}
person Anooj VM    schedule 29.09.2015
comment
Это работает для меня, и это правильный ответ. Все разработчики должны использовать этот код. Не нужно добавлять LSApplicationQueriesSchemes. Спасибо, Анудж - person Lalit; 24.11.2015

Поскольку iOS9 не поддерживает stringByAddingPercentEscapesUsingEncoding, для очистки подсказки телефона можно использовать следующее: 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];
}
person Steve Forbes    schedule 07.02.2016
comment
Привет, я не уверен, когда использовать URLQueryAllowedCharacterSet ? Доступно множество других наборов символов. - person Hemang; 10.03.2016

В 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>
person Ricardo    schedule 18.03.2016

Попробуйте запустить это на реальном устройстве вместо симулятора. Не нужно добавлять LSApplicationQueriesSchemes для схемы tel.

person maxkonovalov    schedule 13.06.2018

Попробуй это:

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