Extracting NSManagedObject attribute values from NSOrderedSet - ios

I have an initializer that takes an array of Strings as a parameter. Rather than re-write the class and risk breaking things, I'd prefer to feed the initializer what it wants.
I'm trying to extract NSStrings from NSManagedObjects stored in an NSOrderedSet.
Here's what I've tried:
let soundsToPlay = sequenceToPlay.sounds as NSOrderedSet
for element in soundsToPlay {
// this prints out the object in console
print("\(element)")
// this, doesn't give me accessors for the sound object
// print("\(element.fileName)")
}
I'm missing something basic, but I'm not sure what. How would I enumerate the objects in an NSOrderedSet and extract the value of the attributes for the entities contained within the set?

I would suggest reading the documentation on KVC (Key Value Coding) as you can write this as one line of code:
let filenameArray = soundsToPlay.valueForKey("fileName").array()
The call to valueForKey will return an NSOrderedSet of the string and then you can convert that to an array with a call to array()

I figured it out. I was missing a step:
let soundsToPlay = sequenceToPlay.sounds as NSOrderedSet
for element in soundsToPlay {
// I have to tell the compiler what type of thing my thing is
let whatIWantToAccess = element as! MyObjectINeedAccessorsFor
print("\(whatIWantToAccess.fileName)")
}

Thats probably because compiler thinks that "element" is instance of NSManagedObject and it does not have fileName , try explicit type-casting , something like
for element: YourClass in soundsToPlay

Related

Using CoreData to save array containing dictionaries

I'm trying to use CoreData framework inside an iOS app for the first time and I have some troubles with it.
I have a kind of complex type of array, containing tuples that contains dictionaries:
let DataSet: [( Float, Float, [String : String])] = ...
I created an NSManagedObjectContext and an NSManagedObject, I added the DataSet array to the NSManagedObject, but when I try to save the 1st NSManagedObjectContext, the app is crashing.
That's not happening using normal arrays but only with more complex ones like the one above.
Is there a way to deal with that problem? Do I need to adjust my xcdatamodel?
I would appreciate any help a lot.
First you need to declare 2 separate entities. One for Floats and another for Dictionary.
Then create "One to Many" relation ship between Float entity and Dictionary. It will look like this,
Then you need to convert your tuple into these 2 entities, Like this,
dataSet.forEach{ (member) in
let tuple = Test.(context: mainContext)
tuple.first = member.0
tuple.second = member.1
let dictionary = member.2
dictionary.forEach{ (key, value) in
let dick = Dick.(context: mainContext)
dick.key = key
dick.value = value
tuple.addToContains(dick)
}
}
Finally you need to save the values.
if mainContext.hasChanges {
do {
try mainContext.save()
} catch {
print(\(error))
}
}

Cannot assign value of type NSManagedObject to type 'Journal' (an entity)

I am trying to take a single entity from an array of NSManagedObjects var journals = [NSManagedObject]() and display it on a details page. I currently do that by declaring a variable on the destination controller when a segue is prepared from a didSelectRow action:
let indexPath = tableView.indexPath(for: (sender as! UITableViewCell))
controller.journalToDisplay = journals[indexPath!.row]
In the display controller I don't have much set up yet, just this delaration:
var journalToDisplay: Journal?
which throws the error:
Cannot assign value of type 'NSManagedObject' to type 'Journal?'
Isn't journal just an NSManagedObject anyway in this case? I tried using something like:
var journalToDisplay: NSManagedObject as! Journal
But that doesn't seem to be the right way.
Arrays do not implicitly know the types of the objects contained within them, so the compiler can't assign custom classes without explicitly casting the object you get from indexing the array.
Cast journals[indexPath!.row] to a Journal object so the compiler knows to treat it as such.
Fixed as per #JakeT. 's instructions to explicitly downcast journals[indexPath!.row] to a Journal object,
controller.journalToDisplay = journals[indexPath!.row] as! Journal

How to convert NSArray to Set?

Most of the posts here are on about how to convert a set into an array.But I would like to know if I could convert an array to a set.I have downloaded my array from parse and want to convert it to a set because I want the user to edit their details and the form builder I used needs to accept a set data type only.
This is what I got.The "Subjects" field is an NSArray in Parse.
let subjects = Set(currentuser?.objectForKey("Subjects"))
Basically the syntax is correct, but the compiler (and me too) doesn't know that the object for key Subjects is supposed to be an array. Use optional binding to check at least for an array of NSObject to conform to the requirement that the items in the array are hashable (thanks to dan for pointing that out):
if let userSubjects = currentuser?.objectForKey("Subjects") as? [NSObject] {
let subjects = Set(userSubjects)
}
If the real type of Subjects is more specific than [NSObject] use that instead

When to cast in swift

So this is probably a super simple question, but I have looked and cannot find the answer.
Let's say I have made a class and I fill an NSMutableArray with instances of this class and that is it. I want to use a for in loop to loop through. What is the easiest way to cast so I don't have to everytime I want to call the current instance in the loop?
Here it is shown:
for m in objects {
m.randomVar = "hello"
}
where m is my custom object that has a randomVar as a String and objects is an array of custom objects.
Of course the code above will not execute because xcode assumes m is an [AnyObject?]. Where and how would be the best was to get m in its own class. Let's assume we are changing more than one variable so casting everytime would not be optimal.
Sorry if I am unclear. Thank you
Avoid the problem.
Don't use NSArray/NSMutableArray — just use let/var variables of pure Swift arrays, such as [MyClass].
Or, if your array is coming from Objective-C, in Xcode 7+ you can use the NSArray<MyClass *> * syntax to expose it to Swift as [MyClass] rather than [AnyObject].
Cast the array.
Use objects as! [MyClass] (unsafe) if you are absolutely sure it contains instances of MyClass.
Cast the variable.
for m in objects {
if let m = m as? MyClass { ...
// or
let myobj = m as! MyClass // unsafe
or in Swift 2 (Xcode 7)
for case let m as MyClass in objects {
// this is executed only for objects which are instances of MyClass,
// ignoring other objects in the array.
}

NSMutableArray cast to swift Array of custom type

I'd like to figure out how to specify or cast an NSMutableArray to a swift Array of a custom type. I currently have 2 files:
First file requires an NSMutableArray for its functionality (passed by reference, ability to remove particular objects with indices I don't know)
Second file uses a Swift array (better memory / throwaway array), with a custom type, which I declare using
let newArray: [CustomType]!
I need to pass the NSMutableArray in as a parameter to a function in the second file, which requires a [CustomType]. When simply calling it:
let newVC = UIViewController(array: mutableArray)
it keeps telling me 'CustomType' is not identical to 'AnyObject'. I've tried calling the function using mutableArray as [CustomType], which does not work either. How can I make the swift Array function accept my NSMutableArray?
This works for me:
var swiftArray = NSArray(array:mutableArray) as Array<CustomType>
swiftArray is then a Swift array of objects of CustomType. You can pass the array and iterate over it as you would expect.
What I needed was this:
let newVC = UIViewController(array: mutableArray as AnyObject as [CustomType])

Resources