CoreStore icon indicating copy to clipboard operation
CoreStore copied to clipboard

Is it possible to store the array safely?

Open noppefoxwolf opened this issue 4 years ago • 3 comments

I made a FieldCoderType because I want to save an array of NSCoding. Is the following implementation safe? I want to receive feedbacks about this. (I'm a beginner for CoreData.)

import Foundation
import CoreStore

extension FieldCoders {
    public struct NSArray<C: Foundation.NSObject & Foundation.NSCoding>: FieldCoderType {
        public typealias FieldStoredValue = Array<C>

        public static func encodeToStoredData(_ fieldValue: FieldStoredValue?) -> Data? {

            guard let fieldValue = fieldValue else {

                return nil
            }
            return try! NSKeyedArchiver.archivedData(
                withRootObject: fieldValue,
                requiringSecureCoding: self.requiresSecureCoding
            )
        }

        public static func decodeFromStoredData(_ data: Data?) -> FieldStoredValue? {

            guard let data = data else {

                return nil
            }
            return try! NSKeyedUnarchiver.unarchivedObject(
                ofClasses: [Foundation.NSArray.self, FieldStoredValue.Element.self],
                from: data
            ) as? FieldStoredValue
        }

        private static var requiresSecureCoding: Bool {

            switch FieldStoredValue.Element.self {

            case let valueType as NSSecureCoding.Type:
                return valueType.supportsSecureCoding

            default:
                return false
            }
        }
    }
}

noppefoxwolf avatar Oct 23 '21 06:10 noppefoxwolf

No need to implement your own. CoreStore implements FieldCoders.DefaultNSSecureCoding and FieldCoders.DefaultNSCoding for NSArrays, or you can use FieldCoders.Json directly for swift Arrays:

@Field.Coded("values", coder: FieldCoders.Json.self)
var values: [MyCodableType] = []

JohnEstropia avatar Oct 23 '21 14:10 JohnEstropia

DefaultNSSecureCoding looks not supports typed array. How to serialize to element that cannot encode json value?

@Field.Coded("images", coder: FieldCoders.DefaultNSSecureCoding.self)
public var images: [UIImage] = []
Referencing initializer 'init(wrappedValue:_:versionHashModifier:previousVersionKeyPath:coder:customGetter:customSetter:affectedByKeyPaths:)' on 'FieldContainer.Coded' requires that '[UIImage]' conform to 'FieldOptionalType'

noppefoxwolf avatar Oct 24 '21 05:10 noppefoxwolf

Your original code used KeyedArchiver and KeyedUnarchiver, which DefaultNSSecureCoding uses internally so your code wouldn't work either if DefaultNSSecureCoding doesn't. You need to have Codable types to use the built-in coders, otherwise you have to create your own way to convert to and from Data without using KeyedArchiver/Unarchiver.

JohnEstropia avatar Oct 24 '21 07:10 JohnEstropia