【发布时间】:2021-12-25 02:39:30
【问题描述】:
在我的代码中,用户输入他们的地址,然后将其更改为位置坐标。然后它应该保存到核心数据,另一个视图控制器访问这些坐标并将它们固定在地图上。所以,我的代码可以正常工作,但是在我关闭应用程序并再次打开它之后,地图将位置固定在纬度 0 经度 0 处(基本上它会忘记保存的数据)。
查看控制器 1:
//
// Preferences.swift
// distanceTester
//
// Created by Vaibhav Satishkumar on 12/19/21.
//
import UIKit
import CoreLocation
import CoreData
class Preferences: UIViewController, UITextFieldDelegate {
var data = [User]()
lazy var geocoder = CLGeocoder()
@IBOutlet var countryTextField: UITextField!
@IBOutlet var streetTextField: UITextField!
@IBOutlet var cityTextField: UITextField!
@IBOutlet var locationLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
latCor.delegate = self
longCor.delegate = self
let user = User(context: context)
appDelegate.saveContext()
}
@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
@IBOutlet var geocodeButton: UIButton!
@IBAction func geocode(_ sender: UIButton) {
guard let country = countryTextField.text else { return }
guard let street = streetTextField.text else { return }
guard let city = cityTextField.text else { return }
// Create Address String
let address = "\(country), \(city), \(street)"
// Geocode Address String
geocoder.geocodeAddressString(address) { (placemarks, error) in
// Process Response
self.processResponse(withPlacemarks: placemarks, error: error)
}
// Update View
geocodeButton.isHidden = true
activityIndicatorView.startAnimating()
}
private func processResponse(withPlacemarks placemarks: [CLPlacemark]?, error: Error?) {
// Update View
geocodeButton.isHidden = false
activityIndicatorView.stopAnimating()
if let error = error {
print("Unable to Forward Geocode Address (\(error))")
locationLabel.text = "Unable to Find Location for Address"
} else {
var location: CLLocation?
if let placemarks = placemarks, placemarks.count > 0 {
location = placemarks.first?.location
}
if let location = location {
let coordinate = location.coordinate
locationLabel.text = "\(coordinate.latitude), \(coordinate.longitude)"
let user = User(context: context)
user.lat = coordinate.latitude
user.long = coordinate.longitude
appDelegate.saveContext()
} else {
locationLabel.text = "No Matching Location Found"
}
}
}
@IBOutlet weak var latCor: UITextField!
@IBOutlet weak var longCor: UITextField!
@IBAction func saveCor(_ sender: Any) {
saveData()
fetchData()
}
func saveData(){
let user = User(context: context)
user.lat = latCor.text!.doubleValue
user.long = longCor.text!.doubleValue
do{
try context.save()
}
catch {
//error
}
appDelegate.saveContext()
}
func fetchData(){
do {
data = try context.fetch(User.fetchRequest())
for each in data {
print("Latitude:\(each.lat)/aLongitude: \(each.long)/n")
}
}
catch{
//error
}
}
}
extension String {
var doubleValue: Double {
return Double(self) ?? 0
}
}
查看控制器 2:
import MapKit
import UIKit
import CoreLocation
import UserNotifications
import MessageUI
import GoogleMobileAds
class ViewController: UIViewController, CLLocationManagerDelegate, UNUserNotificationCenterDelegate, MFMessageComposeViewControllerDelegate, GADBannerViewDelegate {
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
}
var data = [User]()
let user = User(context: context)
@IBOutlet var mapView: MKMapView!// <<< add this and connect to the label in IB
@IBOutlet weak var positionLabel: UILabel!
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
mapView.layer.cornerRadius = 16
manager.delegate = self
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
manager.startUpdatingLocation()
// Do any additional setup after loading the view.
// Do any additional setup after loading the view.
}
private func initializeLocationServices(){
manager.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
var coordinate1 = CLLocationCoordinate2D()
func fetchData(){
do {
data = try context.fetch(User.fetchRequest())
for each in data {
print("Latitude:\(each.lat)/aLongitude: \(each.long)/n")
coordinate1.latitude = each.lat
coordinate1.longitude = each.long
appDelegate.saveContext()
}
}
catch{
//urmom
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first{
manager.startUpdatingLocation()
print(location)
render(location)
}
func render(_ location: CLLocation){
fetchData()
appDelegate.saveContext()
let span = MKCoordinateSpan (latitudeDelta: 0.01, longitudeDelta: 0.01)
let region = MKCoordinateRegion(center: coordinate1, span: span)
mapView.setRegion(region, animated: true)
mapView.showsUserLocation = true
let pin = MKPointAnnotation()
pin.coordinate = coordinate1
pin.title = "your home"
pin.subtitle = "Location"
if coordinate1.latitude != 0{
mapView.addAnnotation(pin)
}
else{
coordinate1.latitude = user.lat
coordinate1.longitude = user.long
}
// 1
}
}
【问题讨论】:
-
Core Data 不是初学者技术。你确定你在这里做出了最好的架构决定吗?
-
是的,我有,请帮忙
-
每次您执行
User(context: context)时,都会在Core Data 中创建一个新的用户对象,因此您的核心数据存储中必须有很多空用户。您需要了解 Core Data 是什么以及如何正确使用它。