从 Swift Core Data 中的一对多关系中获取对象

Getting objects from to-many relationship in Swift Core Data

我在核心数据中与Swift一起使用多对多关系时遇到了一些困难。

我的数据模型

我想做的是使用 Country 的实例,然后显示属于该国家/地区的所有 Contacts 公民。因为我一直在尝试这样做,所以我构建了一个 UITableViewController 来显示该国的所有公民。然而,我在从关系 citizensOfCountry 中获取实际 Contacts 方面遇到了重大问题。这是我正在使用的代码(仅相关部分)。

class ShowingCitizensOfCountry: UITableViewController {

     var countryToShow: Country?
     //This is a value that is passed by a prepareForSegue method
     override func viewDidLoad() {
          //how do I get a list/set/other iterable object of Contacts?

          //***Line in question***
          let listOfPeople = countryToShow!.citizensOfCountry

          for citizen in listOfPeople {
              println(citizen)//THIS IS NOT WORKING
          }

     }

所以,这根本不起作用。现在在 for 循环中我得到一个编译器错误 Type 'Contacts' does not conform to protocol 'Sequence Type'。我不明白的是,它只是联系人类型...我认为这将是某种集合。所以,那没有用,所以我尝试了这个。

let listOfPeople = countryToShow!.citizensOfCountry as! [Contacts]

这也不起作用,我收到错误 'NSArray' is not a subtype of 'Contacts'。接下来我尝试使用 NSSet 进行转换。

let listOfPeople = countryToShow!.citizensOfCountry as! NSSet<Contacts>

不幸的是,这也不起作用,我收到警告 Cast from 'Contacts' to unrelated type 'NSSet' always failsCannot specialize non-generic type 'NSSet'。接下来我尝试了别的东西。我尝试使用 valueForKey 方法。

let listOfPeople = countryToShow!.citizensOfCountry.valueForKey("name") as! Set<String>

这行得通!我可以打印出该国所有公民的名字。但是我不明白为什么。为什么当我使用 valueForKey("name") 时它有效但我无法获得个人联系人?有没有更好的方法来做到这一点,我只是错过了?非常感谢任何关于为什么我无法从单个 Country 中获得 Contacts 集合的解释。谢谢。

您的错误的原因是一对多关系导致 NSSet。您对这些集合进行迭代的所有尝试都应考虑到这一点。

更好的方法是实现 NSFetchResultsController,这是在 table 视图中显示核心数据的标准方式。

  • 在 FRC 中,找人
  • 根据需要对 FRC 进行排序
  • 给它一个过滤 countryToShow
  • 的谓词

FRC 实现:

var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {
        return _fetchedResultsController!
    }

    let fetchRequest = NSFetchRequest(entityName: "Contact")
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
    fetchRequest.predicate = NSPredicate(format:"countryOfOrigin = %@", self.countryToShow!)
    let aFetchedResultsController = NSFetchedResultsController(
       fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, 
       sectionNameKeyPath: nil, cacheName: nil)
    _fetchedResultsController = aFetchedResultsController

    var error: NSError? = nil
    if !_fetchedResultsController!.performFetch(&error) {
        NSLog("%@", error!)
    }

    return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil

我把Contacts改成了更合适的单数。

抱歉,因为我真的很累,所以无法阅读所有内容。但是从我读过的内容来看,您想获得一个应该是 NSSet 的国家/地区的公民。要做到这一点,您只需执行以下操作:

let contacts = yourArrayOfCountries.flatMap { 
    [=10=].citizensOfCountry.allObjects as! [Contacts] 
}

根据您的评论:

let contacts = countryToShow!.citizensOfCountry.allObjects as! [Contacts]