Swift
Swift_ CoreData Model , extension , Struct
JunsC
2024. 8. 2. 13:47
728x90
코어 데이터 모델과 일반 Struct 과 같이 사용하려고 생각했다.
AOS 에서는 한 모델을 기준으로 Sqlite 도 같은 형변환이 될 수 있도록 치환이 가능했기 때문이다.
그 부분때문에 당연히 IOS 에서도 가능하겠지 하고 계속 시도해보았지만 잘 안됐다. 흠...
enum Gender: String, Codable {
case M = "M"
case F = "F"
case NULL = "NULL"
}
enum CurrentStatus: String, Codable {
case IN = "IN"
case OUT = "OUT"
case NULL = "NULL"
}
enum Time: String, Codable {
case afternoon = "afternoon"
case NULL = "NULL"
case night = "night"
}
enum Grade: String, Codable {
case A = "A"
case B = "B"
case C = "C"
case D = "D"
case E = "E"
case NULL = "NULL"
}
struct MemberStruct: Codable, Comparable {
var clubName: String
var name: String
var gender: Gender
var memberOwnId: String
var currentStatus: CurrentStatus
var age: Int
var grade: Grade
var time: Time
enum CodingKeys: String, CodingKey {
case memberOwnId = "m_Id"
case name
case gender
case currentStatus
case clubName
case grade
case age
case time
}
init(clubName: String = "", name: String = "", gender: Gender = .NULL, memberOwnId: String = "", currentStatus: CurrentStatus = .NULL, age: Int = 0, grade: Grade = .NULL, time: Time = .NULL) {
self.clubName = clubName
self.name = name
self.gender = gender
self.memberOwnId = memberOwnId
self.currentStatus = currentStatus
self.age = age
self.grade = grade
self.time = time
}
init() {
self.clubName = ""
self.name = ""
self.gender = .NULL
self.memberOwnId = ""
self.currentStatus = .NULL
self.age = 0
self.grade = .NULL
self.time = .NULL
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
clubName = try container.decode(String.self, forKey: .clubName)
name = try container.decode(String.self, forKey: .name)
gender = try container.decode(Gender.self, forKey: .gender)
memberOwnId = try container.decode(String.self, forKey: .memberOwnId)
currentStatus = try container.decode(CurrentStatus.self, forKey: .currentStatus)
age = try container.decode(Int.self, forKey: .age)
grade = try container.decodeIfPresent(Grade.self, forKey: .grade) ?? .NULL
time = try container.decode(Time.self, forKey: .time)
}
static func < (lhs: MemberStruct, rhs: MemberStruct) -> Bool {
return lhs.name < rhs.name
}
static func == (lhs: MemberStruct, rhs: MemberStruct) -> Bool {
return lhs.name == rhs.name
}
func toMembers(context: NSManagedObjectContext) -> Members {
let members = Members(context: context)
members.clubName = self.clubName
members.name = self.name
members.gender = self.gender.rawValue
members.memberOwnId = self.memberOwnId
members.currentStatus = self.currentStatus.rawValue
members.age = String(self.age)
members.grade = self.grade.rawValue
members.time = self.time.rawValue
return members
}
}
이 일반적인 Struct 를 하나로 전부 이용하고 싶었지만,
CoreData 에서는 CoreDataProperties.swift 파일은 Core Data의 속성 확장만을 포함해야 해서 일반적으로 이 파일에 메서드 확장보다는 속성 관련 코드만 넣는다고 한다.
따라서, 별도의 extension으로 정의하는 것이 좋다고 하는 ChatGpt 의 말에 따라 하는 수 없이 별도 분리를 하는 수밖에 없었다.
//
// Members+CoreDataProperties.swift
//
//
// Created by macbookpro on 7/24/24.
//
//
import Foundation
import CoreData
extension Members {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Members> {
return NSFetchRequest<Members>(entityName: "Members")
}
@NSManaged public var clubName: String?
@NSManaged public var name: String?
@NSManaged public var gender: String?
@NSManaged public var memberOwnId: String?
@NSManaged public var currentStatus: String?
@NSManaged public var age: String?
@NSManaged public var grade: String?
@NSManaged public var time: String?
func update(from member: MemberStruct) {
self.clubName = member.clubName
self.name = member.name
self.gender = member.gender.rawValue
self.memberOwnId = member.memberOwnId
self.currentStatus = member.currentStatus.rawValue
self.age = String(member.age)
self.grade = member.grade.rawValue
self.time = member.time.rawValue
}
func toMemberStruct() -> MemberStruct? {
guard
let clubName = self.clubName,
let name = self.name,
let gender = self.gender,
let memberOwnId = self.memberOwnId,
let currentStatus = self.currentStatus,
let ageString = self.age,
let age = Int(ageString),
let grade = self.grade,
let time = self.time
else {
return nil
}
return MemberStruct(
clubName: clubName,
name: name,
gender: Gender(rawValue: gender) ?? .NULL,
memberOwnId: memberOwnId,
currentStatus: CurrentStatus(rawValue: currentStatus) ?? .NULL,
age: age,
grade: Grade(rawValue: grade) ?? .NULL,
time: Time(rawValue: time) ?? .NULL
)
}
override public var description: String {
return """
Member{
clubName: \(String(describing: clubName)),
name: \(String(describing: name)),
gender: \(String(describing: gender)),
memberOwnId: \(String(describing: memberOwnId)),
currentStatus: \(String(describing: currentStatus)),
age: \(String(describing: age)),
grade: \(String(describing: grade)),
time: \(String(describing: time))
}
"""
}
}
위의 코드는 이제 잘못된 코드이다..
저런 부가적인 함수들은 따로 extension 파일을 만들어 정리하도록 해야겠다.
그렇다면 내가 이해한 바로는 ,
코어데이터와 일반적인 Struct 는 각 독립적인 모델로 생각해야 하고 서로 상호호환을 하려면 형변환을 해주어야 한다는 의미로 생각되었당
그래서 우선 코어데이터로 저장하는건 코어데이터 모델을 사용하고 그리고 그 데이터를 가져올땐 Struct 로 형변환 후 사용하는 것이 깔끔한듯 하다
AOS IOS 각각의 장단점이 있는 듯 하다..