Не могу позвонить

Я хочу сделать телефонный звонок, и я использую для этого приведенный ниже код.

- (void)callPhoneNumber:(NSString *)phoneNumber
{
    UIWebView * webView2 = [[UIWebView alloc] init];

    // Remove non-digits from phone number
    phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

    // Make a call
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", phoneNumber]];
    [webView2 loadRequest:[NSURLRequest requestWithURL:url]];
    [self.view addSubview:webView2];
}

Перед звонком я прошу пользователя выбрать вариант с помощью UIActionSheet. Когда пользователь выбирает вариант, на основе которого я звоню.

Проблема в том, что приведенный выше код работает нормально, если я не отображаю UIActionSheet и напрямую звоню. Он выводит предупреждение с запросом подтверждения пользователя для совершения вызова. Но после отображения UIActionSheet, если я вызываю вышеуказанный метод, он не отображает предупреждение о подтверждении.

Странно то, что после этого, если я остановлю приложение из Xcode, приложение будет помещено в фоновый режим, как и должно быть. Но также я вижу это уведомление о подтверждении на главном экране устройства. Как он отображается на главном экране устройства, а не в приложении?

Кто-нибудь сталкивался с этим раньше? Что может быть причиной?

EDIT: я также попробовал код ниже. Но у него такая же проблема. Всякий раз, когда приведенный выше код веб-просмотра работает, приведенный ниже код также работает. То же самое, когда он не работает.

NSString *phoneNumberURL = [NSString  stringWithFormat:@"telprompt:%@", phoneNumber];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumberURL]];

Редактировать: добавлен код для листа действий и делегата.

Сначала я показываю предупреждение. При нажатии кнопки оповещения я отображаю лист действий. И выбрав вариант из листа действий, я звоню.

# pragma mark - ALERT VIEW DELEGATE

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(alertView.tag == MY_TAG)
    {
        // Ask to select option
        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select Option" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Option1", @"Option2", nil];
        actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
        [actionSheet showInView:self.view];   
    }
}


#pragma mark - UIActionSheet Methods

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // If not pressed cancel button.i.e. selected one of the options
    if (buttonIndex != actionSheet.cancelButtonIndex)
    {
        // Place a call
        [self callPhoneNumber:@"1234567890"];
    }
}

person Geek    schedule 08.05.2014    source источник
comment
почему вы используете веб-просмотр? почему бы и нет [[UIApplication sharedApplication] openURL:…]   -  person vikingosegundo    schedule 08.05.2014
comment
@vikingosegundo Смотрите отредактированный вопрос.   -  person Geek    schedule 09.05.2014


Ответы (5)


Если в вашем номере есть пробелы, он не будет работать, поэтому его необходимо удалить, также при использовании tel: и telprompt: он должен быть tel:// или telprompt://, обратите внимание на дополнительные //.

Я прокомментировал свой код с объяснением каждого шага, если вам нужно что-то еще, просто прокомментируйте, и я предоставлю больше.

- (void)callPhoneNumber:(NSString *)phoneNumber
{
    // If statement to check we actually have something
    if(phoneNumber) {
        // Remove any unwanted whitespace, if there is any whitespace it will not work
        phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
        // Create an NSURL instance of your number
        // Note the extra `//` in the string
        // Also note you can also use: `telprompt://` instead of `tel://`
        NSURL *urlPhoneNumber = [NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", phoneNumber]];
        // Check to make sure we can open this because iPad and iPod will not respond to phone calls
        if([[UIApplication sharedApplication] canOpenURL:urlPhoneNumber]) {
            // If we can (So if iPhone really) make the call.
            [[UIApplication sharedApplication] openURL:urlPhoneNumber];
        }
    }
}

Редактировать дополнительные примечания

Ознакомьтесь с документацией Apple по этому здесь

Я отмечу, что в документации Apple говорится, что tel: и telprompt: должны работать и нет необходимости в дополнительных //, но я обнаружил, что это все еще работает с дополнительными //. Это меня немного смущает, поскольку технически tel: и telprompt: являются URL Schemes, а дополнительные // требуются в «схемах URL». Вот хорошее руководство по ним от iPhone Development 101.

Здесь немного дополнительной информации

person Popeye    schedule 12.05.2014

Используйте OpenURL для вызова с использованием URL.

- (void)callPhoneNumber:(NSString *)phoneNumber
{
    // Remove non-digits from phone number
    phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

    // Make a call
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", phoneNumber]];
    [[UIApplication sharedApplication] openURL:url];
}
person Savitha    schedule 08.05.2014

Вместо использования UIWebView попробуйте следующее:

NSURL *phoneUrl = [NSURL URLWithString:[NSString  stringWithFormat:@"telprompt:%@",phoneNumber]];

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

Отредактировано: проверьте, вызывается ли функция телефонного звонка, установив точку останова. Если эта функция телефонного звонка не вызывается, замените функцию проверки указателя кнопок листа действий следующим образом:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0)
    {
         //Code for cancel button
    }
    if (buttonIndex == 1)
    {
       //Code for calling phone call
       [self callPhoneNumber:@"1234567890"];
    }
}

Отредактировано 2:

Теперь сформулируйте это так:

  - (void)checkCallAlert :(NSInteger)index
 {
    UIAlertView *checkCallAlert = [[UIAlertView alloc] initWithTitle:@"Check?" message:@"Are you sure you want to continue?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Call", nil];
    [checkCallAlert setTag:index];
    [checkCallAlert show];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0)
    {
         //Code for cancel button
    }
    if (buttonIndex == 1)
    {

       [self checkCallAlert : buttonIndex];


    }

}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
   if(alertView.tag == 1){
   //Destination 1 clicked
    //Code for calling phone call
       [self callPhoneNumber:@"1234567890"];
}
}

Это было бы моим окончательным решением для этого.

person Bikram Thapa    schedule 08.05.2014
comment
@Geek, если это не так, то должно быть что-то не так с UIActionSheet, не могли бы вы показать, как вы реализовали представление UIActionSheet и его метод делегата. - person Bikram Thapa; 09.05.2014
comment
@Geek, посмотри мой отредактированный ответ 2: Я думаю, это определенно решит эту проблему. - person Bikram Thapa; 12.05.2014
comment
@Geek Извините за сбой, теперь он последний. Эта реализация alertviewdelegate должна работать. - person Bikram Thapa; 12.05.2014

Попробуйте использовать следующее вместо [self callPhoneNumber ... ] для вызова callPhoneNumber после завершения текущего цикла обновления:

[self performSelector:@selector(callPhoneNumber:) withObject:@"1234567890" afterDelay:0];

Также в справочном документе UIActionSheet говорится:

В iOS 4.0 и более поздних версиях листы действий не закрываются автоматически, когда приложение переходит в фоновый режим.

Поэтому вам нужно проверить applicationWillResignActive, если отображается actionSheet, и отклонить его программно.

person jamihash    schedule 12.05.2014
comment
Но приложение не в фоне. Так почему это актуально? - person Aaron Brager; 18.05.2014

Попробуйте вызвать didDismissWithButtonIndex:, чтобы UIActionSheet уже был закрыт, возможно, он что-то блокирует.

person iCaramba    schedule 18.05.2014