Swiftで位置情報をバックグラウンドで取得する10のステップ – JPSM

Swiftで位置情報をバックグラウンドで取得する10のステップ

Swiftのロゴと位置情報アイコンを持ったスマートフォン画像Swift

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

また、理解しにくい説明や難しい問題に躓いても、JPSMがプログラミングの解説に特化してオリジナルにチューニングした画面右下のAIアシスタントに質問していだければ、特殊な問題でも指示に従い解決できるように作ってあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

皆さんは、スマートフォンのアプリを利用しているとき、位置情報の利用許可を求められた経験があるでしょうか?

そうした許可を出すことで、アプリはユーザーの位置情報を取得することができるのです。

しかし、一度許可を出したからと言って、アプリが前面に表示されていないとき、いわゆる「バックグラウンド」でも位置情報を取得できるのでしょうか?答えは「はい」です。

Swiftを用いたアプリ開発において、バックグラウンドでの位置情報取得は非常に役立つ機能の一つです。

この記事を読めば、Swiftでの位置情報のバックグラウンド取得の基本から、その応用方法、さらには注意点やカスタマイズの方法まで、幅広くマスターすることができます。

初心者の方から中級者の方まで、わかりやすく解説しますので、最後までお付き合いいただけると嬉しいです。

●Swiftと位置情報の取得とは

位置情報サービスは、モバイルデバイスのGPS、Wi-Fi、携帯電話の基地局などの情報を利用して、デバイスの現在位置を取得するサービスです。

Swiftでは、Core Locationというフレームワークを用いることで、これらの位置情報を取得することができます。

○Swiftの位置情報サービスの概要

Swiftにおける位置情報サービスは、主に「Core Location」というフレームワークを通して提供されています。

このフレームワークを利用することで、GPSのような位置情報のデータ源から情報を取得し、アプリ内で利用することができるようになります。

さらに、Core Locationは位置情報だけでなく、高度や方向、移動速度などの情報も提供します。

これにより、マップアプリや天気アプリ、運転サポートアプリなど、さまざまな用途で位置情報を活用することができるのです。

○バックグラウンドでの取得のメリット

バックグラウンドでの位置情報取得は、アプリが前面に表示されていない状態、つまりユーザーが他のアプリを利用しているときや、デバイスの画面がオフの状態でも、位置情報を取得し続けることができる機能です。

この機能のメリットは大きく2つあります。

1つ目は、リアルタイムでの位置情報取得が可能であること。

例えば、ナビゲーションアプリのように、現在位置を常に更新し続ける必要があるアプリにおいては、バックグラウンド取得は欠かせない機能と言えるでしょう。

2つ目は、ユーザーエクスペリエンスの向上です。ユーザーがアプリを起動するたびに位置情報の取得を待つことなく、すぐに最新の情報を提供できるため、ユーザーのストレスを軽減することができます。

●バックグラウンドでの位置情報取得の基本ステップ

Swiftを利用した位置情報の取得は、表面的には単純に思えますが、実際にはいくつかのステップを経て実現する必要があります。

特にバックグラウンドでの取得には、設定や権限の取得が欠かせません。ここでは、その基本的なステップを3つのサンプルコードを通じて解説していきます。

○サンプルコード1:位置情報サービスの許可を取る

まず、アプリが位置情報を取得するためには、ユーザーからその許可を得る必要があります。

下記のサンプルコードでは、位置情報サービスの許可を求める方法を表しています。

import CoreLocation

let locationManager = CLLocationManager()

func requestLocationPermission() {
    // 位置情報サービスの利用が許可されていない場合
    if CLLocationManager.authorizationStatus() == .notDetermined {
        // 許可を求めるダイアログを表示
        locationManager.requestWhenInUseAuthorization()
    }
}

このコードでは、CLLocationManagerを使って位置情報サービスの許可をユーザーに求めています。

requestWhenInUseAuthorizationは、アプリが前面にあるときのみ位置情報を利用する許可を求めるメソッドです。

実行結果として、アプリを起動した際に「このアプリは位置情報を使用します。許可しますか?」というダイアログが表示され、ユーザーは「許可する」または「許可しない」を選択できます。

○サンプルコード2:バックグラウンドでの取得を設定する

次に、バックグラウンドでの位置情報取得を設定する方法を見ていきましょう。

バックグラウンドでの取得を許可するには、requestAlwaysAuthorizationメソッドを使用します。

func requestBackgroundLocationPermission() {
    if CLLocationManager.authorizationStatus() == .notDetermined {
        // バックグラウンドでも位置情報を利用する許可を求める
        locationManager.requestAlwaysAuthorization()
    }
}

このメソッドを実行すると、「このアプリは常に位置情報を使用します。許可しますか?」というダイアログが表示されます。

実行結果として、ユーザーが「許可する」を選択すると、アプリはバックグラウンドでも位置情報を取得することができるようになります。

○サンプルコード3:位置情報の更新を受け取る

位置情報の許可が得られた後は、実際に位置情報の更新を受け取る設定を行います。

下記のコードは、位置情報の更新を受け取るための設定を示しています。

// 位置情報の更新を受け取るためのデリゲートを設定
locationManager.delegate = self

// 位置情報の更新を開始
locationManager.startUpdatingLocation()

このコードを実行すると、位置情報が更新されるたびに、デリゲートメソッドが呼び出されます。

具体的には、didUpdateLocationsメソッドが呼び出され、最新の位置情報が取得できます。

実行結果として、アプリが前面にあるとき、またはバックグラウンドで動作しているときでも、位置情報が更新されるたびにその情報を受け取ることができます。

●Swiftのバックグラウンド位置情報取得の応用例

Swiftでの位置情報取得は多岐にわたる用途があります。

ここでは、バックグラウンドでの位置情報取得を応用した具体的な例を3つのサンプルコードを通じて紹介します。

○サンプルコード4:バックグラウンドでの移動距離を計算する

位置情報を用いて、ユーザーが移動した距離を計算することができます。

下記のコードは、その一例として、バックグラウンドで移動距離を計算する方法を表しています。

import CoreLocation

var lastLocation: CLLocation?
var totalDistance: Double = 0.0

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let newLocation = locations.last, let previousLocation = lastLocation {
        let distance = newLocation.distance(from: previousLocation)
        totalDistance += distance
    }
    lastLocation = locations.last
}

このコードでは、didUpdateLocationsメソッド内で、前回の位置と新しい位置との間の距離を計算して、トータルの移動距離を更新しています。

実際にこのコードをアプリに実装し、移動すると、totalDistanceには移動した合計距離がメートル単位で記録されます。

○サンプルコード5:特定のエリアに入った時の通知を設定する

特定の地域や場所にユーザーが入った際に通知を行うことも可能です。

下記のコードは、指定された地域にユーザーが入ったときにローカル通知を表示する方法を表しています。

import CoreLocation
import UserNotifications

let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 35.6895, longitude: 139.6917), radius: 500, identifier: "TokyoStation")

func setupRegionMonitoring() {
    region.notifyOnEntry = true
    region.notifyOnExit = false
    locationManager.startMonitoring(for: region)
}

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
    let content = UNMutableNotificationContent()
    content.title = "東京駅に到着しました"
    content.body = "ようこそ、東京駅へ!"
    let request = UNNotificationRequest(identifier: "regionEntered", content: content, trigger: nil)
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

このコードは、東京駅の周辺にユーザーが入ると、ローカル通知を表示するものです。

このコードをアプリに実装すると、指定されたエリアに入った際に、「ようこそ、東京駅へ!」という通知が表示されます。

○サンプルコード6:バッテリー節約のための最適化手法

位置情報の取得はバッテリー消費が大きくなりやすいため、節約のための最適化が求められます。

下記のコードは、位置情報の取得精度を調整し、バッテリーの消費を抑える方法を表しています。

import CoreLocation

func optimizeBatteryUsage() {
    // 精度を100mに設定
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
    // 最小移動距離を500mに設定
    locationManager.distanceFilter = 500.0
}

このコードでは、取得する位置情報の精度を100m、最小の移動距離を500mに設定しています。

このコードをアプリに導入することで、不要な位置情報の更新を減らし、バッテリーの消費を節約することが期待できます。

●注意点と対処法

Swiftを使ってバックグラウンドで位置情報を取得する際、いくつかの問題点や考慮すべき点があります。

ここでは、特に注意が必要な2つの点、バッテリー消費とプライバシーに関する問題を中心に詳しく解説していきます。

○バッテリー消費の問題とその解決方法

位置情報の取得はスマートフォンのバッテリーを大幅に消費します。

特に、バックグラウンドでの連続的な取得は、その影響が大きくなります。

この問題を緩和するための一例として、位置情報の取得精度や取得間隔を調整する方法が考えられます。

import CoreLocation

let locationManager = CLLocationManager()
// 精度を1kmに設定
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
// 最小移動距離を500mに設定
locationManager.distanceFilter = 500.0

このコードでは、位置情報の精度を1kmに設定し、最小の移動距離を500mに設定しています。

これにより、不要な位置情報の更新を抑制し、バッテリー消費を節約することが期待できます。

このように、取得精度や間隔を適切に設定することで、アプリのバッテリー消費を抑えつつ、必要な機能を維持することができます。

○プライバシーに関する考慮点

位置情報は、ユーザーのプライバシーに関わる非常にデリケートなデータです。

アプリが位置情報を取得することに対して、ユーザーが不安を感じることもあるため、取得の際には十分な注意が必要です。

下記のコードは、ユーザーに位置情報の取得許可を求める際に、その理由を明示する方法を表しています。

import CoreLocation

let locationManager = CLLocationManager()

func requestLocationPermission() {
    locationManager.requestWhenInUseAuthorization()
    // Info.plistに「NSLocationWhenInUseUsageDescription」キーを追加して、取得理由を記述
}

このコードを実行する前に、アプリのInfo.plistファイルにNSLocationWhenInUseUsageDescriptionキーを追加し、位置情報取得の理由を明確に記述する必要があります。

例えば、「マップ上に現在地を表示するため」といった理由をユーザーに伝えることで、ユーザーの理解を得やすくなります。

●カスタマイズ方法

Swiftを使用した位置情報の取得には、様々なカスタマイズ方法が存在します。

特にバックグラウンドでの取得時に、アプリの要件に合わせたカスタマイズが必要になることが多いです。

ここでは、カスタム通知の設定や位置情報の精度調整など、Swiftでの位置情報取得をさらに便利にするためのカスタマイズ方法をいくつか紹介します。

○サンプルコード7:カスタム通知の設定

位置情報の変化や特定のエリアへの入退場時に通知を出すことは、多くのアプリで必要とされる機能です。

下記のサンプルコードでは、特定のエリアに入ったときにカスタム通知を表示しています。

import CoreLocation
import UserNotifications

let locationManager = CLLocationManager()
let notificationCenter = UNUserNotificationCenter.current()

func setupGeofenceNotification() {
    let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 35.6895, longitude: 139.6917), radius: 100.0, identifier: "Tokyo")
    region.notifyOnEntry = true
    region.notifyOnExit = false

    locationManager.startMonitoring(for: region)

    // 通知内容の設定
    let content = UNMutableNotificationContent()
    content.title = "エリアに入場しました"
    content.body = "東京エリアに入りました。"

    let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
    let request = UNNotificationRequest(identifier: "GeofenceNotification", content: content, trigger: trigger)

    notificationCenter.add(request, withCompletionHandler: nil)
}

このコードでは、東京の中心部を中心に、半径100mの範囲を監視対象として設定しています。

このエリアに入った際に、カスタム通知が表示されるようになっています。

○サンプルコード8:位置情報の精度を調整する

位置情報の精度は、使用目的やバッテリー消費量に応じて適切に調整する必要があります。

下記のサンプルコードでは、位置情報の精度をベストな精度に設定しています。

import CoreLocation

let locationManager = CLLocationManager()

func setupLocationAccuracy() {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
}

このコードでは、kCLLocationAccuracyBestを使用して、最も高い精度での位置情報取得を設定しています。

ただし、この設定はバッテリーを大幅に消費するため、常時の使用は推奨されません。

アプリの要件に合わせて、適切な精度を選択することが大切です。

○サンプルコード9:取得間隔をカスタマイズする

位置情報の取得間隔は、アプリの要件やバッテリーの消費量に応じて調整することが可能です。

頻繁に位置情報を取得するとバッテリー消費が増大するため、適切な間隔を設定することが重要です。

下記のサンプルコードは、位置情報の取得間隔を10分に設定する方法を表しています。

import CoreLocation

let locationManager = CLLocationManager()

func setupLocationUpdateInterval() {
    // 位置情報取得の間隔を10分(600秒)に設定
    locationManager.distanceFilter = 600.0
}

このコードを実行すると、前回の位置情報取得から600秒経過した後に次の位置情報が取得されるようになります。

このように、distanceFilterプロパティを使用して、位置情報取得の間隔をカスタマイズすることができます。

○サンプルコード10:バックグラウンド取得を一時的に停止する

時折、特定のシチュエーションで位置情報のバックグラウンド取得を一時的に停止したい場合があります。

下記のサンプルコードは、バックグラウンドでの位置情報取得を一時的に停止する方法を表しています。

import CoreLocation

let locationManager = CLLocationManager()

func stopBackgroundLocationUpdates() {
    // バックグラウンドでの位置情報取得を停止
    locationManager.stopUpdatingLocation()
}

func startBackgroundLocationUpdates() {
    // バックグラウンドでの位置情報取得を再開
    locationManager.startUpdatingLocation()
}

上記のstopBackgroundLocationUpdates関数を呼び出すことで、バックグラウンドでの位置情報取得を一時的に停止することができます。

再開する場合は、startBackgroundLocationUpdates関数を呼び出します。

まとめ

Swiftを用いて位置情報をバックグラウンドで取得する方法は、モバイルアプリ開発の多岐にわたるシチュエーションで役立つスキルと言えるでしょう。

この記事を通じて、基本的な位置情報の取得手法から、カスタマイズや最適化の方法、そして注意点や対処法まで、多くの知識を得ることができたことと思います。

特に、バッテリー消費の問題やプライバシーに関する考慮点は、開発者として常に意識しておくべき重要なポイントです。

ユーザーの利便性や体験を最優先にしつつ、テクニカルな問題や課題にも柔軟に対応できる開発者として成長するために、これらの知識を活かして実践的な開発に取り組むことをおすすめします。

Swiftに関する位置情報取得の技術や手法は日々進化しています。

常に最新の情報をキャッチアップし、技術の深化を目指してください。

これからも、Swiftを活用したアプリ開発が、より多くのユーザーにとって価値あるものとなるよう、努力と挑戦を続けてまいりましょう。