Do you need help on a specific subject? Use the contact form (Request a blog entry) on the right hand side.

2016-07-29

VJson release v0.9.9 | A Single Class JSON Hierarchy in Swift

Old

I have released a new version of VJson, a JSON hierarchy that can be used to create and parse JSON code.

Yet another JSON parser? Yes.

For some reasons I needed to own the sources that could be used to create JSON code and to parse JSON code. A simple way to achieve this is to write your own...

It also has the advantage that I get to decide how the interface looks. And that is quite important to me. Usage should be easy. And I believe I have achieved just that. I have not studied other implementations, and I am sure there are (many?) similar solutions "out there".

So how easy is it?

... Read more about it in my pervious post for the 0.9.8 release here.

New

In this release (0.9.9) I have added a static function to create a VJson hierarchy using Apple's parser: NSJSONSerialization.

Apple's parse is faster than the build-in parser functions so far. To me it seems about twice as fast.

But before you decide to switch to Apple's parser there is a catch, two in fact:

First: Apple's parser reads JSON BOOL items as instances of NSNumber. This has the drawback of being unable to verify if a certain JSON item is in fact a bool or an integer (with value 0 or 1). This also causes a symmetry break. This is more an academic argument, but I like my read/write code to be symmetrical: i.e. reading JSON code and then converting the resulting hierarchy to text again should create exactly the same text as the original code. With Apple's parser this is not possible without additional (and rather complicated) code.

Second: Apple's parser cannot process JSON code that contains for a single object two name/value pairs with identical names. This is probably no real biggy, but it can be quite inconvenient if the JSON code you receive uses this feature.

While I do have some vague plan for speed improvements of the VJson native parser, for now you should use Apple's parser if time is an issue and the two drawbacks do not prevent its usage. Otherwise, stick with the native parser functions.

The VJson parser/hierarchy can be downloaded from Github.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2016-07-20

Drawing a vertical String | A Swift example using NSAffineTransform

I found the String drawing options out-of-the box a little unsatisfying. I don't need much, but even "not much" necessitates much more in-depth knowledge than I would have hoped for.

Case in point: Drawing a string vertically.

Drawing a String in Cocoa is not that difficult, though it is necessary to map the String onto a NSString:

        (str as NSString).drawAtPoint(NSPoint(x: x, y: y), withAttributes: nil)

Specifying nil for the attributes means that the default attributes will be used. Which is sufficient in most cases.

The NSPoint uses double values for x and y, where (0, 0) is the lower left corner of the view. (Unless "flipped" is overridden to return 'true', then (0, 0) is the upper left corner. "Flipped" also affects the operation of NSAffineTransform, thus the rest of this blog assumes a non-flipped view)

To rotate the string we need to specify a transformation. That is where NSAffineTransform comes in.
For the non-flipped view, a positive rotation is counter-clockwise.

I.e. to achieve this:




we have to specify a rotation of 90 degrees.

Since I have to do this more than once, I wrote a little function for this:

class MyView: NSView {

    static let rotateVertically: NSAffineTransform = {
        let trans = NSAffineTransform()
        trans.rotateByDegrees(90)
        return trans
    }()
    
    private func drawVerticalString(str: String, x: CGFloat, y: CGFloat) {
        let context = NSGraphicsContext.currentContext()!.CGContext
        CGContextSaveGState(context)
        let strRect = (str as NSString).boundingRectWithSize(NSSize(width: frame.height, height: frame.height), options: NSStringDrawingOptions.TruncatesLastVisibleLine, attributes: nil, context: nil)
        let nx = y
        let ny = -x - (strRect.size.height / 2)
        MyView.rotateVertically.concat()
        (str as NSString).drawAtPoint(NSPoint(x: nx, y: ny), withAttributes: nil)
        CGContextRestoreGState(context)

    }

I created a static transformation for this, as I will need that again and again. I do not know how much overhead creating a transformation incurs, so that may be unnecessary.

There are three things to keep in mind for the above implementation:

1) The transformation changes the graphics context permanently (at least for the duration of the "drawRect" call). Hence the operation needs to "push" and "pop" the graphic context so as not to affect other drawing operations that might come after.

2) We must apply a reverse transformation on the coordinates before calling the drawing operation itself. That way the drawing ends up in the proper place. It is of course also possible to do that transformation by using the translate operation of the NSAffineTransform object. However that would mean that the transformation would need to be different for each invocation which kind-of messes with the static definition. But your milage may differ.

3) The "- (strRect.size.height / 2)" was added to let the string rotate around the middle of the "height" (which becomes the "width" afterwards). This is because I calculate the mid-point for the string, not its corner point. Again, your milage may differ.

PS: In Swift 3 the context operations will become much more readable... the principles should remain the same though.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2016-07-16

NSDate, NSTimeInterval, UNIX time and Java Date | Timestamps in OS-X

Back in 1970 things were simple; hardly any computers around...
Then time started... computers arrived.
Computers, being what they are, need time...
And so the troubles started.

First there was UNIX Time. It was measured in seconds, and started in the year zero: 1 Jan 1970.
Since you can store a lot in 32 bit, and since memory was expensive, there was a consensus that 32 would be more than enough to store all the seconds you need.
Turns out, they were wrong.

So here we are today, with a baffling array of solutions. Since this blog is about Swift, its about MacOS (Unix) and iOS. Even so, we still need to interact with the world at large, so the most common time formats are still of interest.

The following are the most common:

NSDate: An internal representation of a moment in time, used in MacOS, iOS, tvOS and watchOS.

NSTimeInterval: A double value that is used to express the time elapsed between two moments in time. Commonly used to store the time between 1 Jan 1970 and another moment. It thus can be confused with Unix Time and Java Date.

Unix Time: Started out as a 32 unsigned integer that represents the number of seconds since 1 Jan 1970. Today all modern Unixes use a 64 bit unsigned integer. Due to the large size, it can safely be used (converted into) a singed integer 64 for just about all cases. This will fail sometime in the future, but I have not even bothered to calculate how far in the the future that is (probably after the sun stops shining...).

Java Date: This too measures the time since 1 Jan 1970, but counts in milli-seconds. It is thus 1000 x as large as the Unix Time. Still, it can be safely encapsulated in a signed 64 bit integer for most practical purposes.

Personally, I find it a bit disappointing that NSTimeInterval uses a double. I would have preferred an integer, 64 bit of course. While I can understand why Apple has done this it also makes comparing on equality difficult. (Remember: never compare a double (or float) on equality!). And though modern processors will do a pretty quick job on double compare, an integer compare is often faster.

If we have to exchange time information between applications and computers, the question is which representation do we use?

Simply defaulting to the standard of the system at hand can easily be the wrong answer. I would suggest to make a conscious choice. That could save a lot of hassle later on. (It's usually not a good day when you find out that you have to refactor all of your code -and tests- because you need to interface with another party that uses a different system...). Having said this, the safest choice is IMO the Java Date. It won't always be the right choice, but if offers a resolution that is high enough in most cases (when you need nano-second resolution, do a google on "timespec") and can be represented in a 64 bit integer.

In Swift it makes sense to create an extension for this. And while we are at it, we can include the conversions for the Unix time as well:

extension NSDate {
       

    /// Milli seconds since 1 Jan 1970
    
    var javaDate: Int64 {
        return Int64(self.timeIntervalSince1970 * 1000)
    }
    
    
    /// Seconds since 1 Jan 1970
    
    var unixTime: Int64 {
        return Int64(self.timeIntervalSince1970)
    }
    
    
    /// From milli seconds since 1 Jan 1970
    
    static func fromJavaDate(value: Int64) -> NSDate {
        return NSDate(timeIntervalSince1970: Double(value / 1000))
    }
    
    
    /// From seconds since 1 Jan 1970
    
    static func fromUnixTime(value: Int64) -> NSDate {
        return NSDate(timeIntervalSince1970: Double(value))
    }
}

Happy coding...
Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2016-07-12

VJson release v0.9.8 | A Single Class JSON Hierarchy in Swift

I have released a new version of VJson, a JSON hierarchy that can be used to create and parse JSON code.

Yet another JSON parser? Yes.

For some reasons I needed to own the sources that could be used to create JSON code and to parse JSON code. A simple way to achieve this is to write your own...

It also has the advantage that I get to decide how the interface looks. And that is quite important to me. Usage should be easy. And I believe I have achieved just that. I have not studied other implementations, and I am sure there are (many?) similar solutions "out there".

So how easy is it?

For starters, it consists of a single class: VJson. Of course a VJson object can contain other VJson objects. And then, wel, there is parsing:

let json = try VJson.parse(sourceData)

Where source-data can be a String, a (file)URL, NSMutableData or a buffer. Sometimes with additional parameters. There is of course also a non-throwing alternative (with an extra parameter).

Then there is creation of JSON code:

let json = VJson()
print(json.description) // Prints "{}", i.e an empty JSON code.

Adding values to the JSON hierarchy:

json["Test"] &= true   // Code = {"Test":true}
json["Another"] &= 13  // Code = {"Test":true,"Another":13}

Note that the subscript accessor actually creates the JSON code parts that are needed to fulfil the whole request. Thus it is possible to create a fully formed JSON hierarchy in two lines:

let json = VJson()
json["Books"][2]["available"] &= true

Creates the JSON code {"Books":[null,null,{"available":true}]}
Notice how two "null" items have been automatically inserted to fulfil the array subscript accessor.

Having the subscript accessors create the items as necessary makes them impossible to use for testing of items if you do not want to change the JSON hierarchy for non-existing items. For that purpose the UNIX pipe symbol is used:

To test if book number 23 exists:

if json|"Books"|23 != nil { ... }

Or in a guard statement:

guard let title = (json|"Books"|23|"title")?.stringValue else { ... }

Iteration is also possible:

for item in json {...}

This will iterate the children of OBJECT and ARRAY JSON items.

The "name" (i.e. the tag in a JSON OBJECT used to identify a child item) is available as the "nameValue" of an item. Thus when iterating an OBJECT the name can be read by:


for item in json {
    let name = item.nameValue
}

Items contained in an array may have a name as well, however these names will not be part of the generated code.

VJson uses 'null' as a substitute for 'nil'. Assigning an optional to an item will generate the value 'null' if that optional is nil. Example:


let json = VJson()
var title: String?
json["Title"] &= title // Code = {"Title":null}

It is often possible to convert values. I.e. you could read a number as a string, or certain strings as booleans. For those situations VJson offers the "as...." accessors.

let json = try VJson.parse("{\"label\":true}")
let labelIsTrue = (json|"label")?.asBool

And lastly, how to chain a complex type into generating a representative JSON code:

class Inner {
    var a: Int?
    var json: VJson {
        let j = VJson()
        j["A"] &= a
        return j
    }
}

class Outer {
    var b = Inner()
    var c: String?
    var json: VJson {
        let j = VJson()
        j["C"] &= c
        j.add(b.json, forName: "B")
        return j
    }
}

let k = Outer()

print(k.json)

This is the way I do it, but other ways are possible of course. In defence of the present method: It keeps information where it should be (I.e. the name of the Inner item is part of the Outer item) and creates a clear distinction between local properties that do not have an internal structure and properties that have a bested structure.
You can download VJson from Github.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.