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.


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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.