我回到了使用 CoreData 的 SwiftUI 學習課程。我有三個物體:
User // Has many Customers
Customer // Belongs to User and has many PartExchanges
PartExchange // Belongs to customer
當用戶在登錄后首次安裝應用程式時,我會獲取一些要保存的初始資料(以上:客戶、零件交換等...):
struct AuthResponse: Decodable {
let error: String?
let token: String?
let userData: UserObject?
let customers: [Customers]?
struct UserObject: Decodable {
let FirstName: String?
let Surname: String?
let EmailAddress: String?
let UserID: String
}
struct Customers: Decodable {
let FirstName: String?
let Surname: String?
let EmailAddress: String?
let Customer_ID: String
let PartExchanges: [PartExchangeData]?
}
}
// In another file and not inside AuthResponse
struct PartExchangeData: Decodable {
let Registration: String?
let Customer_ID: String?
let PartExchange_ID: String?
let Variant: String?
let Colour: String?
}
AuthResponse 僅在用戶首次登錄或重新安裝應用程式以從我們的 API 獲取初始資料時使用:
// The exact data I have
import SwiftUI
class AuthController {
var emailUsername: String = ""
var password: String = ""
func login() -> Void {
guard let url = URL(string: "http://localhost:4000/api/auth") else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: AnyHashable] = [
"emailUsername": emailUsername,
"password": password
]
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
// Make the request
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let decodedResponse = try?
decoder.decode(AuthResponse.self, from: data) {
DispatchQueue.main.async {
if decodedResponse.error != nil {
// Tell user?
return
}
let userObject = UserModel()
userObject.createUser(authObject: decodedResponse)
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
}
最后,UserModel:
class UserModel: ObservableObject {
private let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
private let viewContext = PersistenceController.shared.container.viewContext
@Published var saved: Bool = false
var firstName: String = ""
var surname: String = ""
var emailAddress: String = ""
var token: String = ""
var userId: String = ""
init() {...}
public func createUser(authObject: AuthResponse) -> Void {
do {
// Create a user on first login
let user = User(context: viewContext)
let customer = Customer(context: viewContext)
let partExchange = PartExchange(context: viewContext)
//let userCustomers: [AuthResponse.Customers]
user.firstName = authObject.userData!.FirstName
user.surname = authObject.userData!.Surname
user.emailAddress = authObject.userData!.EmailAddress
user.token = authObject.token!
user.userId = authObject.userData!.UserID
// Save customers
for cus in authObject.customers! {
customer.firstName = cus.FirstName
customer.surname = cus.Surname
user.addToCustomers(customer)
// save part exchanges
for px in cus.PartExchanges! {
partExchange.registration = px.Registration
partExchange.partExchangeId = px.PartExchange_ID
partExchange.variant = px.Variant
customer.addToPartExchanges(partExchange)
}
}
try viewContext.save()
saved = true
print("ALL SAVED!!")
} catch {
let error = error as NSError
// If any issues, rollback? viewContext.rollback()
fatalError("Could not save user: \(error)")
}
}
public func logOut() {
// Only remove the token....
}
}
我用這種方法遇到的問題是保存時;它正在保存回圈中的最后一個客戶。
Xcode 為 生成了一些擴展User,Customer并且PartExchnage在里面User,我看到了一個函式@NSManaged public func addToCustomers(_ values: NSSet)::
[..]
user.addToCustomers(<what-goes-here>)
我的用戶物體正確保存。客戶只有來自 api 陣列的最后一個資料。如何正確保存有很多客戶的用戶,其中每個客戶都有很多零件交換?
uj5u.com熱心網友回復:
您需要為每個回圈中的每次迭代創建一個新物件,因為創建的每個物件都將作為單獨的專案存盤在 Core Data 中
所以改成createUser這樣
public func createUser(authObject: AuthResponse) -> Void {
do {
let user = User(context: viewContext)
user.firstName = authObject.userData!.FirstName
// more properties ...
for cus in authObject.customers! {
let customer = Customer(context: viewContext)
customer.firstName = cus.FirstName
customer.surname = cus.Surname
user.addToCustomers(customer)
for px in cus.PartExchanges! {
let partExchange = PartExchange(context: viewContext)
partExchange.registration = px.Registration
partExchange.partExchangeId = px.PartExchange_ID
partExchange.variant = px.Variant
customer.addToPartExchanges(partExchange)
}
}
try viewContext.save()
saved = true
print("ALL SAVED!!")
} catch let error = error as NSError {
//Either log the error and return some status or throw it
//FatalError is a bit to much in this situation
fatalError("Could not save user: \(error)")
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/349778.html
