Note: Source code (RemoteJSON) available on Github

Loading something remotely is a pretty simple task in Flash. We can use the URLStream or URLLoader object, a URL is wrapped inside a URLRequest object, we call the load() API and we are done.

So I was wondering what it looks like in Swift and specifically loading a JSON file, which is a common thing to do today, so here is a little snippet for that.

First, we use the NSURLRequest (not that different right?) object to specify our remote URL:

// this is our remote end point (similar to URLRequest in AS3)
let request = NSURLRequest(URL: NSURL(string: "http://bytearray.org/wp-content/projects/json/colors.json"))

Now, we need to use that object to connect over there, this is where the NSURLConnection comes into play, think of it as the equivalent of the URLStream object:

// this is what creates the connection and dispatches the varios events to track progression, etc.
let loader = NSURLConnection(request: request, delegate: self, startImmediately: true)

As a first parameter, we pass our NSURLRequest object, then we pass our current class as a delegate hander, and we ask that the request starts immediately. We could have passed on that, and call the NSURLConnection.start() API later.

Our data is now coming in, and we need to save it. With URLStream, the data would be gathered internally and stored, and calls to the URLRequest object directly would let you read the data, just like you would do with a Socket connection. In Cocoa with Swift, it is a little bit different, we need to create our buffer to store the data, then through the progress event, write the bytes to it:

func connection(connection: NSURLConnection!, didReceiveData conData: NSData!) {
self.bytes?.appendData(conData)
}

We are using the optional operator cause we are initializing our property later on, when we receive the first response from the server:

func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
self.bytes = NSMutableData()
}

When data is done loading, we can parse it:

func connectionDidFinishLoading(connection: NSURLConnection!) {

// we serialize our bytes back to the original JSON structure
let jsonResult: Dictionary = NSJSONSerialization.JSONObjectWithData(self.bytes, options: NSJSONReadingOptions.MutableContainers, error: nil) as Dictionary<String, AnyObject>

// we grab the colorsArray element
let results: NSArray = jsonResult["colorsArray"] as NSArray

// we iterate over each element of the colorsArray array
for item in results {
// we convert each key to a String
var name: String = item["colorName"] as String
var color: String = item["hexValue"] as String
println("\(name): \(color)")
}
}

Note that we are casting our result to a Dictionary that we can query later on to extract our colorsArray key. This code above gives us in the following output:

red: #f00
green: #0f0
blue: #00f
cyan: #0ff
magenta: #f0f
yellow: #ff0
black: #000

Note that we did not specify listeners to the various callbacks that are being called during loading and when loading is complete. This is done implicitly when we passed our current instance (self) to the delegate property (when we create the NSURLConnection object). The delegate functions are called because they follow a specific naming convention. Have a look in the final complete code:

import SpriteKit

class GameScene: SKScene {

var bytes: NSMutableData?

override func didMoveToView(view: SKView) {

// this is our remote end point (similar to URLRequest in AS3)
let request = NSURLRequest(URL: NSURL(string: "http://bytearray.org/wp-content/projects/json/colors.json"))

// this is what creates the connection and dispatches the varios events to track progression, etc.
let loader = NSURLConnection(request: request, delegate: self, startImmediately: true)
}

func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
self.bytes = NSMutableData()
}

func connection(connection: NSURLConnection!, didReceiveData conData: NSData!) {
self.bytes?.appendData(conData)
}

func connectionDidFinishLoading(connection: NSURLConnection!) {

// we serialize our bytes back to the original JSON structure
let jsonResult: Dictionary = NSJSONSerialization.JSONObjectWithData(self.bytes, options: NSJSONReadingOptions.MutableContainers, error: nil) as Dictionary<String, AnyObject>

// we grab the colorsArray element
let results: NSArray = jsonResult["colorsArray"] as NSArray

// we iterate over each element of the colorsArray array
for item in results {
// we convert each key to a String
var name: String = item["colorName"] as String
var color: String = item["hexValue"] as String
println("\(name): \(color)")
}
}

override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}

The didReceiveResponse and didReceiveData parameters allow us to specify through the method signature, which method is assigned to each event as a handler. Pretty succinct and efficient. The only exception is the connectionDidFinishLoading handler that needs to use that name, and that’s it, we are done!