Как сохранить ответ JSON от входа пользователя в Core Data для отслеживания состояния пользователя в Swift?

Я пытаюсь сохранить свой ответ json от входа пользователя в Core Data, чтобы, когда пользователь выйдет из приложения и снова откроется, он распознал этого конкретного пользователя. У меня есть только простой json, который имеет тип [String: Any, …. String: Any], теперь я сохранил ответ, создав модель структуры, как показано ниже. Может ли кто-нибудь узнать лучший способ достичь того, чего я хочу, пожалуйста Помогите мне, я новичок в Core Data, я не знаю, с чего начать

Вот как я запрашиваю и сохраняю json

Вот моя модель LoginInfo

Вот мой объект Core Data

print(loginData) печатает правильную информацию?   —  person Ulugbek    schedule 08.03.2021

да, он напечатает логин json   —  person Ulugbek    schedule 08.03.2021

Почтовый индекс в виде текста, а не изображений   —  person Ulugbek    schedule 08.03.2021

Вам следует начать с выполнения некоторых руководств и чтения некоторых статей по Core Data, поскольку stackoverflow не является учебным сайтом, поэтому этот вопрос слишком широкий и должен быть закрыт.   —  person Ulugbek    schedule 08.03.2021

да, я читал яблочный документ, и их пример использования CoreData был трудным для понимания концепции, поэтому я поискал в сети полезных руководств, но безуспешно, и последний вариант — запросить stackoverflow,   —  person Ulugbek    schedule 08.03.2021

Нет, stackoverflow не является «последним вариантом» при проведении исследований и / или обучения. Кроме того, если все, что вы хотите достичь, это распознать пользователя, который вошел в систему, я уверен, что UserDefaults будет достаточно.   —  person Ulugbek    schedule 08.03.2021

См. также:  Swift - виджет не может получить доступ к группе приложений
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Ulugbek

    Сначала объявите свой основной контейнер данных

    //CoreData container
    private lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "container_name")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error {
                //Error handling
            }
        })
        return container
    }()
    

    Здесь container_name будет вашим именем файла основных данных.

    Затем эта функция выполнит сохранение:

    public func saveLoginData(data: LoginData) {
        let context: NSManagedObjectContext = self.persistentContainer.viewContext
    
        let entityDescription: NSEntityDescription = NSEntityDescription.entity(forEntityName: "LoginInfo", in: context)!
    
        let loginInfoEntry: NSManagedObject = NSManagedObject(entity: entityDescription, insertInto: context)
    
        //Set your values here
        loginInfoEntry.setValue(data.AccountId, forKey: "accountId")
        loginInfoEntry.setValue(data.UserId, forKey: "userId")
        ... //Set all your values
    
        //Then save
        do {
            try context.save()
        } catch {
            //Error handling
        }
    }
    

    Для запроса ваших данных:

    public func getLoginData() -> LoginData? {
        let context: NSManagedObjectContext = self. persistentContainer.viewContext
        let loginDataFetchRequest: NSFetchRequest = NSFetchRequest<NSManagedObject>(entityName: "LoginInfo")
        do {
            let fetchedData: [Any] = try context.fetch(loginDataFetchRequest)
            let loginDataObjectArray: = fetchData as! [NSManagedObject]
            let loginDataObject: NSManagedObject = loginDataObjectArray[0]
            var loginData: LoginData = LoginData()
            loginData.AccountId = loginDataObject.value(forKey: "accountId") as! String
            ...//Set all your values
            
            return loginData
            
        } catch {
            //Handle errors
            return nil
        }
    }
    

    Это простой ответ на ваш вопрос, который направит вас в нужном направлении. Обратитесь к документации CoreData и некоторым другим руководствам, чтобы лучше понять. Также не забудьте обработать все ошибки, которые могут возникнуть в результате выполнения вышеуказанных шагов. Я не рассматривал каждый сценарий, в котором может произойти ошибка.

    спасибо за вашу помощь, но для запроса он не работает, поскольку LoginData является протоколом Decodable, он говорит, что выдает ошибку, и я не могу создать новый экземпляр LoginData, когда я его запрашиваю, есть ли способ? person Ulugbek; 08.03.2021

    Я обновил ответ. var loginData: LoginData = LoginData(). Не могли бы вы показать ошибку, пожалуйста person Ulugbek; 08.03.2021

    он говорит, что отсутствует аргумент для параметра ‘from’ в вызове в var loginData: LoginData = LoginData(), я должен передать параметр LoginData () некоторому декодеру, это ошибка person Ulugbek; 08.03.2021

    Проверьте, правильно ли поступают значения из запроса, используя только print(loginDataObject.value(forKey: "accountId") as! String) без создания loginData. person Ulugbek; 08.03.2021

    chat.stackoverflow.com/rooms/229646/ заходите в чат person Ulugbek; 08.03.2021

  2. Ulugbek

    Основы
    Создайте свой проект Swift на XCode и проверьте Use CoreData
    Обязательно используйте import CoreData в заголовке вашего класса

    Сохранение в CoreData
    Если в вашем проекте используется CoreData, вы можете выполнить функцию сохранения, указанную ниже:

    func saveLoginDataToCoreData(data: LoginData){
    
        guard let appDel = UIApplication.shared.delegate as? AppDelegate else { return }
        let context = appDel!.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "LoginInfo", in: context)!
        let mngdObj = NSManagedObject(entity: entity, insertInto: context)
        
        mngdObj.setValue(data.LoginToken, forKeyPath: "loginToken")
        mngdObj.setValue(data.UserId, forKeyPath: "userId")
        // Add all loginData here...
         
        do { try context.save(); print("LoginData has been saved to CoreData")
        } catch { print("An error has occurred: \(error.localizedDescription)") } }
    

    С другой стороны, если ваш проект не использует CoreData, вы можете объявить контейнер CoreData под названием CoreData Stack (он автоматически включается в проект, который использует CoreData в AppDelegate). Вы можете поместить его в класс ViewController там, где он вам нужен, или добавить в расширение UIViewController для глобального использования:

    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Your_DataModel_Filename")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                print("An error has occurred: \(error.localizedDescription)")
            }
        })
        return container
    }()
    

    Использовать:

    func saveLoginDataToCoreData(data: LoginData){
        
        let context: NSManagedObjectContext = self.persistentContainer.viewContext
        let entity: NSEntityDescription = NSEntityDescription.entity(forEntityName: "LoginInfo", in: context)!
        let mngdObj: NSManagedObject = NSManagedObject(entity: entity, insertInto: context)
        
        mngdObj.setValue(data.LoginToken, forKeyPath: "loginToken")
        mngdObj.setValue(data.UserId, forKeyPath: "userId")
        // Add all loginData here...
         
        do { try context.save(); print("LoginData has been saved to CoreData")
        } catch { print("An error has occurred: \(error.localizedDescription)") } }
    

    ОБНОВЛЕНИЕ: дополнительные ответы

    Если вы хотите использовать этот loginToken или ЛЮБЫЕ данные из LoginData, мы можем получить значения, которые мы сохранили из CoreData ранее.

    Для эффективного получения значений лучше всего сначала сохранить LoginToken текущего пользователя. Для облегчения доступа я предлагаю вам сохранить его в UserDefaults при ВХОДЕ и просто удалить его при выходе.

    func saveCurrentLoginToken(_ token:String){
        let defaults = UserDefaults.standard
        defaults.set(token, forKey: "currentLoginToken")
        defaults.synchronize() }
    

    Пример использования:

    // ...
    let currentLoginToken = data.LoginToken
    mngdObj.setValue(currentLoginToken, forKeyPath: "loginToken")
    self.saveCurrentLoginToken(currentLoginToken)
    // ...
    

    Чтобы получить currentLoginToken:

    func getCurrentLoginToken() -> String? {
        let defaults = UserDefaults.standard
        let token = defaults.object(forKey: "currentLoginToken") as? String
        if token != nil { return token! // Return value if not nil
        } else { return nil } // Will return as nil if you haven't save the LoginToken in UserDefaults
    }
    

    Получение определенных данных

    Я создал функцию, которую мы можем использовать для получения ЛЮБОЙ информации, которую мы сохранили ранее:

    func getAnyValueFromCoreData(_ loginToken:String,_ key:String) -> Any? { // key = data you want to retrieve the value of
    
        guard let appDel = UIApplication.shared.delegate as? AppDelegate else { return nil }
        let context = appDel.persistentContainer.viewContext
        let fetchReq = NSFetchRequest<NSManagedObject>(entityName: "LoginInfo")
        fetchReq.predicate = NSPredicate(format: "loginToken==%@",loginToken)
        
        var anyVal: Any?
        
        do { let result = try context.fetch(fetchReq)
            for data in result {
                let val = data.value(forKey: key)
                // Check if nil to avoid fatal error
                if val != nil { anyVal = val! } else { anyVal = nil } }
        } catch {
            anyVal = nil // Set value to nil in case of error (not always recommended)
            print("An error has occurred: \(error.localizedDescription)")
        }
        
        return anyVal }
    

    Теперь, например, если вы хотите получить ReturnCode текущего пользователя:

    func getReturnCode() -> Int? {
         let token = getCurrentLoginToken() // retrieve from UserDefaults
         let returnCode = getAnyValueFromCoreData(token!,"returnCode") as? Int
         return returnCode
    }
    

    Для использования (в ситуации, описанной в комментарии):

    func checkReturnCode(){
         let returnCode = getReturnCode()! // catch if nil?
         if returnCode == 0 {
              // show MainPage to User
         } else { }
         // or use Switch Statements for more than two ReturnCodes
         // or to handle error in case of default (nil value)
    }
    

    Заявление об ограничении ответственности: я не тестировал приведенные выше коды. Если вы столкнетесь с какой-либо ошибкой, просто дайте мне знать в комментариях.
    Изменить: обновлено fetchReq и заменено filterReq в getAnyValueFromCoreData() (самодельные функции)

    спасибо, все сработало, но позже, если я захочу использовать эти loginTokens или какие-либо данные из LoginData, как я могу их получить? например, в другом vc, если returnCode == 0, показать пользователю главную страницу. person Ulugbek; 08.03.2021

    Я обновил свой ответ, чтобы ответить на ваши дополнительные вопросы. пожалуйста, дайте мне знать, работает ли это person Ulugbek; 08.03.2021

    Я думаю, что это какая-то ошибка, я поискал в Интернете, но не нашел решения, там написано Cannot find 'fetchEntity' in scope и Cannot find 'filterReq' in scope в getAnydatafromCoredata() методе person Ulugbek; 09.03.2021

    @Ulugbek, извините, это были самодельные функции, которые я забыл включить. Обновлю свой ответ person Ulugbek; 09.03.2021

    Да, не беспокойтесь, я так благодарен за вашу помощь. Теперь, глядя на код, и я понимаю поток, я с нетерпением жду вашего обновления, person Ulugbek; 09.03.2021

    @ Улугбек, я отредактировал свой ответ, пожалуйста, дайте мне знать, как все прошло person Ulugbek; 09.03.2021

    @Ulugbek, если какой-либо из ответов решил ваш вопрос, отметьте его как ответ. Спасибо person Ulugbek; 10.03.2021

    Я пометил его как полезный, НЕТ? person Ulugbek; 10.03.2021

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: