Categories
Blog

JSON Deserialization in Swift

Some time ago when Swift was announced there was a big discussion in the iOS development community about JSON deserialisation and the right way to implement it. At the time, I didn’t give it much attention because I was still committed to Objective-C and didn’t have any immediate requirements to use Swift.

Fast forward two years and I’m now mostly programming in Swift and quickly found out the issues around JSON that everyone was talking about two years ago.

The main problems result from the way JSON parsing is done on iOS, the NSJSONSerialization object simply returns an AnyObject for you to handle, and because of Swift is very strictly typed you soon get code that is very verbose and hard to follow.

For example to read the photo URL from a JSON file like this:

[
  {
    "id": 1,
    "name": "Sergio",
    "weight": 70.5,
    "photos": [{
             "url": "http://fake.com/sergio.jpeg",
             "width": 100,
             "height": 200
             }]
  }
]

You will need to write something like this:

do {
    guard let url = NSBundle.mainBundle().URLForResource("sample", withExtension: "json"),
        let JSONData = NSData(contentsOfURL: url),
        let users = try NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions()) as? Array<AnyObject>
        let user = users[0] as? [String: AnyObject],
        let photos = user["photos"] as? Array<AnyObject>,
        let photo = photos[0] as? [String: AnyObject],
        let photoURL = photo["url"]
    else {
        print("Ops... some error")
    }
    print("\(photoURL)")
} catch {
    print(error)
    return
}

While this is improved from early versions of Swift because of the addition of the guard statement and the new error handling, it’s still very verbose and if you need to track errors on the JSON file you need to split all the guard conditions in order to be able to find where things failed.

So I decided to implement my own library to allow less verbose code while reading values from JSON, but without using any custom operators or protocols like other libraries. Another goal was also to make it easy to find any mistakes made on the JSON files.

The end result was a single class called SVEJSONObject were you can write code like this:

    let url = NSBundle.mainBundle().URLForResource("sample", withExtension: "json")!

    do {
        let users = try JSONObject(url: url)
        let photoURL = try users[0]["photos"][0]["url"].string()
    } catch {
        print(error)
        return
    }

SVEJSONObject allows you to have simpler deserialization code by keeping types restricted to what is available in the JSON specification.

It also allows you to chain subscript calls like this:

users[0]["photos"][0]["url"].string()

And it makes error tracking easy by using Swift exception mechanism with a custom ErrorType that shows what went wrong. For example, if for some reason you tried to do this

users[0]["photos"][0]["link"].string()

you will get an JSONValidationError with this message:

Root[0]->photos->[0]: Missing "link" element in dictionary.

You can check the full code and documentation in the project repo in GitHub.

Categories
Blog

Our software must get “a lot” better

Great post from Seth Godin about the issues with “free” software. The examples he provides in the article are good ones but there is a plenty of good companies and individuals out there doing free software that is great, see WordPress, Linux, Slack and many others.

Categories
Blog Code

Logging in Swift

Here is my poor man version of logging for SWIFT

func logPrint(logMessage: Any, _ file: String = __FILE__, _ function: String = __FUNCTION__, line: Int = __LINE__) {
    print("\(file):\(line):0: \(function): \(logMessage)")
}

This method besides printing your message it shows the file name, the line and the function method where the log was made. The file, function and line numbers are extracted using literal expressions.

This makes it easier to find where the log message come from and if you have the KZLinkedConsole plugin installed in Xcode you just need to click on the error message in the console and Xcode will take you there.

For a more advanced logging library I recommend XCGLogger

== Update (2016-01-25) ==

I found out that the print statement doesn’t print to the System Logs, this could be useful in scenarios that you want to see the log message on a user device. So I update my method to use the NSLog function

func logPrint(logMessage: Any, _ file: String = __FILE__, _ function: String = __FUNCTION__, line: Int = __LINE__) {
    NSLog("\(file):\(line):0: \(function): \(logMessage)")
}
Categories
Blog

Apple TV Tech Talks – London

I attended the Apple TV Tech Talks in London this week. They are part of a tour that developers and designers from Apple are doing around world to show the possibilities of the new Apple TV and share some insights on how to design and develop for it. 

The presentations where all very good with a lot of suggestions on how to optimise/improve your app in terms of UI/UX and tech. Even more valuable where the coding and UI/UX workshops where you could present your questions directly to an Apple engineer or designer. You could even get design review from one of the UX experts from Apple.

In conclusion it was great and concise conference about tvOS, in a way I think they are better than the WWDC because they are more focused and a lot less crowded! It was also a great opportunity to connect with London developers community and see some old colleagues. I hope they do them again next year!

  
  

Categories
Blog

WordCamp Edinburgh 2015

I had a great time on WordCamp Edinburgh 2015, met some great people from the local WordPress community and enjoyed some great talks from the other speakers.

Here is the video of my presentation about the WP-REST API

and the slides:

The code for the app  show in the presentation can be found on this GitHub repo.

I also participated on the Roundtable about the future of the REST API:

#wcedin @wcedin

Categories
Blog Portfolio

WordPress iOS App

Role: Core Developer

Client: Automattic

Links: AppStore, GitHub repo

Inspiration strikes — anytime, anywhere. Manage your WordPress blog or website on the go, from your iOS device: view your stats, moderate comments, create and edit posts and pages, and upload media. All you need is a WordPress.com blog or a self-hosted WordPress.org site running 3.6 or higher. With WordPress for iOS, you have the power of publishing in the palm of your hand. Draft a spontaneous haiku on the train. Snap a photo on an afternoon stroll for the week’s photo challenge at The Daily Post. Respond to your latest comments, or monitor your stats to see where today’s readers are coming from.

Categories
Blog Cafe Co-Work

Brew Lab

Great place to co-work in Edinburgh, excellent coffee (they even have cold brew!) great wifi connection, power plugs available all around, good music and excellent food!

The only downside is that it gets very busy so get there soon in day to grab a seat.

 

Categories
Blog

San Francisco Font

Excellent articles from Martian Craft about the new San Francisco font on Apple devices:

A must read for all designers and developers working on the platform.

 

Categories
Blog Meetups

GM 2015

IMG_3168
With Matt and Filipe
IMG_0008
Mobile Workshop
Categories
Blog Code

DVR

I really like DVR approach to networking testing. So much better than mocking.