【问题标题】:How to use predicates with fetchRequest in Core Data如何在核心数据中使用带有 fetchRequest 的谓词
【发布时间】:2017-05-29 05:51:43
【问题描述】:

我将联系人标识符从联系人表视图控制器传递到另一个位置表视图控制器。所以我定义了一个委托 ContactSelectionDelegate 并在 Location tableview 控制器中实现方法 userSelectedContact 并获取 contactIdentifierString

我正在搜索数据库以查找 contactIdentifierString 的匹配项并查找另一个属性提供程序名称的值。这涉及搜索整个数据库。通过将谓词分配给上下文 fetchRequest 是否有更快的方法。我认为这样会更快,代码行数更少。

有人可以建议如何在联系 fetchRequest 中使用谓词吗?

ContactTableViewController 代码:

protocol ContactSelectionDelegate{
func userSelectedContact(contactIdentifier:NSString)
}

class ContactTableViewController: UITableViewController {

var delegate:ContactSelectionDelegate? = nil

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if (delegate != nil){
        let contactDict:NSDictionary = allContacts.object(at: indexPath.row) as! NSDictionary
        let identifier = contactDict.object(forKey: "uniqueId")
                   delegate!.userSelectedContact(contactIdentifier: identifier as! NSString)
                  self.navigationController!.popViewController(animated: true)
               }
}

}

LocationTableViewController 代码:

 class LocationTableViewController: UITableViewController, ContactSelectionDelegate, CLLocationManagerDelegate {

var contactIdentifierString:NSString = NSString()

 func userSelectedContact(contactIdentifier: NSString) {
    var fetchedResults: [Contact] = []

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    do {
        fetchedResults = try context.fetch(Contact.fetchRequest())
    }
    catch {
        print ("fetch task failed")
    }
    if fetchedResults.count > 0 {
        for contact in fetchedResults{
            let aContact:Contact = contact
            if (aContact.uniqueId! == contactIdentifierString as String) {
                providerName.text = aContact.providerName
            }
            else {
                continue
            }
        }
    }


}

【问题讨论】:

    标签: ios swift core-data ios10 nsfetchrequest


    【解决方案1】:

    首先摆脱所有NSString 和NSDictionary 的出现。这是斯威夫特!使用 Swift 原生结构 String 和 Dictionary。

    其次,始终将所有好代码放在do - catch块的do范围内。

    CoreData 谓词有一个简单的格式attribute == value,它与aContact.uniqueId! == contactIdentifierString 非常相似:

    var contactIdentifierString = ""
    
    func userSelectedContact(contactIdentifier: String) {
    
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
        do {
            let fetchRequest : NSFetchRequest<Contact> = Contact.fetchRequest()
            fetchRequest.predicate = NSPredicate(format: "uniqueId == %@", contactIdentifier)
            let fetchedResults = try context.fetch(fetchRequest)
            if let aContact = fetchedResults.first {
               providerName.text = aContact.providerName
            }
        }
        catch {
            print ("fetch task failed", error)
        }
    
    }
    

    代码假设有一个NSManagedObject子类Contact包含

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Contact> {
        return NSFetchRequest<Contact>(entityName: "Contact")
    }
    

    【讨论】:

    • 我在此行收到错误联系人:“Ambiguoius 使用 fetchrequest”。让 fetchRequest = Contact.fetchRequest()
    • 将其更改为:让 req:NSFetchRequest = Contact.fetchRequest()。现在我收到错误:使用未声明的类型 NSFetchRequest。看起来我没有 NSManagedObject 子类。所以为我的两个实体生成了 NSManagedObject 子类。我在 Contact+CoreDataProperties.swift 中的联系人实体上收到错误,因为“联系人在此上下文中的类型查找不明确”。可能是自动生成的 NSManagedObject 类。循环错误。你能请吗?解释以及如何解决?
    • 我假设您使用的是 NSManagedObject 子类,因为providerName 是用点符号访问的。子类必须包含方法fetchRequest()。我更新了答案。
    • 是的,它有效。你能解释一下 fetchedResults.first. 是什么吗?我将接受您的解决方案作为答案。但我想如果我接受你可能无法回答我的问题。但我会接受的
    • CoreData 提取总是返回一个数组,并且这种提取请求应该在成功时只返回一个项目。如果数组不为空,if let .... .first 行将获取数组中的第一项(first 返回一个可选项)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多