2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

iOSアプリで位置情報取得からのバックグラウンド処理をしたときの話

Posted at

これは2014年頃、Swiftが発表される直前の話。
バックグラウンドになってもどうにか処理をつづけられないかという依頼があって、いろいろためしてみたメモ。
知っての通りiOSにはバックグラウンドに厳しい制約があり基本無理だがいくつか方法はあった

  • BackgroundFetch(Background App Refresh Tasks)をつかう
    iOSが任意のタイミングでアプリの処理を30秒だけ実行してくれる。
    iOS7からだったので却下した

  • VoIPアプリになる
    VoIPアプリではないので却下

  • 位置情報をバックグラウンドで取得
    他アプリでも採用されていた方法だったのでこれをやってみた

いまはBackground ProcessingやBackgroundNotificationの選択肢もあるが当時はなかったので除外

位置情報取得

CoreLocation.frameworkの追加、CapabilityからBackground Modesを追加してLocation updatesにチェックをいれておく
当時はObjective-cで書いていたが、今Objective-cを残してもしょうがないのでSwiftで記載する

    var locationManager: CLLocationManager = {
        var locationManager = CLLocationManager()
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
        locationManager.distanceFilter = 1
        return locationManager
    } ()

allowsBackgroundLocationUpdatesをtrueにしておくとバックグラウンドで受信できる

    func startLocation() {
        locationManager.startMonitoringSignificantLocationChanges() // 大幅に位置が変更した時のみ位置情報を取得する
    }

startMonitoringSignificantLocationChangesを使うと位置情報が大きく動いたときだけupdateされる


extension AppDelegate: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let status = UIApplication.shared.applicationState
        if status != .background {
            return
        }
        NSLog("test application update location")
        task.execute()
    }
}

位置情報の変更を検知したらバックグラウンドタスクを実行、今回はバックグラウンドで動いていることがわかりやすいようにタスクの実行をバックグラウンドでのみ行う。

class BackgroundTask {
    private var loopCount = 0
    private var isExecuting = false
    private let PrefKey = "countValue"
    
    func execute() {
        if isExecuting { return }
        DispatchQueue.global().async {
            self.isExecuting = true
            self.loopCount = UserDefaults.standard.integer(forKey: self.PrefKey)
            while(true) {
                NSLog("test application background task %d", self.loopCount)
                sleep(1)
                self.loopCount = self.loopCount + 1
                UserDefaults.standard.setValue(self.loopCount, forKey: self.PrefKey)
            }
        }
    }
}

検証用のバックグラウンドタスク、ただ1秒おきにログを表示するだけ

結果

検証はシミュレータのLocationからFree Driveをつかって行った

2020-12-06 21:28:29.373625+0900 LaunchLocationInBackground[2189:105006] test application enter foreground
2020-12-06 21:28:32.634231+0900 LaunchLocationInBackground[2189:105006] test application enter background
2020-12-06 21:28:38.703424+0900 LaunchLocationInBackground[2189:105006] test application update location
2020-12-06 21:28:38.710385+0900 LaunchLocationInBackground[2189:105264] test application background task 0
2020-12-06 21:28:39.759649+0900 LaunchLocationInBackground[2189:105264] test application background task 1
2020-12-06 21:28:40.821763+0900 LaunchLocationInBackground[2189:105264] test application background task 2
2020-12-06 21:28:41.858983+0900 LaunchLocationInBackground[2189:105264] test application background task 3
2020-12-06 21:28:42.959856+0900 LaunchLocationInBackground[2189:105264] test application background task 4
2020-12-06 21:28:43.967623+0900 LaunchLocationInBackground[2189:105264] test application background task 5
2020-12-06 21:28:45.003097+0900 LaunchLocationInBackground[2189:105264] test application background task 6
2020-12-06 21:28:46.037451+0900 LaunchLocationInBackground[2189:105264] test application background task 7
2020-12-06 21:28:47.138904+0900 LaunchLocationInBackground[2189:105264] test application background task 8
2020-12-06 21:28:48.235930+0900 LaunchLocationInBackground[2189:105264] test application background task 9
2020-12-06 21:28:49.258731+0900 LaunchLocationInBackground[2189:105264] test application background task 10
2020-12-06 21:29:32.255424+0900 LaunchLocationInBackground[2189:105006] test application update location
2020-12-06 21:29:32.255519+0900 LaunchLocationInBackground[2189:105264] test application background task 11
2020-12-06 21:29:33.323138+0900 LaunchLocationInBackground[2189:105264] test application background task 12
2020-12-06 21:29:34.425526+0900 LaunchLocationInBackground[2189:105264] test application background task 13
2020-12-06 21:29:35.434688+0900 LaunchLocationInBackground[2189:105264] test application background task 14
2020-12-06 21:29:36.526842+0900 LaunchLocationInBackground[2189:105264] test application background task 15
2020-12-06 21:29:37.535671+0900 LaunchLocationInBackground[2189:105264] test application background task 16
2020-12-06 21:29:38.622164+0900 LaunchLocationInBackground[2189:105264] test application background task 17
2020-12-06 21:29:39.658490+0900 LaunchLocationInBackground[2189:105264] test application background task 18
2020-12-06 21:29:39.698484+0900 LaunchLocationInBackground[2189:105006] test application update location
2020-12-06 21:29:40.672103+0900 LaunchLocationInBackground[2189:105264] test application background task 19
2020-12-06 21:29:41.681671+0900 LaunchLocationInBackground[2189:105264] test application background task 20
2020-12-06 21:29:42.747317+0900 LaunchLocationInBackground[2189:105264] test application background task 21
2020-12-06 21:29:43.818607+0900 LaunchLocationInBackground[2189:105264] test application background task 22
2020-12-06 21:29:44.830959+0900 LaunchLocationInBackground[2189:105264] test application background task 23
2020-12-06 21:29:45.855771+0900 LaunchLocationInBackground[2189:105264] test application background task 24
2020-12-06 21:29:46.954273+0900 LaunchLocationInBackground[2189:105264] test application background task 25
2020-12-06 21:29:48.055699+0900 LaunchLocationInBackground[2189:105264] test application background task 26
2020-12-06 21:29:49.065966+0900 LaunchLocationInBackground[2189:105264] test application background task 27
2020-12-06 21:29:50.097980+0900 LaunchLocationInBackground[2189:105264] test application background task 28

application enter backgroundでバックグラウンドに突入してから、application update locationでアプリが起動し、バックグラウンドタスクが実行されている。
また、バックグラウンド生存期間が終了したあとも位置情報の更新によって続きから実行されている。
昔試したときはバックグラウンドでの実行時間は3分あったきがするのだが短くなったのだろうか

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?