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

2016-08-04

while let | Swift gotcha

Consider the following:

class LinkedList {
    var previous: LinkedList?
    var next: LinkedList?
    var payload: String
    init(previous: LinkedList?, value: String) {
        self.previous = previous
        payload = value
        previous?.next = self
    }
    func walkBack() -> String {
        var str = payload
        let link = self
        while let link = link.previous {
            str = link.payload + str
        }
        return str
    }

}

It should be clear what the intention is of the function walkBack() is: it should concatenate all payloads and return that as a string.

But the function contains an error that might not bite immediately.

For the top level element of the list, the function wil work fine. It simply returns its own payload.

But for the elements that have a previous element the function will go into an endless loop.

Why? that becomes clear when we change the definition of link from a let to a var:


This shows that the value of link never changes. The while loop creates its own instance of link each time it loops. And since the value for that link is derived from the value of the link outside the loop it will loop until the app runs out of memory.

Simply replacing the outside-the-loop definition of link to "outsideLink" clarifies this better:

    func walkBack() -> String {
        var str = payload
        let outsideLink = self
        while let link = outsideLink.previous {
            str = link.payload + str
        }
        return str

    }

Now it is clear that link is never modified to anything else but the previous element of self. In fact we could better write this as:

    func walkBack() -> String {
        var str = payload
        while let link = self.previous {
            str = link.payload + str
        }
        return str
    }

Which of course we would never do since the error is now obvious!

The tricky thing is of course that we (I?) get used to simply accepting the suggestions of the compiler.

Lesson for self: Don't automatically accept the compiler suggestions!

Oh, and btw, the right way to do this is:

    func walkBack() -> String {
        var str = payload
        var link = self.previous
        while link != nil {
            str = link!.payload + str
            link = link!.previous
        }
        return str

    }

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-08-02

Missing "remove" operation on Data in Swift 3 | An Extension for the Data type in Swift 3

It could be me, but is anyone missing the "remove" operation on the "Data" type in Swift 3?

Well, there is an extension for that:

extension Data {

    mutating func removeSubrange(_ range: Range<Int>) {
        var dummy: UInt8 = 0
        let empty = UnsafeBufferPointer<UInt8>(start: &dummy, count: 0)
        self.replaceSubrange(range, with: empty)
    }
}

Example usage:

var buffer = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
let range = Range(uncheckedBounds: (lower: 1, upper: 5))
buffer.removeSubrange(range)

Output: <00050607 0809>

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-08-01

Adopting Swift 3 | GCD and CoreData in Swift 3

2016-08-17: Note that this post covers Xcode 8 beta 3, the current beta 6 is not compatible with the stuff below.

In the past few days I have been busy upgrading my frameworks (SwifterLog, SwifterJSON, SwifterSockets) and application Swiftfire to Swift 3.
Over all, the migrator does a decent job. It is not flawless but does a good enough job to keep the remaining work to a minimum. It took me about 4 days to upgrade the above mentioned packages.
The job is not finished yet, but I do have a -sort of- running application again.

The three issues that took the most manual work for me is the conversion of Foundation types to build-in Swift types (like NSDate -> Data, NSNumber -> Number, etc) , the adaptation of the new GCD implementation and Core Data.

None of these is difficult per se, but it is a new way of doing thing, thus it takes some time figuring things out.

This is what I learned:

GCD

Creating a new queue:

let acceptQueue = DispatchQueue(label: "Accept queue", attributes: [.serial, .qosUserInteractive])

Quite nice actually. And you get to specify both the nature (serial/concurrent) and the priority at the same time. Though I would have liked the priorities specified differently (lowest, low, normal, high, highest ?)

To execute work on the queue:

acceptQueue.async() {
    acceptAndDispatch(socket: acceptSocket)
    SwifterSockets.closeSocket(acceptSocket)
}

Or you can use the sync() of course.

To time the execution of some work:

let dpt = DispatchTime(uptimeNanoseconds: DispatchTime.now().uptimeNanoseconds + UInt64(delta * Double(NSEC_PER_SEC)))
queue.after(when: dpt) { [weak self] in self?.execute() }

Assuming the delta time is the delay in seconds.

I also updated the synchronization away from p_thread_lock to GCD as suggested:


    public class MyClass {
        
        private var syncQueue = DispatchQueue(label: "MyClass Synch", attributes: [.serial])
        
        public var aDate: Date? {
            get {
                return syncQueue.sync(execute: { return self._aDate })
            }
            set {
                syncQueue.sync(execute: { self._aDate = newValue })
            }
        }
             private var _aDate: Date

Though I am a little weary about creating a new queue for every instance of 'MyClass', I decided that for now I will simply wait and see if that becomes a problem.

Core Data

The first I noticed is that the choice to use scalar types has been moved from the "Edit -> Create..." dialogue to the Data Model Inspector. This makes it possible to decide on a case-by-case if we want to use scalar types or not. The second thing is that the choice between Swift and Objective-C has also moved: from the "Edit -> Create..." dialogue to the File Inspector.

Also in the Data Model Inspector there is a new "Codegen" selection box. By default it is set to "Manual/None" which is the same behaviour as before. I have tried the other settings, but either the selection criteria is a little buggy or I am doing things wrong. I could not get the automatic code generation to work properly. No biggy, that can wait.

Generating the managed object custom classes uses a different naming strategy now: <myname>+CoreDataProperties.swift (as before) and <myname>+CoreDataClass.swift (replaces <myname>.swift)
I moved my code from <myname>.swift to <myname>+CoreDataClass.swift and have not experienced any problems.
It can occur that an extra file is created, I have already forgotten how its called precisely, but that file will not compile. Simply delete it. I have read elsewhere that this only occurs if no "save" of the object model was made before creating the managed objects.

The only bigger chance I had to make was to replace the creation of NSFecthRequest's. That must now be done as follows:

let fetchDomainsRequest = NSFetchRequest<CDDomains>(entityName: "CDDomains")

Also, executing the fetch request is now simpeler:

let domainsArray = try self.managedObjectContext.fetch(fetchDomainsRequest)

No need for type casting, that is now implicit.

While there is a new way to create entities as well, that seems to depend on MacOS 10.12, so I kept the old method.

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-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.