Web and application development

Twitter

Just had to resort to browser sniffing. Feature detection failed me - webkitSpeechRecognition available in Opera - just doesn’t work.

Follow me
16thSeptember 2014

JSON and Swift

Posted at 11:50am by Jason in Development

Tags: , ,

JSON encoded content - seriously, no that isn't a real authentication code

At last I have finally gotten around to investigating Swift, the new language from Apple for creating apps for both IOS and OSX.

In common with many people, I’ve decided to dive straight in and access a web based API that expects, and returns, JSON encoded data. So far, so good. As it happens, I have a few projects all set up locally that expose RESTful APIs, so I immediately have something to test against. It’s all going great. Plug in some boilerplate code, and hey presto, my API is successfully handing back some data.

Now, of course, I want to do something with that data – no point otherwise. This is where it all starts getting a bit complicated.

Swift is a statically typed language. This means that the compiler wants to know what the type of everything is at compile time in order to keep it happy and have the code actually compile. That is probably an over simplification, but you probably get the idea. There is a lot of type inference that goes on, so not every variable and constant actually has a type specified, but the complier infers this from the type of the data being assigned. so,
var myKey = "1234asd"
Swift would infer that myKey is of type String as a string literal is assigned during the declaration. The same result would be achieved by
var myKey: String = "1234asd"
This time, the type was explicitly specified, however, because of the ability to infer types, Swift can look a lot like a dynamically typed language. This is where things can get confusing. JSON effectively represents an object or an array with keys and values being of many different types.
{
"ObjectType:"User",
"ID": 1000,
"Enabled": true
"Permissions": [
"UserManagement",
"Reporting"
]
"Manager": true,
"Credit": 123.45,
"Staff": [
{
"ID": 2133,
"Name":"Jason McClean"
},
{
"ID": 2412,
"Name":"Bob Barrington"
}
]
}

The above snippet of JSON is using string keys, but the values are strings, ints, floats, booleans and even an array. A good old mix that you would probably expect to see in any snippet of JSON from any number of APIs. If we don’t necessarily know what types of data are going to be in the JSON, that is where Swift being statically typed can cause a few headaches.

What many tutorials appear to do is process the returned JSON and hand it back in an NSDictionary object. This is an Objective C type that can handle all sorts of different types in the same structure. Ideal you would think, that is until you actually want to get to data that is nested deep in the structure.
// data obtained from the API call
var err: NSError?
var parsedJson = NSJSONSerialization.JSONObjectWithData(data,
options: .MutableLeaves,
error: &err) as? NSDictionary

Now, this is where optionals add to the confusion. We may or may not get a parsed result, so using as? provides some protection here. However, because now you may or may not have data in the variable parsedJson, when we want to access it, we need to take care. Swift has a way of doing this with the let syntax.

So, we want to access the name of the first staff member for which the above manager is responsible. It would be great to go
var name = parsedJson["Staff"][0]["Name"]
However, that isn’t something that appears to be possible. parsedJson may not contain anything, but if it does, we really need to know the structure and expected types, so you may end up with something like
var name = ""
if let staff = parsedJson?["Staff"] as? NSArray {
if let staffMember = staff[0] as? NSDictionary {
name = staffMember["Name"] as String
}
}

For anything remotely complicated, this could get quite convoluted quite quickly. Of course, much clever people than me have already been working solutions to the JSON parsing issue. So, in typical developer fashion, I am not going to try and reinvent the wheel here, I will most likely opt for one of the following solutions/approaches (in no particular order):

Hopefully I’ll end up with something useful.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment