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

2015-12-31

Segmentation fault work around on xcode 7.2

With XCode 7.2 I sometimes experience a "Segmentation Fault". Once it happens, it becomes impossible to recompile my project.
This happens after updating the code while up to that point the code was compiler-error free.
I.e. I would build the project, execute the application, stop de application, make a minor fix, en then bomb: Segmentation fault. And there is (almost) nothing I could do to reverse this. Undoing the change and cleaning the project does not work. Once a segmentation fault, always a segmentation fault.

Until I stumbled upon a work around: My application has a main.swift file. I would select all other swift files in the project and remove them from the target in the "Target Membership" from the "File Inspector" panel.
Then hit Ctrl-B (i.e. rebuild the project).
Of course the build would fail, but this is not important.
Then add the files back to the target and hit Ctrl-B again.
Presto, the code now compiles again, without the segmentation fault!

If you are careful and select (in XCode) only the files that are included in the project then deselect the target membership and use Ctrl-B... then the file selection will remain and implementing the work around will only take a few seconds.

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.

2015-12-10

How to create an Unsafe(Mutable)Pointer

Swift is rather restrictive in the creation of pointers. But when we do low level programming it is sometimes necessary to use pointers. Especially when interfacing to the C-APIs of the underlying Unix system.

The "&" is used in arguments to create a pointer. But cannot be used in other places for the same purpose.

So how to create a pointer outside of a function argument?

Well, Apple has provided us with the withUnsafeMutablePointer and withUnsafePointer functions to deal with this. They take a few arguments and a closure. The argument is converted into a pointer that can subsequently be used inside the closure.

An example:

        var telemetry = Telemetry()
        let result = withUnsafeMutablePointer(&telemetry, {
            ptr in
            // From here on 'ptr' is a UnsafeMutablePointer<Telemetry>
            ...
        })

The same can be done for UnsafePointer as well.
And there are variations on withUnsafeMutablePointer and withUnsafePointer that allow for multiple pointers to be created at once.
The result is the result returned from the closure, which is neat too. In fact the conversion functions are defined as this:

public func withUnsafeMutablePointer<T, Result>(inout arg: T, @noescape _ body: UnsafeMutablePointer<T> throws -> Result) rethrows -> Result

Hence they do not only return the result from the closure, but they will even rethrow any execptions the closure might throw.

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.

2015-12-03

Swift example: How to load a nib/xib file into a view on OS-X

Many simple application use just a single nib/xib file, the MainMenu.xib. And while that works fine, as soon as the application becomes more demanding it gets cramped rather quickly.
Also, Apple suggests that the MainMenu.xib file should only be used for the main menu and that we should add xib files for other windows and views as necessary.

This post shows how to load a view from a different xib file and make it visible. We wil do this the old fashioned way, without storyboards.

For non-document based applications I will use MainMenu.xib for the menu and the main window. Then I will add another xib file containing a view. This view will be loaded into the main window explicitly. The view will use a NSViewController.

Create the project, a simple cocoa application for OS-X. This project comes with the main menu xib already set up the way this example needs it.

Since we want to load a view from a different nib into the window, it would be nice to have access to the view component of the window. To do this, add an outlet to the AppDelegate. Also, we will need an instance of NSViewController to attach the loaded view to, create it in AppDelegate as well:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    @IBOutlet weak var view: NSView!
    
    var myViewController = MyViewController!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

}

In Interface builder, connect the view outlet to the view inside the window. Select the "Window". Right-click the delegate object, click drag the circle behind the "view" and drag it onto the window. When completed it should look like this:



Now create a new OS-X User Interface file. Select the "View" template. I saved it as MyView.xib. In this view I added a textfield and a button like this:



Next, create the view controller. Add a new Swift file called MyViewController.swift to the project. In it, add an outlet for the textfield and an action for the button:

import Foundation
import Cocoa

class MyViewController: NSViewController {
    
    @IBOutlet weak var textField: NSTextField!
    
    @IBAction func countButtonAction(sender: AnyObject?) {
        var count = textField.integerValue
        count++
        textField.integerValue = count
    }

}

Switch back to the MyView.xib file and change the class of the File Owner to MyViewController:


Connect the outlet and action to the textfield and the button. And important: Also connect the "view" outlet to our new view:



Almost done, now the final step: loading the nib file and displaying its contents. We do this in the AppDelegate:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    @IBOutlet weak var view: NSView!
    
    var myViewController: MyViewController!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
        myViewController = MyViewController(nibName: nil, bundle: nil)
        view.subviews.removeAll()
        view.addSubview(myViewController.view)
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

}

That is all, build and run the project.

You will notice that you need to clean up the appearance of the window, but for today, I will leave that exercise for you.

Note: The name of the nib file (or xib file) must be the same as the name for the ViewController. Otherwise the instantiation of the controller will fail.

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.