Ios 当CoreData Swift中已存在记录时,函数不返回

Ios 当CoreData Swift中已存在记录时,函数不返回,ios,swift,core-data,Ios,Swift,Core Data,我有一个被firebase.childAdded observer调用的函数,我试图在写入之前检查要写入的记录是否已经在数据库中。这是因为当用户登录时,所有传入的快照都会导致数据库中出现多个条目。 我尝试对记录执行检查的方法是使用。containsbool,如果它没有返回函数,否则它将继续写入新记录,但不起作用,每次登录时它都会添加所有传入的快照。我该怎么做呢?一如既往,非常感谢。 这就是功能: static func saveBooking(bookingId: String, booking

我有一个被firebase.childAdded observer调用的函数,我试图在写入之前检查要写入的记录是否已经在数据库中。这是因为当用户登录时,所有传入的快照都会导致数据库中出现多个条目。 我尝试对记录执行检查的方法是使用
。contains
bool,如果它没有返回函数,否则它将继续写入新记录,但不起作用,每次登录时它都会添加所有传入的快照。我该怎么做呢?一如既往,非常感谢。 这就是功能:

static func saveBooking(bookingId: String, bookingDate: String, bookingStart: String, bookingEnd: String, customerName: String, price: String, workList: String) throws {
        let context = CoreData.databaseContext

        let request: NSFetchRequest<User> = User.fetchRequest()
        do {
            let fetch = try context.fetch(request)
            print("@@@@@@@@@@@@@@@@@@       fetching user")

            for value in fetch {
                if value.name == UserDetails.fullName {
                    print("User is: \(value.name!)")  //correct


                    if #available(iOS 10.0, *) {
                        let booking = Booking(context: context)
                        booking.user?.name = value.name!

                        booking.bookingId = bookingId
                        booking.bookingDate = bookingDate
                        booking.bookingStart = bookingStart
                        booking.bookingEnd = bookingEnd
                        booking.customerName = customerName
                        booking.bookingPrice = price
                        booking.worksList = workList
                        if value.bookings!.contains(booking){
                            print("@@@@@@@@@   found existing record for this booking! ")
                            return

                        } else {
                            value.addToBookings(booking)
                            print("@@@@@@@@@@@@@@@@@@@@@@@@@  booking user at propertis value attribution is : \(String(describing: booking.user!.name!))")
                            do {
                                try context.save()
                                print("@@@@@@@@@@@@@@@@@@@@@@@@@  booking user after saving booking is : \(String(describing: booking.user!.name!))")
                                print("@@@@@@@@@@@@    New booking is saved")
                            } catch  {
                                print("@@@@@@@@@@@@@@    Error saving new booking")
                                print(error)
                            }
                        }

                    } else {
                        // Fallback on earlier versions
                        let entityDescription = NSEntityDescription.entity(forEntityName: "Booking", in: context)
                        let booking = Booking(entity: entityDescription!, insertInto: context)
                        booking.user?.name = value.name
                        booking.bookingId = bookingId
                        booking.bookingDate = bookingDate
                        booking.bookingStart = bookingStart
                        booking.bookingEnd = bookingEnd
                        booking.customerName = customerName
                        booking.bookingPrice = price
                        booking.worksList = workList
                        if value.bookings!.contains(booking) {
                            print("@@@@@@@@@   found existing record for this booking! ")
                            return
                        } else {
                            value.addToBookings(booking)
                            do {
                                try context.save()
                                print("@@@@@@@@@@@@    New booking is saved")
                            } catch  {
                                print("@@@@@@@@@@@@@@    Error saving new booking")
                                print(error)
                            }
                        }
                    }
                }
            }
        } catch  {
            print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      Error in fetching a user")
        }
    }
static func saveBooking(bookingId:String,bookingDate:String,bookingStart:String,bookingEnd:String,customerName:String,price:String,workList:String)抛出{
let context=CoreData.databaseContext
let请求:NSFetchRequest=User.fetchRequest()
做{
let fetch=try context.fetch(请求)
打印(“获取用户”)
获取中的值{
如果value.name==UserDetails.fullName{
打印(“用户是:\(value.name!)”//correct
如果可用(iOS 10.0,*){
让预订=预订(上下文:上下文)
booking.user?.name=value.name!
booking.bookingId=bookingId
booking.bookingDate=bookingDate
booking.bookingStart=bookingStart
booking.bookingEnd=bookingEnd
booking.customerName=客户名称
预订价格
booking.worksList=工作列表
if value.bookings!.contains(预订){
打印(“找到此预订的现有记录!”)
返回
}否则{
value.addToBookings(预订)
打印(“@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
做{
尝试context.save()
打印(“@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
打印(“保存新预订”)
}抓住{
打印(“保存新预订时出错”)
打印(错误)
}
}
}否则{
//对早期版本的回退
让entityDescription=NSEntityDescription.entity(在:上下文中,名为“预订”)
let booking=booking(实体:entityDescription!,插入到:上下文)
booking.user?.name=value.name
booking.bookingId=bookingId
booking.bookingDate=bookingDate
booking.bookingStart=bookingStart
booking.bookingEnd=bookingEnd
booking.customerName=客户名称
预订价格
booking.worksList=工作列表
if value.bookings!.contains(预订){
打印(“找到此预订的现有记录!”)
返回
}否则{
value.addToBookings(预订)
做{
尝试context.save()
打印(“保存新预订”)
}抓住{
打印(“保存新预订时出错”)
打印(错误)
}
}
}
}
}
}抓住{
打印(“获取用户时出错”)
}
}

let booking=booking(context:context)
正在创建一个新的
booking
并将其插入到上下文中。这是经常发生的(就像你的病情之前一样)。这个新创建的
Booking
从来都不是
值的一部分。Booking
集合-(它怎么可能是刚刚创建的!)-所以它总是被添加的

我想你想要的是

if value.bookings!.contains{ $0.bookingId == bookingId) {
    let booking = Booking(context: context)
    value.addToBookings(booking)
    booking.user?.name = value.name!
    ....

最后,我使用
NSFetchRequest
NSPredicate
以更经典的方式检查现有记录,但我想了解如何使用和探索Jon Rose建议的解决方案,这实际上非常有用,因为我没有意识到我正在创建一个新对象。
我希望这能帮助其他人。 因此,函数现在编写为:

static func saveBooking(bookingId: String, bookingDate: String, bookingStart: String, bookingEnd: String, customerName: String, price: String, workList: String) throws {
        let context = CoreData.databaseContext
        let request: NSFetchRequest<User> = User.fetchRequest()
        do {
            let fetch = try context.fetch(request)
            print("@@@@@@@@@@@@@@@@@@       fetching user")
            for userValue in fetch {
                if userValue.name == UserDetails.fullName {
                    print("User is: \(userValue.name!)")  //correct

                    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Booking")
                    let predicate = NSPredicate(format: "bookingId == %@", bookingId)
                    request.predicate = predicate
                    request.fetchLimit = 1

                    do{
                        let count = try context.count(for: request)
                        if(count > 0){
                            //  matching object
                            print("@@@@@@@@@@@@ booking is already recorded")
                            return
                        }
                        else{
                            print("@@@@@@@@@@@@    booking is new")
                            if #available(iOS 10.0, *) {
                                let booking = Booking(context: context)
                                booking.user?.name = userValue.name!
                                booking.bookingId = bookingId
                                booking.bookingDate = bookingDate
                                booking.bookingStart = bookingStart
                                booking.bookingEnd = bookingEnd
                                booking.customerName = customerName
                                booking.bookingPrice = price
                                booking.worksList = workList
                                userValue.addToBookings(booking)
                            } else {
                                // Fallback on earlier versions
                                let entityDescription = NSEntityDescription.entity(forEntityName: "Booking", in: context)
                                let booking = Booking(entity: entityDescription!, insertInto: context)
                                booking.user?.name = userValue.name!
                                booking.bookingId = bookingId
                                booking.bookingDate = bookingDate
                                booking.bookingStart = bookingStart
                                booking.bookingEnd = bookingEnd
                                booking.customerName = customerName
                                booking.bookingPrice = price
                                booking.worksList = workList
                                userValue.addToBookings(booking)

                            }
                        }
                    }
                }
            }

            do {
                try context.save()
                print("@@@@@@@@@@@@    New booking is saved")
            } catch  {
                print("@@@@@@@@@@@@@@    Error saving new booking")
                print(error)
            }
        }
    }
static func saveBooking(bookingId:String,bookingDate:String,bookingStart:String,bookingEnd:String,customerName:String,price:String,workList:String)抛出{
let context=CoreData.databaseContext
let请求:NSFetchRequest=User.fetchRequest()
做{
let fetch=try context.fetch(请求)
打印(“获取用户”)
用于获取中的userValue{
如果userValue.name==UserDetails.fullName{
打印(“用户是:\(userValue.name!)”//correct
let request=NSFetchRequest(entityName:“预订”)
let谓词=NSPredicate(格式:“bookingId==%@”,bookingId)
request.predicate=谓词
request.fetchLimit=1