如何处理从空持久性存储中获取聚合数据时抛出的NSInvalidArgumentException

时间:2016-11-12 15:49:54

标签: core-data swift3

我正在尝试获取按给定列分组的数据。我有数据时效果很好。我想在没有数据的情况下处理这种情况,因为它引发了一个我无法在快速执行catch块中捕获的NS错误。我已经看到了创建ObjC包装器的答案,但我不适用于我的情况,因为我需要返回一个String数组。

let request = self.fetchRequest()
request.propertiesToGroupBy = [attribute]
request.propertiesToFetch = [attribute]
request.resultType = NSFetchRequestResultType.dictionaryResultType
request.returnsDistinctResults = true

if let results = try? context().fetch(request), // raises exception in testing, but runs fine when run on simulator.
  let dics = results as? [NSDictionary] {
  var resultsArray: [Any] = []
  for dic in dics {
    if let propValue = dic[attribute] {
      resultsArray.append(propValue)
    }
  }
  return resultsArray
}

我该怎么做?

2 个答案:

答案 0 :(得分:0)

建议在do - catch块中包装Core Data提取行始终,因为成功时它会可靠地返回指定返回类型的非可选数组。

斯威夫特有一个强大的类型系统。转换为未指定的Any或基础类型NSDictionary对编译器没有帮助,并且可能导致不必要的编译器错误。

假设字典的键和值都是String,则将字典强制转换为Swift类型[String:String]。强制解包字典是绝对安全的,因为在运行时无法更改Core Data模型。

flatMap返回非nil的所有值的非可选数组。

var resultsArray = [String]()
do {
   let results = try context().fetch(request) as! [[String:String]]
   resultsArray = results.flatMap {$0[attribute] as? String}       
} catch {
   print(error)
}
return resultsArray

答案 1 :(得分:0)

基于此answer

我不能立刻明白它可以这样做:

let request = self.fetchRequest()

request.propertiesToGroupBy = [attribute]
request.propertiesToFetch = [attribute]
request.resultType = NSFetchRequestResultType.dictionaryResultType
request.returnsDistinctResults = true


var result: [Any] = []
do {
  try ObjC.catchException {
    let results = try? context().fetch(request)
    if let dics = results as? [NSDictionary] {
      var resultsArray: [Any] = []
      for dic in dics {
        if let propValue = dic[attribute] {
          resultsArray.append(propValue)
        }
      }
      result = resultsArray
    }
  }
} catch {}
return result

理想情况下,我希望ObjC.catchException返回数组,遗憾的是我还没有完全掌握ObjC。 result var的范围看起来太宽,我欢迎任何改进它的建议。

我想尽快保持一切顺利,但我想我现在仍然坚持这个解决方案。