为啥 CoreData 不保存任何东西?
Posted
技术标签:
【中文标题】为啥 CoreData 不保存任何东西?【英文标题】:Why isn't CoreData saving anything?为什么 CoreData 不保存任何东西? 【发布时间】: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 是什么以及如何正确使用它。
【参考方案1】:
问题一定出在你的保存方法上。您无需调用应用程序委托进行保存,而是需要在您的方法中创建上下文。
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let user = User(context: context)
user.location = //whatever you want to save.
do
try context.save()
catch let error as NSError
print("Could not save. \(error)")
【讨论】:
以上是关于为啥 CoreData 不保存任何东西?的主要内容,如果未能解决你的问题,请参考以下文章
Core Data 的 Save 方法第一次调用“nil” - 为啥?