This is a basic Attendance app that captures TimeIn/TimeOut and saves to CoreData. Im trying to find the best approach to sync my CoreData values to a remote SQL Server. I need it to sync a small dataset at the end of each day filtered from today's date. I tried the following class, but Im really new at this. Any help would be appreciated.
These are my issues:
- First, Im not really sure if this is the best approach to sync the data
- I can't figure out how to apply a predicate in the @FetchRequest to filter CoreData for only today's values (date - datday is a String) - getting the following error: Cannot use instance member 'datDay' within property initializer; property initializers run before 'self' is available
My class code:
import Foundation
import SwiftUI
class CODataModel: ObservableObject {
@Published var entries = [COData]()
@Published var authenticated = ""
@AppStorage(CurrentUserDefaults.tzone) var currentTzone: String?
let dateFormatter = DateFormatter()
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Attendances.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Attendances.dateStamp, ascending: true)], predicate: NSPredicate(format: "datday = %@", datDay(dt: Date())))
private var attendance: FetchedResults<Attendances>
func uploadCoreData() {
attendance.forEach { (attendance) in
let uid = attendance.uid
let lat = attendance.lat
let lon = attendance.lon
let placemark = attendance.placemark
let timein = attendance.time_in
let timeout = attendance.time_out
let datday = attendance.datday
do{
auth(uid: uid!, lat: lat!, lon: lon!, placemark: placemark!, time_in: timein!, time_out: timeout!, datday: datday!)
}
}
}
func auth(uid: String, lat: String, lon: String, placemark: String, time_in: String, time_out: String, datday: String) {
let uid: String = uid
let lat: String = lat
let lon: String = lon
let placemark: String = placemark
let time_in: String = time_in
let time_out: String = time_out
let datday: String = datday
let cid: UUID = UUID()
let repTimeIn: String = time_in.replacingOccurrences(of: " ", with: "+")
let repTimeOut: String = time_out.replacingOccurrences(of: " ", with: "+")
let repPlacemark: String = placemark.replacingOccurrences(of: " ", with: "+")
guard let url = URL(string: "\(AppDefaults.endpoint_url)?uid=\(uid)&lat=\(lat)&lon=\(lon)&placemark=\(repPlacemark)&timein=\(repTimeIn)&timeout=\(repTimeOut)&datday=\(datday)&cid=\(cid)") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data=data else{return}
let transData=try! JSONDecoder().decode(COData.self, from: data)
DispatchQueue.main.async {
self.entries = [transData]
self.authenticated = transData.auth
if transData.auth == "0001" {
}
}
}.resume()
}
func datDay(dt: Date) -> String {
self.dateFormatter.timeZone = TimeZone(identifier: currentTzone!)
self.dateFormatter.dateFormat = "MM/dd/yyyy"
let dte = dateFormatter.string(from: dt)
return dte
}
}
A lot of what makes a sync system good or bad depends on how the server you're using works, what it expects and requires. It also depends heavily on what you're trying to accomplish. There's no single answer-- different strategies apply for different apps and server APIs.
Your
uploadCoreData()function appears to take a collection ofAttendancesobjects and send their data to a server. That's fine if that's all you want to do. I'll assume that your upload code inauth(...)is correct because I have no way to know how your server works.Some things your code does not address that are probably important:
datdayfield. I don't know how you use that field, but you may want to make sure it matches up with the data the server has or needs. A date can be a good way to decide what to upload but if the date isn't right then you might accidentally miss uploading some data or else upload data multiple times. Is that important? Again, it depends on your server and your app's specific needs.dataTaskcompletion closure, it's hard to tell.A couple of other general notes:
auth()function, that first group ofletstatements are unnecessary. All those variables were passed in as arguments, you don't need to make new variables for them.I'm not sure what to make of the error message about
datDay. It would help if you could indicate the specific line of code where that shows up.