Cast a NSManagedObject to it's class instance - swift

I am getting stuck, and this makes me crazy. I have a function that returns a NSManagedObject:
let getaccount = AccountModel.getFirst(globals.managedObjectContext)
and I have to cast it into its generated representation Account
I'll do this:
dump("--------------------")
dump(getaccount)
dump("--------------------")
if let acc = getaccount as? Account {
print("OK")
} else {
print("not convertable ")
}
dump("*********************")
And the output FROM MY UNITTEST looks like this:
- --------------------
▿ Ticketstream.Account
▿ Some: Coredataexampleapp.Account #0
▿ super: <Coredataexampleapp.Account: 0x138d85f90> (entity: Account; id: 0x1398a9fe0 <x-coredata://06F96EF3-96A6-4C32-A6A2-F16BCB8318EA/Account/p1> ; data: {
active = 0;
avatar = (
);
config = (
);
createdAt = "2015-07-31 23:34:58 +0000";
displayName = "My Account (1)";
host = localhost;
lastUpdatedDate = "2015-07-31 23:34:58 +0000";
password = nil;
port = 8080;
schema = HTTPS;
username = "";
})
- NSObject: <Coredataexampleapp.Account: 0x138d85f90> (entity: Account; id: 0x1398a9fe0 <x-coredata://06F96EF3-96A6-4C32-A6A2-F16BCB8318EA/Account/p1> ; data: {
active = 0;
avatar = (
);
config = (
);
createdAt = "2015-07-31 23:34:58 +0000";
displayName = "My Account (1)";
host = localhost;
lastUpdatedDate = "2015-07-31 23:34:58 +0000";
password = nil;
port = 8080;
schema = HTTPS;
username = "";
})
- --------------------
not convertable
- *********************
How to cast a NSManagedObject into Account?
I need this, because I can't get the first Account otherwise than:
class func getFirst(context: NSManagedObjectContext) -> NSManagedObject? {
let request = NSFetchRequest(entityName: accountEntityName)
request.fetchLimit = 1
let list: NSArray = try! context.executeFetchRequest(request)
return list.firstObject as? NSManagedObject
}
I've tried this with NSManagedObject, AnyObject and Account... How do i get the first Account the right way?
UPDATE:
In normal running mode: all is fine! I'll get:
- --------------------
OK
- *********************
But not from my tests :-(
Thanks for your help, I am lost.

Select all your project files in turn and look at the File Inspector at right. Make sure all files have the 'Test' project checked in their Target Memberships.

There is no need to include all the normal class files in the test target. You just have to import the main module, and everything works as expected.
#testable import AppName
This is inserted automatically in Xcode 7 beta 4. For the casting issue see this answer.

Related

Swift 3: Iterate through a _NSSingleObjectArrayI

I'm fetching data from a weather API. I'm not sure how to access the description?
"weather": <__NSSingleObjectArrayI 0x608000012910>(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
I tried:
print(weatherDict["weather"]!.description!)
It just gave me this:
(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
How do I properly access the description?
weather contains an array of dictionaries.
description is a key in the first item of the array.
The code unwraps weather safely and checks if the array is not empty:
if let weatherArray = weatherDict["weather"] as? [[String:Any]],
let weather = weatherArray.first {
print(weather["description"]) // the value is an optional.
}

How to create dictionary from JSON

I receive JSON objects that looks like the one below. How can I convert it into a format that is easily handled by Swift 2.1 ? I will receive several of these and have to put them into an array and sort by createdAt.
Optional({
comment = "<null>";
completedAt = "<null>";
createdAt = "2015-11-02 15:01:04 +0000";
paid = 1;
paidAt = "2015-11-02 15:01:04 +0000";
startedAt = "<null>";
state = request;
type = doctor;
user = KTsCySacEAiz3eDnf;
userdata = {
birthdate = "<null>";
gender = "<null>";
};
})
As in the title you say you expect a Dictionary, you can get one by simply serializate the json and cast it to a Dictionary.
do{
let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
}catch{
print("Something went wrong")
}
Where data is you json content as NSData. If you get a String you can easily convert it
let data = text.dataUsingEncoding(NSUTF8StringEncoding)

Swift Core Data Quirk

Can anyone help me figure out why this code is behaving thusly...
When opening the app for the first time a "User" is created (if it doesn't already exist, which it doesn't the first time) and then the user is saved along with his/her golf "clubs". I get confirmation of the user saved and the clubs saved in the console. HOWEVER, when I close the app and reopen it the user is fetched but the clubs are not. What am I missing here? Let me know if you need/want to see any screen captures beyond this code...
//MARK: Core Data Variables
var user : User!
var userClubs = NSMutableSet()
var currentRound : Round!
var managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
func prepareUser() {
let fetchRequest = NSFetchRequest(entityName: "User")
let sortDescriptor = NSSortDescriptor(key: "createdTime", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
if let fetchResults = self.managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as? [User] {
if fetchResults.count > 0 {
self.user = fetchResults[0]
println("First user: \(self.user!.firstName) \(self.user!.lastName)")
let fetchRequestClubs = NSFetchRequest(entityName: "Club")
if let fetchResults2 = self.managedObjectContext.executeFetchRequest(fetchRequestClubs, error: nil) as? [Club] {
if fetchResults2.count > 0 {
println("test: \(fetchResults2[0].type)")
}
}
} else {
println("No user yet")
var newUser : User = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: self.managedObjectContext) as! User
newUser.createdTime = NSDate()
managedObjectContext.save(nil)
var i = 0
println("before array: clubsArray is \(clubsArray.count) clubs long")
var clubs = NSMutableSet.mutableSetValueForKey("clubs")
for newClub in clubsArray {
var club : Club = NSEntityDescription.insertNewObjectForEntityForName("Club", inManagedObjectContext: self.managedObjectContext) as! Club
club.type = clubsArray[i].type as String
club.estimatedMinYardage = clubsArray[i].minDistance as Int
club.estimatedMaxYardage = clubsArray[i].maxDistance as Int
club.lowerBound = clubsArray[i].lowerBound as Int
club.upperBound = clubsArray[i].upperBound as Int
//userClubs.addObject(club)
managedObjectContext.save(nil)
//club.setValue(newUser, forKey: "user")
println("\(club.type)")
i++
}
//user.setValue(userClubs, forKey: "clubs")
prepareUser()
}
}
}
Here's the console output from the first run:
No user yet
before array: clubsArray is 17 clubs long
Putter
LW
SW
PW
9i
8i
7i
6i
5i
5W
... [the rest of the clubs]
First user: Your Name
test: 7i
And from the second run after closing and reopening the app:
First user: Your Name
Bloody hell. I was trying to set 1 of the 17 instances of the Club class to a value that was less than it's minimum value allowed in the data model. If anyone else is having a similar issue check your min/max and default in addition to what #Tom-Harrington suggested in the comments of the original question. Dunno if Apple could get some kind of warning for this kind of thing into future versions of XCode.

Need help converting (CFPropertyListRef *)nsdictionary to swift

I need a little help converting this
MIDIDeviceRef midiDevice = MIDIGetDevice(i);
NSDictionary *midiProperties;
MIDIObjectGetProperties(midiDevice, (CFPropertyListRef *)&midiProperties, YES);
NSLog(#"Midi properties: %d \n %#", i, midiProperties);
to swift. I have this but I am getting hung up on casting the CFPropertList.
var midiDevice = MIDIGetDevice(index)
let midiProperties = NSDictionary()
MIDIObjectGetProperties(midiDevice, CFPropertyListRef(midiProperties), 1);
println("Midi properties: \(index) \n \(midiProperties)");
Any help would be great.
Thanks
This is the signature for MIDIObjectGetProperties in Swift:
func MIDIObjectGetProperties(obj: MIDIObjectRef, outProperties: UnsafeMutablePointer<Unmanaged<CFPropertyList>?>, deep: Boolean) -> OSStatus
So you need to pass in an UnsafeMutablePointer to a Unmanaged<CFPropertyList>?:
var midiDevice = MIDIGetDevice(0)
var unmanagedProperties: Unmanaged<CFPropertyList>?
MIDIObjectGetProperties(midiDevice, &unmanagedProperties, 1)
Now you have your properties, but they're in an unmanaged variable -- you can use the takeUnretainedValue() method to get them out, and then cast the resulting CFPropertyList to an NSDictionary:
if let midiProperties: CFPropertyList = unmanagedProperties?.takeUnretainedValue() {
let midiDictionary = midiProperties as NSDictionary
println("Midi properties: \(index) \n \(midiDictionary)");
} else {
println("Couldn't load properties for \(index)")
}
Results:
Midi properties: 0
{
"apple.midirtp.errors" = <>;
driver = "com.apple.AppleMIDIRTPDriver";
entities = (
);
image = "/Library/Audio/MIDI Drivers/AppleMIDIRTPDriver.plugin/Contents/Resources/RTPDriverIcon.tiff";
manufacturer = "";
model = "";
name = Network;
offline = 0;
scheduleAheadMuSec = 50000;
uniqueID = 442847711;
}

Multidimensional array makes Xcode6 crash

I have an application which retrieves a JSON file. Here you are a piece of my code:
Array definition
var photos: NSArray = []
How I populate the array:
ezJson().createRequest("http://myapiurl/load", type: "GET", params: nil, completion: {(returnedObject : AnyObject?, error : NSError?)in
if returnedObject{
self.photos = returnedObject as NSArray
self.tableView.reloadData()
}
})
println(self.photos)
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
},
{
created = {
date = "2014-06-13 18:38:38";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description2;
id = 4;
name = 539b290ed8577;
}
println(self.photos[0])
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
}
The problem is, I don't know how to get a particular item. I've tried:
println(self.photos[0]) // it works
println(self.photos[0]["name"] // Xcode crash "Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254"
println(self.photos[0].name) // returns nil
How can I access to the name parameter ?
It seems that you are casting a String to NSArray. This won't give you the effect that you want.
First of all, if you want to acces your elements by name, you want an NSDictionary.
Then it propably still won't work, as there is no implicit conversion between the types so you will have to either parse it yourself or use some JSON library.
Last : your JSON is incorrect.