UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Show and Update MKPolygon on a Map

Forums > SwiftUI

Hello, I have an app which is connected to an MQTT Broker. Via the MQTT Broker the app receives a JSON, let's call it a field, containing an array of lat/lng points, id and a name. Subscription to the specific topic works, there is a class type which inherts from MKPolygon in order to store the points, the id and the name.

I have created the basic mapkit setup ( as it is shown here on hacking with swift in one of the tutorials)

My question is, where do I put the code which handles the creation of the overlay and especially where do I put the code when a new field is received via the mqtt broker?

Here is my basic mqtt class which connects and listens for messages:

class MqttData: ObservableObject, CocoaMQTTDelegate
{
    @Published public var fieldPolygon: FieldPolygon = FieldPolygon()

    init() {
        let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
        let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
        let mqtt = CocoaMQTT(clientID: clientID, host: "xxx", port: 9001, socket: websocket)
        mqtt.username = "xxx"
        mqtt.password = "xxx"
        mqtt.keepAlive = 60
        mqtt.delegate = self
        mqtt.connect()
    }

    func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
        if (ack == .accept) {
            debugPrint("MQTT connection accepted!")
            mqtt.subscribe("#", qos: CocoaMQTTQoS.qos0)
        }
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {

    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {

    }

    func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {

        let topic = message.topic
        guard let msg = message.string else {
            return
        }
        let data = Data(msg.utf8)

        if ("/hmi/field_select" == topic) {
            self.fieldSelectHandler(data: data)
        }
    }

    func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
    }

    func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
    }

    func mqttDidPing(_ mqtt: CocoaMQTT) {
    }

    func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
    }

    func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
    }

    func fieldSelectHandler(data: Data) {
        Task {
            do {
                let fieldData = try JSONDecoder().decode(FieldData.self, from: data)
                let field = try await APIManager.shared.loadFieldData(fieldId: fieldData.fieldId)

                var points: [CLLocationCoordinate2D] = []
                for coordinate in field.coords {
                    points.append(CLLocationCoordinate2DMake(coordinate.lat, coordinate.lng))
                }

                self.fieldPolygon = FieldPolygon(coordinates: &points, count: points.count)
                self.fieldPolygon.fieldId = field.id

            } catch {
                debugPrint("fieldSelectHandler Exception: \(error)")
            }
        }
    }
}

Here is the parent view which integrates the map view

struct HmiMapView: View {

  @EnvironmentObject var mqttData: MqttData

  var body: some View {
    MapView(mqttFieldPolygon: mqttData.fieldPolygon)
  }
}

MapView here is a basic implementation (UIViewRepresentable / Coordinator / MKMapViewDelegate)

My first try was to create a private member within my MapView struct, store the polygon within the private member and create a overlay and add it to the map. Whenever a further polygon is received via MQTT, I need to check - has the map already a overlay, if true check if the id is the same and if not, delete the old overlay and create a new one.

So where does this functionality typically exists? But the MapView struct should (or could) not have a private member var.

Regards Marcus

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.