Atualização contínua de localização em segundo plano iOS13

9

Atualmente, estou testando o modo de localização em segundo plano no iOS 13, pois desejo rastrear a localização e o movimento do usuário (usando o CMMotionManager) em segundo plano. Portanto, eu tenho minha própria classe (singleton) manipulando o rastreamento de local. Eu inicializo o CLLocationManager da seguinte maneira:

    func initializeLocationManager() -> CLLocationManager {
        let manager = locationManager ?? CLLocationManager()
        manager.delegate = self
        manager.requestAlwaysAuthorization()
        manager.allowsBackgroundLocationUpdates = true
        manager.pausesLocationUpdatesAutomatically = false
        manager.distanceFilter = kCLDistanceFilterNone
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.activityType = .other
        return manager
    }

Então inicio os seguintes serviços:

   func startLocationServices() {
        // ...
        locationManager.startUpdatingLocation()
        locationManager.startMonitoringVisits()
        locationManager.startMonitoringSignificantLocationChanges()
        // ...
    }

Além disso, implementei os métodos CLLocationManagerDelegate didChangeAuthorization (), didUpdateLocation ().

No arquivo info.plist, anexei as seguintes entradas:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>...</string>
<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array> 

No meu ViewController, chamo de startLocationServices. Atualmente, defino a autorização do aplicativo para rastrear os dados de localização como ".authorizedAlways"

As atualizações do local são interrompidas após aproximadamente 60 a 130 minutos.

Para resolver o problema, eu já adicionei a função didFinishLaunchingWithOptions, que aciona as atualizações de local novamente:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if let launchOptions = launchOptions,
        let isLocationKey = launchOptions[UIApplication.LaunchOptionsKey.location] as? Bool,
        isLocationKey {
        restartServices()

    }
    return true
} 

Quando o aplicativo é despertado usando essa função, eu consigo obter dados contínuos em alguns testes, mas às vezes o aplicativo é suspenso novamente após alguns minutos.

Por fim, também tentei um timer que reinicia o rastreamento de local a cada 5 minutos, mas isso não parece afetar a duração da atualização.

Portanto, minha pergunta é se existe uma maneira de receber continuamente as atualizações de localização em segundo plano ou se há alguma opção que esteja faltando?

Desde já, obrigado.

Editar: testei o aplicativo no iOS 12 e ele recebe atualizações contínuas em 5/5 testes. Acho que o problema está relacionado ao iOS 13.

mattll
fonte
1
Ei, você conseguiu a solução para isso?
Abhishek
2
Bem, como declarado em meu último comentário, eu poderia aumentar drasticamente a duração antes que o aplicativo seja movido para o estado suspenso, reduzindo os recursos consumidos em segundo plano. -> Eu removi a coleção de movimentos completamente do aplicativo. -> Ao mudar para o segundo plano, diminuo a precisão e aumento o distanceFilter para locais para obter menos eventos, paro algumas tarefas que estão atualizando a interface do usuário, reduzo a amostragem de outras fontes de dados, não exporto meus dados em segundo plano ou outra carga de trabalho. Então agora eu recebo cerca de 3000 minutos em segundo plano.
mattll 31/01
você pode me ajudar com algum código?
Abhishek
1
No AppDelegate.swift, implemente as funções func applicationDidEnterBackground (_ application: UIApplication) e func applicationDidEnterBackground (_ application: UIApplication). Nessas funções, acesse seu CLLocationManager e defina as propriedades distanceFilter, desejadaAccuracy de acordo. Também reduzo a amostragem do timer usado para gravar algumas informações de uso (como o status atual da bateria) e encerro um timer usado para atualizar periodicamente a exibição principal ou vice-versa quando o método applicationDidBecomeActive. Eu acho que brincar e testar é a chave.
mattll 31/01

Respostas:

1

Nada está errado com o código !! , Enfrentei o mesmo problema e, após pesquisas, descobri que

Na palestra WWDC19, a Apple anunciou duas mudanças na maneira como as permissões de localização funcionarão no iOS 13. A primeira alteração oferece aos usuários a opção de compartilhar sua localização com seu aplicativo apenas uma vez. Isso facilita a experimentação dos recursos de localização e ajuda os usuários a manter privados os dados de localização confidenciais.

A primeira mudança notável é que, mesmo quando você liga requestAlwaysAuthorization, o usuário recebe apenas as opções 'agora' e 'quando em uso' na caixa de diálogo de permissão. Se o usuário conceder a permissão 'quando estiver em uso' e você tentar procurar a localização em segundo plano, somente o usuário receberá uma caixa de diálogo para conceder a permissão em segundo plano.

Então, quando usuário concede WhenInUseUsage permissão Você receberá alwaysno CLAuthorizationStatuse Se o usuário escolher Allow Once CLAuthorizationStatusvai estar descansado para notDetermineduma vez lançamentos aplicativo novamente

Você pode verificar este artigo para obter informações detalhadas https://medium.com/q42-engineering/apple-location-permission-ios13-1e0e59002889

E aqui está o vídeo https://developer.apple.com/videos/play/wwdc2019/705/

EDITAR

Após a entrada do usuário, a permissão concedida pelo usuário O iOS mostrará ao usuário outra caixa de diálogo após alguns dias para alterar a permissão de quando em uso para sempre permitir.

Portanto, agora não há como solicitar diretamente ao usuário sempre permitir permissão instantaneamente, como antes.

insira a descrição da imagem aqui

Prashant Tukadiya
fonte
1
Isso resolveu o seu problema? Defino manualmente o nível de autorização para sempre em -> Configurações -> Privacidade -> Serviços de localização. Mas isso não resolveu o problema.
mattll
1
Mas mesmo depois de definir o sinalizador sempre permitir, o Aplicativo será encerrado em algum momento. Seu aplicativo é executado continuamente depois?
mattll
1
Obrigado pela atualização. Eu já encontrei esse pop-up e também é possível definir as notificações sempre nas configurações de privacidade do iphone, mas isso não resolve o problema acima para mim. No iOS 12, ainda não encontrei nenhum problema com o rastreamento contínuo de local, enquanto no iOS 13 o aplicativo fica suspenso após um tempo.
mattll
1
Aqui estão minhas observações depois de explorar o problema por algum tempo. Em poucas palavras: quanto menos eu faço em segundo plano, mais tempo posso gravar até a suspensão. Desabilitei a maioria das funcionalidades que foram executadas em segundo plano. Por enquanto, só rastreio a localização / algumas informações de uso e as armazeno usando os dados principais. Além disso, quando o aplicativo entra no modo de plano de fundo, altero o distanceFilter e o desejoAccuracy do gerenciador de localização. Agora, posso rastrear cerca de 3000 sem ser suspenso.
mattll 28/01
1
alguém conseguiu essa solução?
Abhishek