Обнаружение состояний GSM-звонка в IOS 10 (Swift 3, Xcode 8) и уведомление из фонового состояния

TL;DR: обнаружение события завершения вызова из фона Пожалуйста, ознакомьтесь с приведенным ниже вопросом:

Возможно ли обнаружить/получить событие для состояния вызова в IOS 10 с использованием Swift из состояния фона. В более ранних версиях была CORE Telephony api, но теперь это кажется устаревшим.

Я видел CallKit Api, но он говорит, что он предназначен для вызовов на основе VOIP. Мне нужно получить состояние обычных вызовов CDMA/GSM, а не вызовов на основе VOIP, и когда вызов заканчивается, просто запускается уведомление на сервер. Мне не нужно обращаться к каким-либо точкам данных, которые могут быть проблемой конфиденциальности, просто нужно событие для завершения вызова, а затем мое приложение, которое будет фоном, запустится. Это оно. Любые указатели на то, как это сделать?

ОБНОВЛЕНИЕ: Используя CallKit Api, я могу получить состояния вызова, хотя не могу отличить VoIP и обычные вызовы GSM. Я могу работать с этим. Я также получил локальное уведомление, выполнив ниже.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        application.beginBackgroundTask(withName: "showN", expirationHandler:nil)
        return true
    }

extension AppDelegate: CXCallObserverDelegate {
       func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        if call.hasEnded == true {
            print("Disconnected")
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval:60,repeats:false)
            let identifier = "MyCallLocalNotification"
            let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
            center.add(request, withCompletionHandler: { (error) in
                if let error = error{
                    print(error)
                }
            })
            Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(AppDelegate.showN), userInfo: nil, repeats: false)
            print("Done")
        }
        if call.isOutgoing == true && call.hasConnected == false {
            print("Dialing")
        }
        if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false {
            print("Incoming")
        }
        if call.hasConnected == true && call.hasEnded == false {
            print("Connected")
        }
    }
}

и функция showN как:

func showN(){
        let identifier = "MyCallLocalNotification"
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval:1,repeats:false)
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
        center.add(request, withCompletionHandler: { (error) in
            if let error = error{
                print(error)
            }
        })

Однако (как и ожидалось) это не работает, если приложение было в фоновом режиме в течение длительного времени (более 3 минут) или когда экран заблокирован. Я чувствую, что я почти там, но что-то не хватает. Также подумайте, что это не правильный способ сделать это, или должен быть лучший (быстрый/IOS стандарт) способ сделать это. Пожалуйста, предложите. Уже потеряли 50 пунктов награды:)

Ответ 1

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

Я не могу использовать Push Kit, потому что целью является получение событий для обычных вызовов GSM, а не VoIP-звонков.

Ответ 2

"Возможно ли обнаружить/получить событие для состояния вызова в IOS 10 с использованием Swift из состояния фона"

Да.

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

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

1) Исходные файлы

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

2) Фоновые режимы

введите описание изображения здесь

Самый надежный способ выполнения вашего приложения останется в фоновом состоянии - это включить возможность конфигурации ваших проектов, которая укажет, что ваше приложение использует действующий фоновый режим. Мое приложение Sublam делает это. Это приложение для музыкальных плееров, которое улучшает музыку в iTunes, чтобы лучше звучать. Это было бы очень неприятно для пользователя, если бы они могли слушать музыку только тогда, когда приложение находилось на переднем плане. Почти держался в плену, не мог уйти или музыка остановилась. Я включил фоновый режим для сохранения моего приложения в фоновом режиме и вдали от опасного приостановленного состояния. Таким образом, мое приложение может обрабатывать ввод пользователя для изменения песни, паузы, воспроизведения или любых других действий, на которые будет реагировать приложение.

Ваше приложение должно будет соответствовать действительному фоновому режиму, чтобы он оставался в фоновом состоянии и мог реагировать на любые входящие вызовы. В противном случае методы CXCallObserverDelegate не будут выполняться вообще.


"Мне нужно получить состояние обычных вызовов CDMA/GSM, а не вызовов на основе VOIP"

Как сказал Мукунд и Раза выше - вы не можете использовать CallKit для определения этой информации. Надеюсь, это станет новой функцией CallKit в будущем. Но на данный момент эта функциональность не поддерживается.

Ответ 3

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

В этом выпуске более подробно обсуждается триггер событий: Состояние вызовов

Надеюсь, это изменится в июне, и Apple может добавить новые функции в CallKit.

С уважением,

Мукунд

Ответ 4

Ответ: БОЛЬШОЙ НЕТ, вы не можете получить информацию о данных вызова /GSM, набор вызовов связан только с VOIP.

Ответ 5

PS: Я предполагаю, что VOIP Call обрабатывается вами

Для APNS/PushKit Полезная нагрузка, которую словарь получает с вашего размещенного сервера.

Просто вы можете добавить пару "ключ-значение" isVOIPCall:true, чтобы различить.