首页 > 解决方案 > 无法使用 CoreData 'NSManagedObject' 获取数据没有成员 'fetch'

问题描述

我是 swift 和 Xcode 12 的初学者,在创建项目时忘记检查选项核心数据后,我试图在我的项目中正确实现核心数据,我操作了我的 appDelegate.swift 并且我写了几行关于核心数据功能,但我仍然面临诸如错误类型'NSManagedObject'没有成员'fetch'之类的问题,我觉得我没有正确实现核心数据

经过几次操作,这里是我的 AppDelegate.swift :

//
//  AppDelegate.swift
//  Bicycall
//
//  Created by Jamil Joo on 1/12/2020.
//

import UIKit
import CoreData

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }

    // MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {
        /*
         The persistent container for the application. This implementation
         creates and returns a container, having loaded the store for the
         application to it. This property is optional since there are legitimate
         error conditions that could cause the creation of the store to fail.
        */
        let container = NSPersistentContainer(name: "Bicycall")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                 
                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

}

这是我使用核心数据的控制器:

//
//  login.swift
//  Bicycall
//
//  Created by Jamil Joo on 2/12/2020.
//

import UIKit
import CoreData

class login: UIViewController {

    var id: Int?
    var name: String?
    var lastname: String?
    var email:String?
    var password:String?
    var phone:String?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.DeleteAllData()
        // Do any additional setup after loading the view.
    }
    
    //widgets
    
    @IBOutlet weak var txtEmail: UITextField!
    
    
    @IBOutlet weak var txtPassword: UITextField!
    
    
    
    //Actions
    @IBAction func btnLogin(_ sender: Any){

         //get
       /*
        guard let url = URL(string: "http://localhost:3000/bikes") else {
        return
        }
        let session = URLSession.shared
        session.dataTask(with: url)  { ( data , response ,error) in
            if let response = response {
                print(response)
            }
            
            if let data = data {
                print(data)
                do
                {
                    let json = try JSONSerialization.jsonObject(with: data, options: [])
                    print(json)
                }catch{
                    print(error)
                }
            }
            
        }.resume()
        */
        
        //post
    
        guard let url = URL(string: "http://localhost:3000/login") else {
        return
        }
        
        let bodyparameters = ["email": txtEmail.text, "password": txtPassword.text]
       
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        guard let httpBody = try? JSONSerialization.data(withJSONObject: bodyparameters, options: []) else{
            return
            }
        request.httpBody = httpBody
        let session = URLSession.shared
        session.dataTask(with: request) { (data,response,error) in
            if let response = response {
                print(response)
            }
            
            if let data = data {
                do {
                    //let json = try JSONSerialization.jsonObject(with: data, options: [])
                   // print(json);
                    print(data)
                    let user = try JSONDecoder().decode(User.self, from: data)
                   
                    DispatchQueue.main.async {
                        
                        self.id = user.user_id
                        self.name = user.name
                        self.lastname = user.lastname
                        self.email = user.email
                        self.password = user.password
                        self.phone = user.phone
                        
                        print(self.id!)
                        print(self.email!)
                        
                        
                        if(user.user_id != 0){
                            //self.saveUser(user)
                           self.performSegue(withIdentifier: "HomeSegue", sender: "nil")
                            self.saveUser()
                        }else{
                        
                            let alert = UIAlertController(title: "Login Failed", message: "Wrong credentials", preferredStyle: .alert)
                            alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
                            alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
                            self.present(alert, animated: true)
                            
                        }
                    
                    }
                    
                }catch{
                    print(error)
                }
                
            }
            
        }.resume()
        
        
    
    }
    
    
    func DeleteAllData(){

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let managedContext = appDelegate.persistentContainer.viewContext
        let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: NSFetchRequest<NSFetchRequestResult>(entityName: "Users"))
        do {
            try managedContext.execute(DelAllReqVar)
        }
        catch {
            print(error)
        }
    }

    

    func saveUser() {
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        //represente l'ORM
        let persistentContainer = appDelegate.persistentContainer
        let managedContext = persistentContainer.viewContext
        
        let entityDescription = NSEntityDescription.entity(forEntityName: "Users" ,  in: managedContext)
        let object = NSManagedObject(entity: entityDescription! , insertInto: managedContext )
        object.setValue(id!  ,  forKey: "user_id"  )
        object.setValue(email!  ,  forKey: "email"  )
        object.setValue(password!  ,  forKey: "password"  )
        object.setValue(name!  ,  forKey: "name"  )
        object.setValue(lastname!  ,  forKey: "lastname"  )
        object.setValue(phone!  ,  forKey: "phone"  )
        
                  do {
                  
                 try managedContext.save()
                   print("INSERT SUCCESSFULLY")
                print(id!)
                   }
                   catch  {
                   print("INSERT ERROR")
                   }
        
    }
    
    
    func DisplayData() {
        
        
         let appDelegate = UIApplication.shared.delegate as! AppDelegate

            //represente l'ORM
            let persistentContainer = appDelegate.persistentContainer
            
            let managedContext = persistentContainer.viewContext     //retourne NSManagedObject toujours
            
            //la requete retourne un NSManagedObject
            let request = NSFetchRequest<NSManagedObject>(entityName :   "Users")
            
            //execution de la requete
            do {
            let result = try  NSManagedObject.fetch(request)
            for item in result {
            favourites.append(item.value(forKey: "MovieName")  as! String)
              item.value()
            }
            
               }
               catch {
               print("NO DATA FOUND , Error")
               }


    }
    
    
    
    @IBAction func btnSignup(_ sender: Any) {
        performSegue(withIdentifier: "signupSegue", sender: "nil")
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      
    }

我要做的是修复我的项目CoreData并修复可以修复的内容以防止我在控制器中获得的错误

ps:我已经创建了一个数据模型Users

标签: swiftxcodecore-data

解决方案


该错误是一个错字并且非常清楚:

你不能调用fetch类型 NSManagedObject你必须调用它的NSManagedObjectContext 实例

代替

let result = try  NSManagedObject.fetch(request)

let result = try  managedContext.fetch(request)

推荐阅读