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

2016-12-29

The defer statement | Swift gotcha

I love the defer statement. Use it all the time...

(Note: The defer statement allows you to execute a piece of code just before the scope the statement is in closes)

However today I ran into an inexplicable problem where a file read operation would always fail. And as so often I simply could not see the error until I stepped through. The error turned out to be quite simple: a defer statement at the wrong place.

This was the offending code:

let path = "/Users/Home/Me/Desktop/file.txt"

let file = fopen(path, "r")

if file == nil {
    print("Error opening file at \(path)")
} else {
    defer { fclose(file) }
}

let result = read(from: file)

...

Do you spot the error?

Right! the defer statement is executed immediately because the end-of-scope is the "}" closing the "else" part.

So the file was already closed when the read operation was called.
The solution is obvious:

let path = "/Users/Home/Me/Desktop/file.txt"

let file = fopen(path"r")

if file == nil {
    print("Error opening file at \(path)")
}
defer { fclose(file) }

let result = read(from: file)

...

The rule of thumb is clear: Always place the defer stement at the same "level" or "indent" as the variable it refers to. Which -to be clear- simply means "the same scope".

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-12-21

Value of optional type Bool not unwrapped | Swift Gotcha

Ever come across the following error message?



It occurs when we do something like this:

      [weak self]
      ....
      if self?.isValidPrivateKey(atPath: keyfilepath) {

The "Fix-it"solution from xcode is the following:

      if (self?.isValidPrivateKey(atPath: keyfilepath))! {

And indeed the error message goes away, everything fine?

Nope, don't let that fool you. The entire purpose of the weak "self?" reference is now gone. When self is indeed nil you will get an exception at runtime.

The proper thing to do is the following (choosing either "false" or "true" based on the case at hand:

     if self?.isValidPrivateKey(atPath: keyfilepath) ?? false {

Now the choice of what to do if self is indeed nil is made explicit and won't cause any problems at runtime.

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-12-13

Implementing a delay in Swift

This is a simple post: we often need  delay in our software, so how to do that in Swift now dispatch_after has been changed beyond recognition?

There are multiple possibilities: use the "Thread.sleep" or use a timer instance are two of the often used. But both have drawbacks, the 'sleep' statement delays the actual thread that our code is running on, which degrades performance. And using (NS) Timer is too complex.

When I first looked at DispatchQueue.asyncAfter I hit a brick wall with doing arithmetic on DispatchTime or DispatchWallTime.

A second look at the Dispatch class showed the proper way to do this: simply add the delay not as a double but as a DispatchTimeInterval.

This code is so easy, it does not even need a wrapper:

        DispatchQueue.main.asyncAfter(
            deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(250),
            execute: {
                ...
            }

        )

Or even simpler:

        DispatchQueue.main.asyncAfter(
            deadline: .now() + .milliseconds(250),
            execute: {
                ...
            }
        )

Instead of milliseconds we can also choose from seconds, microseconds or even nanoseconds.

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-12-05

A general purpose progress bar with label | Swift Code Library

Its been a while as I have been tackling one "urgent" thing after another. No time for blog updates. While I am not assuming that this will change soon, I do have a worthwhile addition to the Swift Code library.

In my current iOS project I needed a progress bar with an associated label. This tracks the rate at which messages are being transferred/received over the internet. Since there is a clear label associated with each message this label should be displayed along with the update of the progress bar. The amount of messages is variable and can even be just one. To give the user useful feedback it was decided that each message should be visible for a small amount of time. Enough to recognize the message, but no more than necessary.

The following class was created:

    final class ProgressBarWithLabel {
        
        struct Info {
            let progress: Float?
            let label: String?
        }
        
        var info: Array<Info> = []
        let timeBetweenUpdates: DispatchTimeInterval
        var timeOfPreviousUpdate: DispatchTime = DispatchTime.now()
        let progressBar: UIProgressView
        let progressLabel: UILabel?
        let mainQueue = DispatchQueue.main // Must be main because the GUI is updated from here
        
        init(progressBar: UIProgressView, progressLabel: UILabel?, timeBetweenUpdates: DispatchTimeInterval) {
            self.timeBetweenUpdates = timeBetweenUpdates
            self.progressBar = progressBar
            self.progressLabel = progressLabel
            self.progressBar.progress = 0.0
            self.progressLabel?.text = ""
        }
        
        func add(info: Info) {
            
            mainQueue.async {
                
                [weak self] in
                
                // Add the new info as the last to be displayed
                self?.info.insert(info, at: 0)
                
                // Make sure there will be an update of the gui
                self?.update()
            }
        }
        
        private func update() {
            
            // Check if a new update can be made
            guard DispatchTime.now() >= timeOfPreviousUpdate + timeBetweenUpdates else {
                

                if info.count > 1 { return }

                // Wait until the necessary delay has expired then try again
                mainQueue.asyncAfter(
                    deadline: timeOfPreviousUpdate + timeBetweenUpdates,
                    execute: {
                        [weak self] () -> () in
                        self?.update()
                    }
                )
                return
            }
            
            // An update will be made, set the time of "previous" to current time
            // This could also be done after the factual update, but doing it before the info test can prevent "gui glitches" if somebody modifies the code after the test. (Defensive Programming)
            timeOfPreviousUpdate = DispatchTime.now().uptimeNanoseconds
                
            // Fetch info to be displayed
            guard let forDisplay = info.popLast() else { return }
            
            // Update GUI, reset the GUI if there is no new data
            progressBar.progress = forDisplay.progress ?? 0.0
            progressLabel?.text = forDisplay.label ?? ""
            
            // If there is more info to be displayed, wait a little
            if info.count > 0 {
                mainQueue.asyncAfter(
                    deadline: timeOfPreviousUpdate + timeBetweenUpdates,
                    execute: {
                        [weak self] () -> () in
                        self?.update()
                    }
                )
            }
        }

    }

Note that this class does not contain the GUI elements itself, they must be specified when an instance is created. Since these GUI elements are assigned by the runtime, special care should be taken to ensure that they are not deallocated when the view goes out of sight and a possible low-memory condition occurs.

I used the following code that ensures the cell stays allocated as long as the table is in use:

var progressCell: FetchAutoQuotesCell?

.... and then in tableView_cellForRowAt:


let cell = progressCell ?? tableView.dequeueReusableCell(withIdentifier: "ProgressCell") as? ProgressCell

if progressCell == nil {
    progressCell = cell
    progressBarWithLabel = ProgressBarWithLabel(progressBar: (cell?.progressBar)!, progressLabel: (cell?.progressLabel)!, timeBetweenUpdates: DispatchTimeInterval.milliseconds(250))
}

This may be overkill, but it won't hurt. (The assignment of the GUI elements themselves is probably enough to keep the cell from being deallocated. OTOH, it might not be enough to ensure that the same cell is reused again and again under all conditions)

Usage of the ProgressBarWithLabel class is relatively easy. The initialization was already shown, the only other call is the add function.

It can be called as follows:

progressBarWithLabel?.add(info: ProgressBarWithLabel.Info(progress: (Float(count) / Float(totalCount)), label: message))

To ensure that the progress indicators are reset, call the add function with an empty Info struct.


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-11-17

Creating and publishing a Jekyll theme

This has nothing to do with Swift. But I maintain a couple of websites that I have all switched from Wordpress to Jekyll. There must be a Jekyll theme out there that I could use, but I didn't find it. So I build my own. And to make sure that it remains available as well as maintainable I thought to enforce a bit of quality by making the theme public. It is available for download from RubyGems under the name: Classic-Jekyll-Theme.

As usual many "howtoes" on the net don't detail all steps or skip a little background know-how that would make things easier. So I created my own. As a result the procedure I describe here may not be the most efficient way. But it did (does) work for me!

First: Create a new Jekyll theme.

(btw: almost all commands will be given from a terminal window, so go ahead an open one up. And while you are at it, maybe also do a quick update of all gems?)

$ jekyll new-theme my-theme

Btw: I use all low-caps to avoid any problems with camel-case and case-sensitive file systems. (Ask me why - no don't!)

The difference between this theme and "normal" themes is that it won't try to look up anything from the ruby gems directory.

Change to the new directory:

$ cd my-theme

Since this is a new theme it cannot be started with "jekyll serve" but we need the "bundler" gem to create the environment for "jekyll serve" to execute in. If you don't have the "bundler" gem installed, do so now:

$ sudo gem install bundler

If we now try to start the theme with "bundle exec jekyll serve" then it will report an error because the gemspec has not been properly defined. Do that by editing the "my-theme.gemspec" file.

There are 2 TODO's in that file that must be fixed. The spec.summary and the spec.homepage. Later on when we create updates of the theme we need to update spec.version each time a new release is created. If the gem will be hosted on rubygems.org, we can set the spec.homepage to "https://rubygems.org/gems/my-theme".

Next, simply try to run the jekyll server:

$ bundle exec jekyll serve

Point a web browser to "localhost:4000" and see what happens. If everything went fine there should be something like this:

Index of /

 Name                          Last modified         Size

Parent Directory 2016/11/17 08:56 - Gemfile 2016/11/17 08:51 38 Gemfile.lock 2016/11/17 08:55 1120 LICENSE.txt 2016/11/17 08:51 1071 README.md 2016/11/17 08:51 1885 my-theme.gemspec 2016/11/17 08:55 666

WEBrick/1.3.1 (Ruby/2.0.0/2015-12-16)
at localhost:4000

So far so good. But we would like to see a website there. Obviously there is some stuff missing that is needed to create a working site. For example an index.html ;-)

Create a file called "index.md" with the following content:

---
# You don't need to edit this file, it's empty on purpose.
# Edit theme's home layout instead if you wanna make some changes
# See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults
layout: home
---
Hello World!

Save it and start the jekyll server if it was not running:

$ bundle exec jekyll serve

Check the browser, refresh or load the site at: "localhost:4000".

Lo and behold: "Hello world!" is what we should see.

We can now start developing our theme.

Once theme development is done, we might want to publish our theme on RubyGems.

(CTRL-C to stop the Jekyll server)

To do so, we need to build the gem and push it to the rubygems site. An account is needed for that, so register at the site and log in. There is no need to stay logged in though. Once logged-in everything should be set up so we can upload (push) the gem when ready.

When jekyll created the new theme it also set up a git repository. That repository is used when creating a gem. So when the gem is ready:

- Update the README.md so that other people can find out the where and how of the theme.
- Update the release number in the gemspec.
- Then (assuming you are still in the directory my-theme):

$ git add .

Note: I like to use "git status" here to verify that the only expected files are ready for commit

$ git commit -m "reason for commit"
$ git tag 0.1.0

The version number should match the version number in the gemspec. However this is not needed to create the gem, it is four our own reference)

$ gem build my-theme.gemspec
$ gem push my-theme-0.1.0.gem

And that is all. To create a new version of the theme, repeat the last few steps from "update the README.md".

Happy coding...

If you like to thank me, I'd gladly accept a cup of coffee. 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

2016-10-14

Port Spy

While working on Swiftfire I had the need to see which data actually arrives at a port and which data is actually sent.

Thus I wrote a little utility called Port Spy.



Port Spy is an in-between utility: it listens on one port and connections to a server on the other. All traffic received on the first port is send to the second port and vice versa. Aside from a little delay, there is no interference with the data itself.
This allows Port Spy to display the data in a view, and -if necessary- to write it to file.

Port Spy uses low level socket-io operations and is written completely in Swift.

Obviously Port Spy is primarily useful for developers, thus Port Spy includes its own source code. If you are in need of some example code for socket based IO in Swift, then you can purchase this utility and export the source code (a complete zipped Xcode project actually) from the File menu.

If you have thought about supporting this blog, then you can now do so while getting a nice utility in return!

Oh, a screenshot:



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-09-26

A Q&D error display for the key window

During development it is convenient to have a simple error display routine that shows whatever text you throw into it in the frontmost (key) window.

There is an easy way to accomplish this, just add a global function (for example in the AppDelegate file):

func showErrorInKeyWindow(_ message: String) {
    
    if let window = NSApp.keyWindow {
        
        DispatchQueue.main.async {
            
            let alert = NSAlert()
            alert.messageText = "Error"
            alert.informativeText = message
            alert.addButton(withTitle: "Dismiss")
            alert.beginSheetModal(for: window, completionHandler: nil)
        }
    }
    else {
        log.atLevelError(id: -1, source: #file.source(#function, #line), message: "Could not send error message '\(message)' to key window")
    }

}

Of course you can replace the error logging with a simple "print" statement as long as you are working in Xcode. Otherwise you could use the SwifterLog logging project (free from github, see link at right side)

Now anywhere in your code where you need to flash an error, just call "showErrorInKeyWindow(message)"

(But beware for repeating error's ;-))

Note: Do not use this in shipping code. Yes, you could, but you really should have a something better in place.

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

The nil case in swift switch statements | Swift Short & Sweet

I am not really sure when this was added or even if this was possible from the beginning, but I just re-discovered a very sweet feature of the switch statement in Swift: The nil case.

enum OneTwo { case one, two }

var ot: OneTwo?

switch ot {
case nil: print("Nil")
case .one?: print("One")
case .two?: print("Two")
}

It even detects the absence of the nil case (when you forget) and asks for a default when you do so.

As near to perfect as it gets imo.

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

New versions for SwifterLog, SwifterSockets, SwifterJSON and Swiftfire | Swift 3 adaptation.

2016.08.17: Just upgraded to Xcode 8 beta 6, and lo and behold... have to do it all again...

I just pushed the new versions for SwifterLog (v0.9.12), SwifterSockets (v0.9.6), SwifterJSON (v0.9.10) and Swiftfire (v0.9.13) to github.

All of them upgrades to Swift 3 (beta), so only make the change if you are also working with Swift 3/Xcode 8 beta 3.

All in all I am rather pleased with the changes in Swift 3, they do make the code better. It took me about a week to change all of the above mentioned source code. Which is a lot, so yes, upgrading an existing code base to Swift 3 will cost you some. Worth it or not, that is something only you can decide. For open source projects like the above, it's a no-brainer of course.

So... on and forward to v1.0... :-)

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