【问题标题】: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 是什么以及如何正确使用它。

标签: swift 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)")
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 2010-09-06
    • 2012-12-30
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多