I'm in the process of trying to migrate an existing project to Swift, its more of a learning exercise but I think I've hit a problem which seems pretty basic and I think it may relate to my lack of understanding of AnyObject.
I've created a object that consists of a number of variables and is initialised as:
var customObject:MycustomObject = MYcustomObject()
I'm then using NSURLConnection to retrieve JSON data and this all appears to be working correctly as the jsonArray is being populated with data
jsonArray = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSArray
I'm then looping through the array and attempting to parse the data and this is where I'm experiencing problems, the for loop defaults details to AnyObject.
for details:AnyObject in jsonArray {
parseDetail(details as NSDictionary)
}
The problem relates to the integerValue, its generating an "Cannot downcast from 'AnyObject' to non-@objc...." error
func parseDetail(element: NSDictionary ) {
self.customObject.stringValue = element["id"] as String
self.customObject.integerValue = element["type"] as Integer
}
There also seems to be some differences in the way NSString & String are working, my understanding so far is that when using Swift I should be using the native types Sting, Float Integer etc etc. If I use NSString the stringValue displays correctly in the debug window but when using the type String I receive the following:
{
core = {
_baseAddress = Builtin.RawPointer = 0x0b227f49
_countAndFlags = 1073741828
_owner = Some {
Some = (instance_type = Builtin.RawPointer = 0x0b227f40 -> 0x006d58f0 (void *)0x006d58c8: __NSCFString)
}
}
}
Sorry this is a little long but is there any info regarding threading, this is my next challenge?
NSThread.detachNewThreadSelector(Selector: parseDetail(), toTarget: self, withObject: nil)
Here's a little example that does the job. First, here's a model class for our purposes:
class CustomObject {
var name: String = ""
var age : Int = 0
init(json: Dictionary<String, AnyObject>) {
name = json["name"] as NSString
age = (json["age" ] as NSNumber).integerValue
}
}
As you can see, we still need to deal with NSNumbers and NSStrings since NSJSONSerialization is not yet updated to the Swift types.
Next, a little json.txt file residing in our project:
[{"name":"Alice","age":30},{"name":"Bob","age":40}]
And last, the parser, right in application launch for a quick test:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
var filePath = NSBundle.mainBundle().pathForResource("json", ofType:"txt")
var data = NSData(contentsOfFile:filePath)
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as Array<Dictionary<String, AnyObject>>
var customObjects = json.map { dict in CustomObject(json: dict) }
println(customObjects[0].name)
println(customObjects[0].age)
return true
}
This will print:
Alice
30
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With