#ios #swift #swiftui
#iOS #swift #swiftui
Вопрос:
Я использую https://github.com/peek-travel/swift-currency , и иметь идентифицируемую модель, где одним из полей является «var price: USD» (переменная цены типа USD (из библиотеки). Я заметил, что если я хочу использовать coredata, для меня нет типа «USD». Есть ли способ, которым я мог бы использовать этот тип с core data? Или лучше использовать другой (уже готовый) тип для хранения валюты (например, данные в размере $ 5,08 в swiftui / swift?
Независимо от того, что это за тип, что я делал при преобразовании этого типа (скажем, мне нужно добавить 5 долларов к значению «цена») Обычно я делаю: USD (5,08) USD (5). Поэтому кажется, что может быть неудобно постоянно извлекать значение из coredata и переводить его в USD (..) перед выполнением любого преобразования, а затем преобразовывать его обратно в любой тип, поддерживаемый для CoreData. Хотя, если это лучшая практика, я не против.
Комментарии:
1. Вы можете использовать
Transformable type
Ответ №1:
Вы можете поддерживать пользовательские типы. Вам нужен class
, который соответствует NSSecureCoding
и NSObject
Кроме того, вам нужен преобразователь, соответствующий NSSecureUnarchiveFromDataTransformer
Затем в CoreData вы устанавливаете атрибут type
на Transformable
и Transformer
= YourClassTransformer
и Custom Class
= YourClass
@objc(USD)
public class USD: NSObject {
var value: Double
public enum CodingKeys: String, CodingKey {
case value
}
public init(value: Double) {
self.value = value
}
public required init?(coder: NSCoder) {
value = coder.decodeObject(forKey: CodingKeys.value.rawValue) as! Double
}
public override var description: String{
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "en_US")
return formatter.string(from: NSNumber(value: value))!
}
}
extension USD: NSSecureCoding{
public static var supportsSecureCoding: Bool{
return true
}
public func encode(with coder: NSCoder) {
coder.encode(value, forKey: CodingKeys.value.rawValue)
}
}
@objc(USDTransformer)
public final class USDTransformer: NSSecureUnarchiveFromDataTransformer {
public static let name = NSValueTransformerName(rawValue: String(describing: USDTransformer.self))
public override static var allowedTopLevelClasses: [AnyClass] {
return [USD.self]
}
//Register before CoreData setup starts
public static func register() {
let transformer = USDTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
Комментарии:
1. Спасибо за этот ответ. Из чистого любопытства, это… хотя идеально? Или, учитывая мой случай, поскольку я пытаюсь иметь дело с деньгами, я должен просто придерживаться одного из готовых типов?
2. Для a
Double var
и a требуется много работыdescription
, чтобы показать $. На самом деле я собираю код просто для «развлечения», если вы дадите мне немного, я опубликую его.3. Спасибо, так что, хотя это явно возможно … вероятно, лучше придерживаться двойного типа цены для coredata? Спасибо за код, это действительно помогает четко понять, как это можно сделать.
4. Вероятно, мне трудно представить сценарий, в котором работа над сохранением стоила бы того. Это должно быть приложение с большими затратами, которое будет включать другие свойства, такие как конвертеры, уравнения для определения будущей стоимости и т. Д.