Как я могу сохранить переменные класса в swift?

#swift #variables #core-data #save

#swift #переменные #core-data #Сохранить

Вопрос:

У меня есть class:

 class Dream {
    var name: String?
    var timeStamp = Date()
}
  

И я хочу сохранить все его переменные

Я пытаюсь сохранить в UserDefaults — но это неправильный способ

Я думаю, что это должно быть сохранено в CoreData, но я не знаю, как это сделать, кто-нибудь может мне помочь?

 var item: [Dream] = []

func addItem(nameItem: Dream) {
    item.append(nameItem)
}

func removeItem(at index: Int){
    item.remove(at: index)
}
  

Я использую функцию addItem в IBAction

 @IBAction func saveButton(_ sender: Any) {
        let image = categoryImage.image
        let data = image!.jpegData(compressionQuality: 0.5)!
        let date = Date()
        let name = date.description
        do {
            let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
            let fileURL = documentDirectory.appendingPathComponent(name)

            try data.write(to: fileURL)

            print(fileURL)

        } catch {
            print(error.localizedDescription)
        }
        let dream = Dream()
        dream.timeStamp = date
        dream.name = nameTextField.text

        addItem(nameItem: dream)
        navigationController?.popViewController(animated: true)
    }
  

Комментарии:

1. Посмотрите этот клип, и вы узнаете все, что вам нужно. youtube.com/watch?v=OYRo3i9z-lM

Ответ №1:

На самом деле вам не следует сохранять данные изображения в CoreData или UserDefaults (последний представляет собой просто файл .plist), поскольку изображения, как правило, имеют большой размер файла.

Вам было бы лучше сохранить String(?) значения для изображения, скажем, как необязательные imageUrlString , и иметь необязательное вычисленное var imageUrl: URL? из него. Затем изображение может быть извлечено при загрузке приложения или при необходимости (например, с помощью PINRemoteImage [страницы github]).

Ниже приведен UserDefaults пример, когда у вас есть только один, но вы могли бы сохранить словарь Dream компонентов (или использовать что-то вроде Realm [docs] или CoreData [docs] для хранения более полных Dream экземпляров)

 import Foundation
import UIKit
import PINRemoteImage

class Dream {
    var imageUrlString: String?
    var name: String?
    var timeStampString: String = ""

    init(fromUserDefaults: Bool) {
        if fromUserDefaults {
            self.imageUrlString = StorageService.instance.imageUrlString
            self.name = StorageService.instance.nameString
            self.timeStampString = StorageService.instance.timeStampString
        }
    }
}

extension Dream {
    var imageUrl: URL? {
        guard let imageUrlString = imageUrlString else { return nil }
        return URL(string: imageUrlString)
    }

    var timeStamp: Date? {
        //Insert logic here to return a date in the desired format, from the timeStampString - e.g.
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX") //For example
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" //For example

        guard let dateFromString = formatter.date(from: timeStampString) else { return nil }
        return dateFromString
    }
}

//Create a singleton to handle access to userDefaults safely

class StorageService {
    //MARK: Singleton
    static let instance = StorageService()

    //MARK: Private initialiser
    private init() {}

    private enum UserDefaultsKeys: String {
        case imageUrlString
        case nameString
        case timeStampString
    }

    var imageUrlString: String? {
        get {
            return UserDefaults.standard.string(forKey: UserDefaultsKeys.imageUrlString.rawValue) ?? nil
        }
        set {
            UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.imageUrlString.rawValue)
        }
    }

    var nameString: String? {
        get {
            return UserDefaults.standard.string(forKey: UserDefaultsKeys.nameString.rawValue) ?? nil
        }
        set {
            UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.nameString.rawValue)
        }
    }

    var timeStampString: String {
        get {
            return UserDefaults.standard.string(forKey: UserDefaultsKeys.timeStampString.rawValue) ?? ""
        }
        set {
            UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.timeStampString.rawValue)
        }
    }

}
  

Затем вы можете использовать pin_setImage (или что-то еще) для загрузки изображения из экземпляра dream везде, где это требуется, например:

 var imageView: UIImageView = {
    let img = UIImageView()
    img.pin_setImage(from: yourDreamInstance.imageUrl)
    return img
}()
  

Комментарии:

1. Я не понимаю, как я могу связать свою функцию сохранения с этим кодом?

2.Ну, ваша кнопка сохранения не присутствовала в вашем первоначальном вопросе, когда я задавал этот ответ. В этом случае вы бы сохранили состояние в StorageService следующим образом: StorageService.instance.timeStampString = date(converted to string) StorageService.instance.nameString = nameTextField.text StorageService.instance.imageUrlString = (whatever you defined the url to the image, as a string)

3. моя ошибка. Можете ли вы добавить конкретный пример, касающийся моего cod?