当我离开应用程序时,如何保存我的 MapView 注释?
How can I get my MapView annotations to save when I leave the app?
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 的新手,想知道如何在离开应用程序后保存我的注释。另外,如果用户没有拿起手指,我该如何阻止形成多个注释?
您可能需要做的是将 MKPointAnnotation
作为 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)
}
然后,当再次打开视图控制器时,您需要从 UserDefaults
中提取此 Data
并将其解析为 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)
}
}
}
...
}
如果注释被删除,您将需要类似地将存储的数据转换为字典数组并删除适当的对象并更新数据。
在 iOS 上有很多持久性策略,并且取决于许多因素,例如您将保存多少注释、数据的敏感程度等。
Apple 的持久性指南在这里:https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/PersistData.html
尽管我并不是真的建议这样做,但您也许可以自己序列化对象。相反,请考虑编写自己的符合 Codable
的注释类型,以使持久化更安全、更容易。本教程合理地涵盖了您的用例:
令人恼火的是 CLLocationCoordinate2D
不是 Codable
本身,这就是为什么你必须跳过一些障碍。
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 的新手,想知道如何在离开应用程序后保存我的注释。另外,如果用户没有拿起手指,我该如何阻止形成多个注释?
您可能需要做的是将 MKPointAnnotation
作为 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)
}
然后,当再次打开视图控制器时,您需要从 UserDefaults
中提取此 Data
并将其解析为 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)
}
}
}
...
}
如果注释被删除,您将需要类似地将存储的数据转换为字典数组并删除适当的对象并更新数据。
在 iOS 上有很多持久性策略,并且取决于许多因素,例如您将保存多少注释、数据的敏感程度等。
Apple 的持久性指南在这里:https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/PersistData.html
尽管我并不是真的建议这样做,但您也许可以自己序列化对象。相反,请考虑编写自己的符合 Codable
的注释类型,以使持久化更安全、更容易。本教程合理地涵盖了您的用例:
令人恼火的是 CLLocationCoordinate2D
不是 Codable
本身,这就是为什么你必须跳过一些障碍。