swiftUI入門

GPS で現在地の住所の特定するアプリの実装

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(ログイン画面)

  • TextFieldSecureField でユーザー名・パスワード入力。
  • Button("ログイン") を押すと isLoggedIntrue になり 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: 住所を表示するかどうかを制御するフラグ。

🔹 主要なメソッド

  1. init()
  • 初期化時にデリゲートを設定。
  • requestWhenInUseAuthorization() を呼び出し、位置情報の使用許可をリクエスト。
  1. startUpdatingLocation()
  • locationManager.startUpdatingLocation() を呼び出して位置情報の取得を開始。
  1. stopUpdatingLocation()
  • locationManager.stopUpdatingLocation() を呼び出して取得を停止(バッテリー節約)。
  1. locationManager(_:didUpdateLocations:)
  • 位置情報が更新されるたびに呼ばれるデリゲートメソッド。
  • fetchAddress(from:) を呼び出して住所を取得。
  1. 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要素

  1. 「位置検索」ボタン
  • locationManager.startUpdatingLocation() を呼び出し、現在地の取得を開始。
  1. 住所の表示
  • locationManager.showAddresstrue なら、取得した locationManager.currentAddress を表示。
  1. 「OK」ボタン
  • 押すと locationManager.showAddress = false にして住所の表示を消す。

4. GPSLocationApp.swift(アプリのエントリーポイント)

アプリの起動時に LoginView を表示する設定。

🔹 主要なコード

@main
struct GPSLocationApp: App {
    var body: some Scene {
        WindowGroup {
            LoginView()
        }
    }
}
  • @main アノテーションでアプリのエントリーポイントを定義。
  • WindowGroupLoginView() を設定し、最初にログイン画面が表示されるようにする。