swift 如何将CoreData值同步到远程SQL Server

ojsjcaue  于 2023-03-28  发布在  Swift
关注(0)|答案(1)|浏览(120)

这是一个基本的考勤应用程序,捕获TimeIn/TimeOut并保存到CoreData。我试图找到最好的方法来同步我的CoreData值到远程SQL Server。我需要它在每天结束时同步一个小数据集,从今天的日期过滤。我尝试了下面的类,但我真的很新。任何帮助都将不胜感激。
这些是我的问题:
1.首先,我不确定这是否是同步数据的最佳方法
1.我不知道如何在@FetchRequest中应用一个 predicate 来过滤CoreData,只过滤今天的值(date - datday是一个字符串)-得到以下错误:无法在属性初始值设定项内使用示例成员“datDay”;属性初始值设定项在“self”可用之前运行
我的班级代码:

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
    }
}
qxsslcnc

qxsslcnc1#

同步系统的好坏很大程度上取决于您使用的服务器的工作方式,它的期望和要求。它还很大程度上取决于您试图实现的目标。没有单一的答案-不同的应用程序和服务器API适用不同的策略。
您的uploadCoreData()函数似乎接受Attendances对象的集合并将其数据发送到服务器。如果这就是您想要做的,那很好。我假设您在auth(...)中的上传代码是正确的,因为我无法知道您的服务器是如何工作的。
你的代码没有解决的一些事情可能很重要:

  • 这是一个单向传输,从应用程序到服务器。这不是同步,它只是上传。如果你只想上传,那么这是好的,但你说“同步”,所以也许你想要更多。
  • 您通过datday字段过滤来决定上传内容。我不知道您如何使用该字段,但您可能希望确保它与服务器拥有或需要的数据相匹配。日期可能是决定上传内容的好方法,但如果日期不正确,则可能会意外错过上传某些数据或多次上传数据。这重要吗?再次,这取决于您的服务器和应用的特定需求。
  • 你可能想检查上传是否成功,并记录在某个地方,这样你就知道下次要上传什么了。这可能是你在dataTask完成闭包中所做的,很难说。
  • 如果您将此设置为双向同步,则需要某种方法来处理冲突的更改。如果在不同设备上编辑同一对象,您会使用哪些数据?这有时可能很复杂,答案取决于您的应用需要什么。

其他几个一般注意事项:

  • 正如Joakim在评论中提到的,你需要稍微修改一下代码,这样它就不依赖于SwifUI了。这根本不是UI,而且它不在(或者不应该在)View中,所以它不能使用SwiftUI。
  • auth()函数中,第一组let语句是不必要的。所有这些变量都作为参数传入,您不需要为它们创建新变量。

我不确定datDay的错误信息是怎么回事,如果你能指出出现错误的具体代码行,那会很有帮助。

相关问题