12

I am trying to convert NSManagedObject to NSDictionary this is what I tried:

var keys:NSArray = order?.entity.attributesByName.keys
var dict:NSDictionary = order?.dictionaryWithValuesForKeys(keys)

But I get error:

 LazyForwardCollection<MapCollectionView<Dictionary<NSObject,
 AnyObject>, NSObject>>? is not convertible to NSArray.

What am I doing wrong here?

1110
  • 7,829
  • 55
  • 176
  • 334
  • Do you need exactly `NSDictionary` or it's ok if you get swift Dictionary? – Ilia Apr 16 '15 at 07:03
  • I don't know. My goal is to convert that dictionary to JSON string. So if I can do that with dictionary I don't have a problem with that. – 1110 Apr 16 '15 at 07:05

3 Answers3

26

The keys property of a dictionary returns a LazyForwardCollection which has to be converted to a real array.

Another problem is that order is apparently an optional, so it needs to be unwrapped, e.g. with optional binding.

if let theOrder = order {
    let keys = Array(theOrder.entity.attributesByName.keys)
    let dict = theOrder.dictionaryWithValuesForKeys(keys)
} else {
    // order is nil
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • I don't know. I am using swift 1.2. It require from me to add parameter name but second line can't pass: `let keys = Array(arrayLiteral: order?.entity.attributesByName.keys) let dict = order?.dictionaryWithValuesForKeys(keys)` – 1110 Apr 16 '15 at 07:51
  • @1110: I don't have access to Xcode 6.3 currently, so I tested it with 6.2. I did not expect a difference for this code, but that may be wrong. I can check with Xcode 6.3 later. Sorry if that caused confusion. – Martin R Apr 16 '15 at 07:56
  • Yes I copied it but it doesn't work. I don't understand this should be very simple thing :( – 1110 Apr 16 '15 at 08:13
  • @1110: See updated answer (now checked with Xcode 6.3/Swift 1.2). – Martin R Apr 16 '15 at 11:20
  • @MartinR Even though this works, I can't still serialise them to Json, NSJsonSerialization.isValidObject still returns false. Any ideas? Did you get this to work ultimately? – Salman Hasrat Khan Nov 02 '15 at 15:18
0

Instead of getting the objects out of the database as NSManagedObjects, you could set the resultType, on your NSFetchRequest, to DictionaryResultType to have Dictionaries returned when you execute the request.

However, you will not be able to edit values in these dictionaries and have the changes saved in your database. If you just need to read from your database, then that isn't a problem.

ABakerSmith
  • 22,759
  • 9
  • 68
  • 78
0

Not elegant but this should work...

var names = Array<String>()
for attributeName in order?.entity.attributesByName.keys
{
    names.append(attributeName as! String)
}

This is a problem of converting some kind of collection to another, which is never trivial even if internal types are same.

edit : little more swift spirit

var names = map(order?.entity.attributesByName.keys){return $0 as! String}
Romain TAILLANDIER
  • 1,765
  • 10
  • 18