Skip to content

Instantly share code, notes, and snippets.

@ainame
Created November 7, 2019 01:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ainame/10b953bca71da39904309039bade2545 to your computer and use it in GitHub Desktop.
Save ainame/10b953bca71da39904309039bade2545 to your computer and use it in GitHub Desktop.
NSManagedObjectから任意のモデルに相互にマップしあう定義をプロトコル化するとCoreData Wrapper書くのに捗りそう
import Foundation
import CoreData
protocol NSManagedObjectMappable: NSManagedObject where MapFrom.MapFrom == Self {
associatedtype MapFrom: MappableFromNSManagedObject
static func mappedObject(from object: MapFrom, in context: NSManagedObjectContext) -> Self
}
enum MappingError: Error {
case missingNonOptionalValue(String)
}
protocol MappableFromNSManagedObject where MapFrom.MapFrom == Self {
associatedtype MapFrom: NSManagedObjectMappable
static func mappedObject(from object: MapFrom) throws -> Self
}
extension MappableFromNSManagedObject {
static func mapValue<T>(from object: MapFrom, keyPath: KeyPath<MapFrom, T?>) throws -> T {
guard let value = object[keyPath: keyPath] else {
throw MappingError.missingNonOptionalValue(String(describing: keyPath))
}
return value
}
}
struct Sample {
let string: String
let number: Int
let date: Date
}
extension Sample: MappableFromNSManagedObject {
static func mappedObject(from object: SampleRecord) throws -> Sample {
return Sample(
string: try mapValue(from: object, keyPath: \.string),
number: Int(object.number),
date: try mapValue(from: object, keyPath: \.date)
)
}
}
extension SampleRecord: NSManagedObjectMappable {
static func mappedObject(from object: Sample, in context: NSManagedObjectContext) -> Self {
let entity = Self.init(context: context)
entity.string = object.string
entity.number = Int32(object.number)
entity.date = object.date
return entity
}
}
class StoreService {
private let coreDataStack: CoreDataStack
init(from coreDataStack: CoreDataStack) {
self.coreDataStack = coreDataStack
}
func insert<T: MappableFromNSManagedObject>(_ object: T) throws {
let context = coreDataStack.newBackgroundContext
let entity = T.MapFrom.mappedObject(from: object, in: context)
try context.save()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment