MKMapview에 annotation 표시하고 실시간 위치 정보 가져오기

DevelopRecord·2022년 4월 23일
0

드라이버의 위치 어노테이션을 커스텀하고 위치값이 바뀔 때 바뀐 위치에도 어노테이션을 표시해보자.

Annotation 클래스 생성

import MapKit

class DriverAnnotation: NSObject, MKAnnotation {
    public static let identifier = "DriverAnnotation"

    dynamic var coordinate: CLLocationCoordinate2D
    var uid: String

    init(coordinate: CLLocationCoordinate2D, uid: String) {
        self.coordinate = coordinate
        self.uid = uid
    }
}

Annotation 클래스를 생성하고 NSObject, MKAnnotation을 상속한다.
MKAnnotation을 상속하려면 NSObject도 같이 상속해야하니까 잊지말고 꼭 입력하자.

identifier

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {}

이것을 사용할 때 필요하기 때문에 static하게 선언해 놓았다.

dynamic var coordinate: CLLocationCoordinate2D
이 클래스는 coordinate라는 변수를 가지고 있다.
dynamic으로 한 이유는 coordinate 값이 항상 바뀌고 실시간으로 반영이 되어야 하기 때문이다.

uid
특정 드라이버의 정보를 가져와야하기 때문에 필요하다.

드라이버의 annotation 위치 가져오기

func fetchDriver(location: CLLocation, completion: @escaping(User) -> Void) {
        let geoFire = GeoFire(firebaseRef: REFERENCE_DRIVER_LOCATIONS)

        REFERENCE_DRIVER_LOCATIONS.observe(.value) { _ in
            geoFire.query(at: location, withRadius: 50).observe(.keyEntered, with: { uid, location in
                Service.shared.fetchUser(uid: uid, completion: { user in
                    var driver = user
                    driver.location = location
                    completion(driver)
                })
            })
        }
    }

유저의 위치에서 반경 50m 이내의 드라이버들의 위치를 가져오고 만약 드라이버의 위치가 변경되면 드라이버의 위치가 다시 반영이 되게 했다.

드라이버의 실시간 위치 업데이트

func fetchDrivers() {
        guard let location = locationManager?.location else { return }
        ServiceAPI.shared.fetchDriver(location: location) { driver in

            guard let coordinate = driver.location?.coordinate else { return }
            let annotation = DriverAnnotation(coordinate: coordinate, uid: driver.uid)

            self.mapView.addAnnotation(annotation)
    }
}

view가 로드되면 드라이버의 위치 정보를 가져오고,
가져온 위치 정보를 바탕으로 annotation을 맵뷰에 추가한다.
그럼 아래와 같이 annotation이 표시된다.

커스텀 어노테이션

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
	if let annotation = annotation as? DriverAnnotation {
    	let view = MKAnnotation(annotation: annotation, reuseIdentifier: DriverAnnotation.identifier)
        view.image = UIImage(systemName: "arrow.right.circle.fill")
        return view
    }
    
    return nil
}

헷갈리는 부분이나 개념이 있으면 여기에 정리할 예정.. 끝.

0개의 댓글