Как получить аннотации MapView для сохранения при выходе из приложения? - PullRequest
0 голосов
/ 26 сентября 2019
func addPin(_ sender: UILongPressGestureRecognizer) {

    let location = sender.location(in: self.mapView)
    let locCoord = self.mapView.convert(location, toCoordinateFrom: self.mapView)

    let annotation = MKPointAnnotation()

    annotation.coordinate = locCoord
    annotation.title = titleTextField.text

    self.mapView.addAnnotation(annotation)

    print("This will become the annotation title: \(titleTextField.text).")
    print(annotation.coordinate.latitude, annotation.coordinate.longitude)

}

Я новичок в swift и хотел бы узнать, как сохранить свои аннотации для сохранения после выхода из приложения.Кроме того, как я могу остановить формирование нескольких аннотаций, если пользователь не поднимает палец?

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Существует много стратегий сохранения на iOS, которые зависят от многих факторов, таких как, сколько аннотаций вы сохраните, насколько важны данные и т. Д.

Руководство Apple по сохранению приведено здесь: https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/PersistData.html

Возможно, вам удастся избежать сериализации самих объектов, хотя я не советую этого делать.Вместо этого попробуйте написать собственный тип аннотации, соответствующий Codable, чтобы сделать постоянство более безопасным и простым.Этот урок делает разумную работу по рассмотрению вашего варианта использования:

https://www.raywenderlich.com/5247-core-location-tutorial-for-ios-tracking-visited-locations#toc-anchor-022

Досадно, что CLLocationCoordinate2D не является Codable, поэтому вы должны перепрыгнуть через некоторые обручи.

0 голосов
/ 26 сентября 2019

Что вам, вероятно, нужно будет сделать, это сохранить MKPointAnnotation s как Data в UserDefaults.Для этого вы создадите массив словарей из всех аннотаций mapView:

func addPin(_ sender: UILongPressGestureRecognizer) {

    let location = sender.location(in: self.mapView)
    let locCoord = self.mapView.convert(location, toCoordinateFrom: self.mapView)

    let annotation = MKPointAnnotation()

    annotation.coordinate = locCoord
    annotation.title = titleTextField.text

    self.mapView.addAnnotation(annotation)

    //Create a dictionary from the annotation
    let newAnnotationDict = [
        "lat": locCoord.latitude
        "lng": locCoord.longitude
        "title": annotation.title
    ]

    //Pull the stored annotations data
    var annotationsArray: [[String:Any]]!
    var annotationsData = UserDefaults.standard.data(forKey: "StoredAnnotations")

    //If the data is nil, then set the new annotation as the only element in the array
    if annotationsData == nil {
        annotationsArray = [newAnnotationDict]
    } else {
        //If it isn't nil, then convert the data into an array of dicts
        do {
            //Convert this data into an array of dicts
            annotationsArray = try JSONSerialization.jsonObject(with: annotationsData, options: []) as! [[String:Any]]
            annotationsArray.append(newAnnotationDict)
        } catch {
            print(error.localizedDescription)
        }

    }

    do {

        //Use JSONSerialization to convert the annotationsArray into Data
        let jsonData = try JSONSerialization.data(withJSONObject: annotationsArray, options: .prettyPrinted)

        //Store this data in UserDefaults
        UserDefaults.standard.set(jsonData, forKey: "StoredAnnotations")
    } catch {
        print(error.localizedDescription)
    }

    print("This will become the annotation title: \(titleTextField.text).")
    print(annotation.coordinate.latitude, annotation.coordinate.longitude)

}

И затем, когда контроллер представления снова откроется, вы захотите извлечь это Data изUserDefaults и разберите его на массив MKPointAnnotation объектов.

class MapViewController: UIViewController {

    //Whenever the view loads, check if there were any annotations stored last time
    override func viewDidLoad() {
        super.viewDidLoad()

        //Check if the data for "StoredAnnotations" exists
        if UserDefaults.standard.data(forKey: "StoredAnnotations") != nil {

            var storedAnnotationObjects = [MKPointAnnotation]()

            do {

                //Get the data from UserDefaults
                let storedAnnotationsData = UserDefaults.standard.data(forKey: "StoredAnnotations")!

                //Convert this data into an array of dictionaries
                let storedAnnotationsArray = try JSONSerialization.jsonObject(with: storedAnnotationsData, options: []) as! [[String:Any]]

                for dict in storedAnnotationsArray {
                    //Initialize a new annotation and set the annotation's properties
                    let newAnnotation = MKPointAnnotation()
                    newAnnotation.coordinate = CLLocationCoordinate2D(latitude: dict["lat"] as! CGFloat, longitude: dict["lng"] as! CGFloat)
                    newAnnotation.title = dict["title"] as! String
                    newAnnotationObjects.append(newAnnotation)
                }

                //Add the annotation to the mapView
                self.mapView.annotations = storedAnnotationObjects
            } catch {
                print(error.localizedDescription)
            }
        }
    }

    ...

}

Если аннотации удаляются, вам необходимо аналогичным образом преобразовать сохраненные данные в массив dicts и удалить соответствующий объект.и обновите данные.

...