2014-01-17 1 views
12

Документация CTCallCenter: setCallEventHandler: утверждает, что:Как получить событие вызова с помощью CTCallCenter: setCallEventHandler: это произошло во время приостановки приложения?

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

в части, касающейся этого вопроса

Когда приложение возобновляет активное состояние, он получает одно событие вызова для каждого вызова, который изменил состояние

подразумевая приложение получит событие вызова для вызова, который имел место в прошлом, в то время как приложение было приостановлено. И это возможно в соответствии с ответом на этот вопрос: How does the Navita TEM app get call log information?

Мой вопрос: если мое приложение приостановлено и происходит вызов, то когда мое приложение возобновляет активное состояние, как он может получить событие вызова для вызова что произошло?

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

Это самая простейшая вещь, которую я пробовал: 1) Создайте новый проект, используя шаблон приложения с одним представлением Xcode. 2) Добавьте приведенный ниже код didFinishLaunchingWithOptions 3) Запустите приложение 4) Задача далеко от приложения 5) Выполните вызов с другого устройства, ответа на вызов, отбой вызова с любого устройства 6) Принесите приложение обратно на передний план, таким образом возобновив активное состояние.

Код для регистрации событий вызова является:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
     self.callCenter = [[CTCallCenter alloc] init]; 
     [self.callCenter setCallEventHandler:^(CTCall *call) 
     { 
      NSLog(@"Event handler called"); 
      if ([call.callState isEqualToString: CTCallStateConnected]) 
      { 
       NSLog(@"Connected"); 
      } 
      else if ([call.callState isEqualToString: CTCallStateDialing]) 
      { 
       NSLog(@"Dialing"); 
      } 
      else if ([call.callState isEqualToString: CTCallStateDisconnected]) 
      { 
       NSLog(@"Disconnected"); 

      } else if ([call.callState isEqualToString: CTCallStateIncoming]) 
      { 
       NSLog(@"Incomming"); 
      } 
     }]; 

    return YES; 
} 

С помощью этого кода я могу получить назвать события, если приложение находится на переднем плане, когда происходит вызов. Но если я отвлекся от приложения перед выполнением вызова, то я не смогу получить событие вызова, когда мое приложение снова возобновит активное состояние, - как он заявляет, что это должно быть в документации Apple.

Другие вещи я пытался:

1) В документации говорится, что объект блок отправляется на приоритет по умолчанию глобальной очереди диспетчеризации, поэтому я попытался поместить регистрацию setCallEventHandler в dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{})

2) Вызов setCallEventHandler: в appBecameActive вместо didFinishLaunchingWithOptions

3) Добавление фоновых способности приложения - с помощью beginBackgroundTaskWithExpirationHandler и/или обновления местоположения с использованием startUpdatingLocation или startMonitoringForSignificantLocation Изменения.

4) Различные сочетания вышеуказанного.

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

Это на прошивке 7.

+0

Добавить журнал как первую строку doneFinishLaunchingWithOptions и снова запустить один из ваших неудачных тестов, он регистрируется? – Wain

+0

Да. У меня нет проблем с базовой настройкой использования обработчика - я могу получить обновления, если приложение находится на переднем плане, и, как я упоминал в 2), я также могу получить их в фоновом режиме до истечения срока действия обработчика истечения срока действия. Таким образом, он регистрируется в файле didFinishLaunchingWithOptions и вызывается. – Gruntcakes

+0

Я действительно интересовался, что обратный вызов каким-то образом заменялся, и был запущен новый сеанс, поэтому список событий был потерян ... – Wain

ответ

14

Я нашел решение, но я понятия не имею, почему это работает. Единственное, о чем я могу думать, это ошибка в GCD и/или CoreTelephony.

В принципе, я выделяю два экземпляра CTCallCenter как этот

void (^block)(CTCall*) = ^(CTCall* call) { NSLog(@"%@", call.callState); }; 

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions 
{ 
    callCenter1 = [[CTCallCenter alloc] init]; 
    callCenter1.callEventHandler = block; 

    callCenter2 = [[CTCallCenter alloc] init]; 
    callCenter2.callEventHandler = block; 

    return YES; 
} 

аналогичный код в Swift:

func block (call:CTCall!) { 
     println(call.callState) 
    } 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
     //Declare callcenter in the class like 'var callcenter = CTCallCenter()' 
     callcenter.callEventHandler = block 

     return true 
    } 

Чтобы проверить это, я сделал звонок, ответил, а затем повесил трубку, пока приложение был в фоновом режиме. Когда я запустил его, я получил 3 события вызова: входящий, подключенный, отключенный.

+2

Спасибо. Поскольку вы предоставили решение, которое работает, я дам вам щедрость, однако я хотел бы знать, есть ли/что такое «правильное» решение. Поскольку Apple заявляет о таком поведении в своей документации, вероятно, должен быть другой способ сделать это, мы надеемся, что если вышеупомянутое связано с ошибкой, то его хрупкой будет полагаться на нее. – Gruntcakes

+0

Ну, в документации четко указано, что она не является полной или окончательной. По крайней мере, когда я смотрю на него с Xcode 5. Поэтому не стоит полагаться на документацию. – creker

+0

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

3

В моем случае, я работал над приложением предприятия, не нужно быть одобрены приложения рынка от Apple - так что если вы разрабатываете приложение предприятия это решение для вас.

Также выбранный ответ не Работает, когда приложение является фоном.

Решение простое, в основном вам просто нужно добавить (скачивает VOIP & фона) 2 возможности на вкладке Возможности:

  • Ваша цель проекта -> Возможности -> Режимы фона -> знак Передача голоса по IP & Фоновая выборка

enter image description here

Теперь ваше приложение регистрируется в IOS каркасных звонков «делегат», так что ОП раствор кода надреза:

[self.callCenter setCallEventHandler:^(CTCall *call) 
    { 
     NSLog(@"Event handler called"); 
     if ([call.callState isEqualToString: CTCallStateConnected]) 
     { 
      NSLog(@"Connected"); 
     } 
     else if ([call.callState isEqualToString: CTCallStateDialing]) 
     { 
      NSLog(@"Dialing"); 
     } 
     else if ([call.callState isEqualToString: CTCallStateDisconnected]) 
     { 
      NSLog(@"Disconnected"); 

     } else if ([call.callState isEqualToString: CTCallStateIncoming]) 
     { 
      NSLog(@"Incomming"); 
     } 
    }]; 

бы демонстративно работать, и вы будете получать уведомления, даже если приложение работает в фоновом режиме.

+0

Это не простое решение. Вы не можете просто добавить функцию voip - Apple отвергнет ее из магазина приложений, если у нее не будет веской причины использовать voip, т. Е. Это приложение, которое предоставляет пользователю функции voip. Просто добавив voip, как это, ваше приложение будет отклонено. – Gruntcakes

+0

@Woofbeans В моем случае я работал над корпоративным приложением, которому не нужен магазин приложений Apple. Я поменяю фразу «простого решения» на соответствующую. Поскольку это решение может быть полезно, если вы разрабатываете приложение, которое не нуждается в магазине приложений Apple. – OhadM

+0

Эй, извините, ударить старую нить. Я пробовал то, что вы указали выше, но я все еще не могу заставить код работать, когда приложение находится в фоновом режиме. Я запускаю приложение, затем нажимаю кнопку «домой», затем звоню, ничего не происходит. Однако после этого момента, если я запустил приложение, я получаю информацию о вызове. Могу ли я получить информацию о вызове, пока приложение остается в фоновом режиме? – NecipAllef