Contents
GPS で現在地の住所を特定するアプリの実装
この構成で、ログイン → ホーム画面 → 位置検索 という流れが実装されています!
LocationManager.swift
import Foundation
import CoreLocation
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private var locationManager = CLLocationManager()
@Published var currentAddress: String = ""
@Published var showAddress: Bool = false
override init() {
super.init()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
func startUpdatingLocation() {
locationManager.startUpdatingLocation()
}
func stopUpdatingLocation() {
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
fetchAddress(from: location)
}
private func fetchAddress(from location: CLLocation) {
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
if let error = error {
print("Failed to get address: \(error.localizedDescription)")
return
}
if let placemark = placemarks?.first {
let address = [placemark.thoroughfare, placemark.locality, placemark.administrativeArea, placemark.country]
.compactMap { $0 }
.joined(separator: ", ")
DispatchQueue.main.async {
self.currentAddress = address
self.showAddress = true
self.stopUpdatingLocation()
}
}
}
}
}
LoginView.swift
import SwiftUI
struct LoginView: View {
@State private var username: String = ""
@State private var password: String = ""
@State private var isLoggedIn: Bool = false
var body: some View {
if isLoggedIn {
HomeView()
} else {
VStack(spacing: 20) {
Text("ログイン")
.font(.largeTitle)
.padding()
TextField("ユーザー名", text: $username)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
SecureField("パスワード", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Button("ログイン") {
isLoggedIn = true
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.padding()
}
}
}
HomeView.swift
import SwiftUI
struct HomeView: View {
@StateObject private var locationManager = LocationManager()
var body: some View {
VStack(spacing: 20) {
Text("ホーム画面")
.font(.largeTitle)
.padding()
Button("位置検索") {
locationManager.startUpdatingLocation()
}
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
if locationManager.showAddress {
Text(locationManager.currentAddress)
.font(.title2)
.padding()
Button("OK") {
locationManager.showAddress = false
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
.padding()
}
}
GPSLocationApp.swift
import SwiftUI
@main
struct GPSLocationApp: App {
var body: some Scene {
WindowGroup {
LoginView()
}
}
}
構成要素
このアプリのコードは、以下のような構成になっています!
📌 1. LocationManager.swift(位置情報管理)
CLLocationManagerを使ってGPSから現在地を取得。CLGeocoderで緯度・経度を住所に変換。@Published var currentAddress:取得した住所を保存。@Published var showAddress:住所の表示フラグ。startUpdatingLocation():位置情報の取得を開始。stopUpdatingLocation():取得後、バッテリー節約のために停止。
📌 2. LoginView.swift(ログイン画面)
TextFieldとSecureFieldでユーザー名・パスワード入力。Button("ログイン")を押すとisLoggedInがtrueになりHomeViewに遷移。
📌 3. HomeView.swift(ホーム画面)
Button("位置検索")を押すとLocationManagerが現在地を取得。- 住所が表示されると
Button("OK")で非表示に戻る。
📌 4. GPSLocationApp.swift(アプリのエントリーポイント)
- アプリ起動時に
LoginViewを表示。 @mainキーワードでアプリのエントリーポイントを定義。
📌 5. Info.plist(位置情報の使用許可)
- 位置情報の利用許可を求めるために以下を追加:
LocationWhenInUseUsageDescription
⇨このアプリは現在地の住所を取得するために位置情報を使用します。
コード解説
1. LocationManager.swift(位置情報管理)
このファイルは、ユーザーの現在地の住所を取得するためのロジックを実装しています。
🔹 LocationManager クラス
NSObjectを継承(CoreLocationのデリゲートに必要)。ObservableObjectにすることで、SwiftUIビューがこのクラスのプロパティを監視できる。CLLocationManagerDelegateを実装し、位置情報の取得を処理。
🔹 主要なプロパティ
locationManager:CLLocationManagerインスタンス(位置情報の管理)。@Published var currentAddress: 取得した住所を保存(SwiftUIビューと連携)。@Published var showAddress: 住所を表示するかどうかを制御するフラグ。
🔹 主要なメソッド
init()
- 初期化時にデリゲートを設定。
requestWhenInUseAuthorization()を呼び出し、位置情報の使用許可をリクエスト。
startUpdatingLocation()
locationManager.startUpdatingLocation()を呼び出して位置情報の取得を開始。
stopUpdatingLocation()
locationManager.stopUpdatingLocation()を呼び出して取得を停止(バッテリー節約)。
locationManager(_:didUpdateLocations:)
- 位置情報が更新されるたびに呼ばれるデリゲートメソッド。
fetchAddress(from:)を呼び出して住所を取得。
fetchAddress(from:)
CLGeocoderを使って逆ジオコーディング(緯度・経度→住所)。- 取得した住所を
currentAddressに保存。 showAddress = trueに設定し、住所の表示を有効化。- 取得が完了したら
stopUpdatingLocation()で更新を停止。
2. LoginView.swift(ログイン画面)
このファイルでは、ユーザーがログインするための画面を実装しています。
🔹 主要なプロパティ
@State private var username: ユーザー名の入力。@State private var password: パスワードの入力。@State private var isLoggedIn: ログイン状態を管理(trueならHomeViewに遷移)。
🔹 主要なUI要素
Text("ログイン"): ログイン画面のタイトル。TextField&SecureField: ユーザー名とパスワードの入力。Button("ログイン"): ボタンを押すとisLoggedIn = trueになり、HomeViewに移動。
3. HomeView.swift(ホーム画面)
ログイン後に表示される画面で、位置情報の検索ができます。
🔹 主要なプロパティ
@StateObject private var locationManager:LocationManagerのインスタンスを管理。
🔹 主要なUI要素
- 「位置検索」ボタン
locationManager.startUpdatingLocation()を呼び出し、現在地の取得を開始。
- 住所の表示
locationManager.showAddressがtrueなら、取得したlocationManager.currentAddressを表示。
- 「OK」ボタン
- 押すと
locationManager.showAddress = falseにして住所の表示を消す。
4. GPSLocationApp.swift(アプリのエントリーポイント)
アプリの起動時に LoginView を表示する設定。
🔹 主要なコード
@main
struct GPSLocationApp: App {
var body: some Scene {
WindowGroup {
LoginView()
}
}
}
@mainアノテーションでアプリのエントリーポイントを定義。WindowGroupにLoginView()を設定し、最初にログイン画面が表示されるようにする。
