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

2015-11-30

Swift Example: Binding a NSTableView to an Array

After the introduction to Cocoa bindings in the previous post, todays example is a little more complicated. Unfortunately Apple is lacking in easily accessible documentation: I had to spend a couple of days in frustration before I finally got the tableview bindings working. Though there are some blogs on this subject I found that none worked for the version of xcode that I am using here (7.1).

So here goes:

This is how the app will look:



Each row will contain a label, a textfield and a button. The content for the label and the textfield will be in a table, and the button will be linked to the object that is shown in the table. As you see above, the button will be disabled if the textfield is empty.

All the code that is necessary (in AppDelegate.swift) looks as follows:

class ParameterTableRow: NSObject {
    var name: String = "Parameter Value:"
    var value: String?
    func setButtonClicked() {
        print("Set button clicked")
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    dynamic var parameterTable: Array<ParameterTableRow> = []
    
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

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

}

In the AppDelegate class itself, I only added the definition of the parameterTable. Notice that this property must be made dynamic. Otherwise the runtime cannot intercept the messages to and from the property.
The parameterTable contains items of the class ParameterTableRow that for convenience was included in the same file (AppDelegate.swift).
It is advisable that the ParameterTableRow class inherits from NSObject  It must implement the KVO and KVC protocols and inheriting from NSObject is the easiest way to achieve this.

The name and value properties are displayed in the table, and the button in the table-row will call the method setButtonClicked.

Now, the part that is difficult to show: the bindings.

In Xcode/IB create a window with a table. Also create a row-like NSView that is populated with a label, a textfield and a button. In the table remove the content of the Table Cell View and replace it with the row view. The end result should look like this:


Note that I also added two buttons "add(+)" and "remove(-)" at the end.

Next, drag an Array Controller:


into the objects of this xib file. The result should be this:


The Shared User defaults Controller appears automagically, don't worry about it. We will not touch it.

The Array Controller must be bound to the parameterTable in our delegate. Select the Array Controller and open up the bindings inspector:


Under "Controller Content" open "Content Array" and bind to the delegate like this:


Since we will be using a Add(+) button to create new items in the table, we also need to tell the Array Controller which kind of items to create. Do this in the attributes inspector of the Array Controller:


Fill in the Class Name and use the fully qualified name: This starts with the project name and follows the path from there. In our case it is simply "TableBindingsExample.ParameterTableRow".

That is all for the Array Controller.

Next, lets bind the Table View to the Array Controller. We need to make two bindings, one for the content and one for the selection. Select the Table View in the object navigator of the xib file and open its bindings inspector. Create the bindings as shown below:


Forgetting to create the selection indexes bindings will cause problems later when table rows are deleted. (When the remove button only removes the last entry, you will know that you forgot this binding)

While we are at the Table View, we can also enable multiple selection in the attributes inspector:


Note the "Selection" checkbox "Multiple" is selected here to enable multiple row selection.

Next bind the Parameter Value Textfield (not the cell with the same name!!). Select the Parameter Value and open up the bindings inspector. Create the Value binding as follows:


Note that the value is not bound to the array controller but to the Table Cell View. When the runtime fills in the column, it sets the "objectValue" in the Table Cell View to the corresponding ParameterTableRow object. Hence we need to bind to the objectValue and specify the property "name" of our table row object.

Do the same for the Text Field of our table row as follows:


For the button we do not bind the content, but the target. And possible the arguments, however our target has no arguments. Bind the target of the button as follows:


Clicking the button will call the setButtonClicked method, but we want to disable the button if the textfield is empty. There is a binding for that... :



One final thing: connect the Add(+) and Remove(-) buttons to the Array Controller and connect them to the corresponding actions. Use the simple ctrl-drag for this, drag from the + button to the Array Controller object and select the "add" action. Do the same for the - button and the "remove" action. The Connections inspector should show this for the add button:


That is all, now the project should work as intended. Compile and run.
I have tried to show all the steps, if I missed something, please let me know.

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

Swift Example: Using Cocoa Bindings to connect a NSTextField to a String.

Bindings are a neat way to wire up a GUI. They connect a GUI element to a variable in such a way that updates to the interface are reflected in the variable, and updates to the variable are reflected in the interface. It is a powerful concept, but there are a few snags along the way.
In the MVC parlour, a binding can (up to a point) replace a Controller. You will probably not want to go that far, but at least for simple GUI's it is possible (as we shall see in this example).

To introduce the concept, lets look at a very simple example: Connecting a textfield to a String variable.

Since this is going to be a very simple example, I want to put the variable in the AppDelegate like this:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var parameterId: String = "Any Name"

Here we hit the first 'snag'. This won't work since later on we need to specify the property of a container that can be bound to the textfield. So we need to introduce a wrapper class like this:

class StringWrapper {
    var str: String
    init(str: String) {
        self.str = str
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var parameterId: StringWrapper = StringWrapper(str: "One")

Er.. no, actually that won't work either. The StringWrapper Swift class is not KVO/KVC compliant. While it is probably possible to add the necessary protocols, it is way easier to simply inherit them from NSObject. Like this:

class StringWrapper: NSObject {
    var str: String
    init(str: String) {
        self.str = str
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var parameterId: StringWrapper = StringWrapper(str: "One")

That is all for the AppDelegate, the rest is done within Interface Builder.

Open up the MainMenu.xib file and make sure you display the object/property hierarchy.
Next pick a ObjectController and drop in in the "Objects", it should show up like this (the Object Controller is placed under the "Font Manager"):


Select the Object Controller and bring up the "Bindings Inspector". Here we have to set the "Content Object". Select the "Bind to" checkbox, and select the "Delegate" from the popup box after it. In the "Model Key Path" enter "self.parameterId". Once you entered "self." a popup should appear from which you can choose "parameterId". If that does not happen, check the spelling and the code in AppDelegate.swift before continuing.


Now the controller knows where to find the variable, but it does not know about the textfield the variable should be connected to. To connect the controller with the textfield, we start from the textfield. I.e. we connect the textfield to the controller instead of the other way around. This way it is possible to connect multiple textfields with a single controller, should you ever want to...

Select the "Window" and drop the "NSTextField" in it. You can also add a label should you want to.
Now select the "Text Field":



and bring up the "Binding Inspector" again. This time we edit the "Value" binding as follows:


Click the "Bind to" check box, select the "Object Controller" and enter "self.str" in the Model Key Path. The "Controller Key" remains empty (will be filled in automatically later), and ignore the warning symbol. There is no popup selection box this time (or rather, it is empty). Maybe this will be fixed in a future version of xcode.

Now compile and run the app. You won't see the updates you'll make in the textfield, to see that the variable is actually updated, add an observer:

class StringWrapper: NSObject {
    var str: String {
        didSet {
            print("New value = \(str)")
        }
    }
    init(str: String) {
        self.str = str
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var parameterId: StringWrapper = StringWrapper(str: "One") {
        didSet {
            print("Will never be called")
        }
    }


Notice that only the wrapper observer is called, the "parameterId" observer is never called.

One more thing: When you want to update the value of parameterId.str do not simply assign the value, but use a KVC compliant method. Thus do not:

        parameterId.str = "Will not update the view"

But do this:

        parameterId.setValue("Will update the view", forKey: "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.

2015-11-23

Instantiating a Swift class unknown at compile time at runtime

In objective-C it was possible to instantiate a class at runtime just from the name with NSClassFromString. In Swift this is no longer possible, however we could still use the old objective-C method with a little extra effort to obtain the necessary names etc. All in all it does not look 'nice' to me. There should be a better way...

In general, it could be said that instantiating a class completely unknown at compile time is a questionable practise. Sure there are some situations in which we can justify anything, but usually we do know something about the class, for example that it implements a certain protocol...

And that is all that is needed to use a more Swift-like way to hop around the aforementioned restriction.

If the unknown class has to implement a known protocol we can demand that the unknown class inherits from a known class. And we can specify for a known class that it must implement a "newFromSelf" method. And we can then use the newFromSelf method to create as many new objects as necessary at runtime.

In the example below a library function is made that needs to create instances of a "data end detector". That is, a network server receives data from a client and has to know when all data has been received. However the nature of the data is not known to the library. Hence a call-back or closure is necessary that identifies the end-of-data.
A further complication arises because the end-of-data closure must be able to handle segmented data transfers. I.e. the closure must have associated internal parameters that are preserved across invocations. Hence the closure is no longer a closure but becomes a class.
And since the library function should be able to spawn multiple threads each processing its own data stream, the library function should be able to create as many instances of the end-of-data detector as necessary.

    /// An child class of this is used to find the end of the data.
    
    class EndOfDataDetector {
        
        
        /// When 'endReached' is called, this buffer pointer will point to the newly received data.
        ///
        /// - Note: The value will most likely be different on each call to 'endReached'.
        
        var buffer: UnsafePointer<UInt8>?
        
        
        /// When 'endReached' is called, bufferSize will indicate how many bytes were received.
        
        var bufferSize: Int?
        
        
        /// This function should only return 'true' when it detects that the received data is complete. It is likely that this function is called more than once for each data transfer. I.e. if the method to detect the end of the incoming data is not a unique single byte, a child implementation must be able to handle segmented reception. Every received byte-block is only presented once to this function.
        
        func endReached() -> Bool {
            return false
        }
        
        
        /// All child classes must implement the newFromSelf function if SocketUtils.accept() is used. The newFromSelf function should set the internal state of the new object into a state that allows 'endReached' to be called for the first time.
        
        func newFromSelf() -> EndOfDataDetector {
            assert(false)
        }
    }

Now the library user can create a child class from EndOfDataDetector and implement the endReached() as well as the newFromSelf() function. When the library needs a new instance for a new connection request it can simply call newFromSelf() to create a new data end detector.

An example for a detector that is used to find the end of a JSON message:

class JsonMessageComplete: SocketUtils.EndOfDataDetector {
    
    var countOpeningBraces = 0
    var countClosingBraces = 0
    
    override func endReached() -> Bool {
        for i in 0 ..< bufferSize! {
            if (buffer! + i).memory == ASCII_BRACE_OPEN { countOpeningBraces++ }
            if (buffer! + i).memory == ASCII_BRACE_CLOSE {
                countClosingBraces++
                if countOpeningBraces == countClosingBraces {
                    return true
                }
            }
        }
        return false
    }
    
    override func newFromSelf() -> SocketUtils.EndOfDataDetector {
        return JsonMessageComplete()
    }
}

In the library function we can now use something like: let newEndDetector = endDetector.newFromSelf() assuming that endDetector is the argument that the library function received.

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

Namespaces in Swift, resolving collisions.

Though Swift does support namespaces, it is not obvious what the namespace is for the standard libraries. This can easily create conflicts when we want to name a function of our own making and happen to pick the same name as a standard function. And there are a lot of standard functions...

Often enough the argument list of a function will prove to be sufficient for the compile to figure out which function we did intent to call, but there are cases where the compiler needs some assistance.

For example the UNIX accept function is defined as follows:

int accept(int, struct sockaddr * __restrict, socklen_t * __restrict)

I defined an accept function with the following signature:

class SocketUtils {
        
    static func accept(socket: Int32, interval: NSTimeInterval?, timeout: NSTimeInterval? = nil) -> AcceptResult { .. }
}

Unfortunately the compiler will nag when I try to use the Unix accept function:


Obviously the compiler thinks that my own accept function should be used, while I want to use the accept from the UNIX system library.

The solution is simple: use the fully qualified name for the system function.

Turns out, the fully qualified name for any system function starts with the name of the project:

let connectionDescriptor = MyGreatProject.accept(socket, &connectedAddrInfo, &connectedAddrInfoLength)

Works just fine!

Note: The fully qualified name for my own accept function is of course:
MyGreatProject.SocketUtils.accept

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

Swift gotcha: Using the same pointer in two arguments

Working with buffers and pointers to buffers in Swift is surprisingly easy. But sometimes a shortcut can end up biting the hand that typed it...

Consider the following case:

func test(a: UnsafeMutablePointer<UInt8>, b: UnsafeMutablePointer<UInt8>) {
    print("a = \(a), \(a.memory), b = \(b), \(b.memory)")
    print("a3 = \(a[3])")
    print("b3 = \(b[3])")
    b[3] = 6
    a[3] = 7
    print("a3 = \(a[3])")
    print("b3 = \(b[3])")
}

var buf = [UInt8](count: 20, repeatedValue: 0)
var v: UInt8 = 40
for i in buf.startIndex ..< buf.endIndex {
    buf[i] = v++
}

test(&buf, b: &buf)

print(buf[3])

What would be the value printed by the last statement?
Of course this would not be a gotcha if that value was not 6.
Thing is, the function's arguments are pointers to an array, and in Swift arrays are passed by value. That behaviour seems to extend to pointers and the memory they point at.
This becomes clear if we look at the result of the first print statement in the function:

a = 0x00007fd422809950, 40, b = 0x00007fd42040c660, 40

It is clear that the pointers point to two different memory area's, but both these area's contain the same values. Then as the function completes, the memory area's are merged such that the area belonging to the later argument is copied over the area pointed at by the first argument.

This has a few implication: first is that inside the function we can be sure that pointers will point at different memory area's, even if we "know" that both pointers refer to the same base value.
The second is that there is copying overhead even though pointers are used.

Now, you may argue that the above is contrived, you would surely never use the same pointer twice in an argument list right?
Well...

Consider this case:

test(&buf[0], b: &buf[4])

This works as intended (when the test function uses the UnsafeMutablePointer  not UnsafePointer!), the printout shows that both pointer point to the same area:

a = 0x00007fcbe072bb10, 40, b = 0x00007fcbe072bb14, 44

When dealing with pointers we can also write &buf[4as &buf+the two are synonyms... right?

Nope... try this: test(&buf+0, b: &buf+4)

This yields: a = 0x00007fcbe072bb10, 40, b = 0x00007fcbe2009b94, 44

Whoa, suddenly the copying behaviour is back. This is very annoying when dealing with low level IO operations where it is sometimes necessary to pass back and forth pointers into buffers.

Using offsets and indicies as arguments is a good way to solve this potential problem.

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

Swift gotcha: UnsafePointer and UnsafeMutablePointer

The UnsafePointer and the UnsafeMutablePointer seem similar enough, but really, they're not!

The first and most obvious difference is that for the UnsafeMutablePointer you need to use the ampersand "&" to refer to an address, with the UnsafePointer that is optional. While annoying for a language purist, the compiler will warn you, so this is not a big issue.

What may bite you is the difference and similarity between indexed pointers of both types, i.e. &buf[2] when you use them as arguments. Mutable pointer will put the address of the third buffer element in the argument, while for non-mutable pointers the third buffer element is copied to a new memory area and a pointer to that area is passed. In the later case losing access to the rest of the buffer.

The work around for these kind of problems is to never use the &buf[iconstruction but the &buf+which has the same behaviour for both types of pointers.

Associated example code:

func non(a: UnsafePointer<UInt8>) {
    print("non address = \(a), content = \(a.memory), content + 1 = \((a+1).memory)")
}

func mut(a: UnsafeMutablePointer<UInt8>) {
    print("mut address = \(a), content = \(a.memory), content + 1 = \((a+1).memory)")
}

var buf: Array<UInt8> = [1, 2, 3, 4, 5]

non(buf)
non(&buf)
mut(&buf)

print("---")

non(&buf[2])
mut(&buf[2])

print("---")

non(&buf+2)
mut(&buf+2)

Output:

non address = 0x00007f84f1e01f30, content = 1, content + 1 = 2
non address = 0x00007f84f1e01f30, content = 1, content + 1 = 2
mut address = 0x00007f84f1e01f30, content = 1, content + 1 = 2
---
non address = 0x00007fff5af70f40, content = 3, content + 1 = 15
mut address = 0x00007f84f1e01f32, content = 3, content + 1 = 4
---
non address = 0x00007f84f1e01f32, content = 3, content + 1 = 4
mut address = 0x00007f84f1e01f32, content = 3, content + 1 = 4

PS: I have reported this to apple, the above behaviour is for Swift 2.1 and Xcode 7.1. Apple replied that this is the intended result because we are not supposed to add to the UnsafePointer. While I can live with that, I still don't like the fact that the same syntax produces different results without generating warnings. This is a vulnerability that could cause big problems when maintaining existing code.

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

Swift code library: Replacements for FD_SET, FD_CLR, FD_ISSET, FD_ZERO

Updated on 2016-08-11 for Swift 3 beta

The FD_SET, FD_CLR, FD_ISSET and FD_ZERO macro's are used in low level file/socket descriptor programming. Unfortunately Swift does not define these macro's, so we need a Swift implementation.

    /**
     Replacement for FD_ZERO macro.
     
     - Parameter set: A pointer to a fd_set structure.
     
     - Returns: The set that is opinted at is filled with all zero's.
     */
    
    public static func fdZero(_ set: inout fd_set) {
        set.fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    }
    
    
    /**
     Replacement for FD_SET macro
     
     - Parameter fd: A file descriptor that offsets the bit to be set to 1 in the fd_set pointed at by 'set'.
     - Parameter set: A pointer to a fd_set structure.
     
     - Returns: The given set is updated in place, with the bit at offset 'fd' set to 1.
     
     - Note: If you receive an EXC_BAD_INSTRUCTION at the mask statement, then most likely the socket was already closed.
     */
    
    public static func fdSet(_ fd: Int32, set: inout fd_set) {
        let intOffset = Int(fd / 32)
        let bitOffset = fd % 32
        let mask = 1 << bitOffset
        switch intOffset {
        case 0: set.fds_bits.0 = set.fds_bits.0 | mask
        case 1: set.fds_bits.1 = set.fds_bits.1 | mask
        case 2: set.fds_bits.2 = set.fds_bits.2 | mask
        case 3: set.fds_bits.3 = set.fds_bits.3 | mask
        case 4: set.fds_bits.4 = set.fds_bits.4 | mask
        case 5: set.fds_bits.5 = set.fds_bits.5 | mask
        case 6: set.fds_bits.6 = set.fds_bits.6 | mask
        case 7: set.fds_bits.7 = set.fds_bits.7 | mask
        case 8: set.fds_bits.8 = set.fds_bits.8 | mask
        case 9: set.fds_bits.9 = set.fds_bits.9 | mask
        case 10: set.fds_bits.10 = set.fds_bits.10 | mask
        case 11: set.fds_bits.11 = set.fds_bits.11 | mask
        case 12: set.fds_bits.12 = set.fds_bits.12 | mask
        case 13: set.fds_bits.13 = set.fds_bits.13 | mask
        case 14: set.fds_bits.14 = set.fds_bits.14 | mask
        case 15: set.fds_bits.15 = set.fds_bits.15 | mask
        case 16: set.fds_bits.16 = set.fds_bits.16 | mask
        case 17: set.fds_bits.17 = set.fds_bits.17 | mask
        case 18: set.fds_bits.18 = set.fds_bits.18 | mask
        case 19: set.fds_bits.19 = set.fds_bits.19 | mask
        case 20: set.fds_bits.20 = set.fds_bits.20 | mask
        case 21: set.fds_bits.21 = set.fds_bits.21 | mask
        case 22: set.fds_bits.22 = set.fds_bits.22 | mask
        case 23: set.fds_bits.23 = set.fds_bits.23 | mask
        case 24: set.fds_bits.24 = set.fds_bits.24 | mask
        case 25: set.fds_bits.25 = set.fds_bits.25 | mask
        case 26: set.fds_bits.26 = set.fds_bits.26 | mask
        case 27: set.fds_bits.27 = set.fds_bits.27 | mask
        case 28: set.fds_bits.28 = set.fds_bits.28 | mask
        case 29: set.fds_bits.29 = set.fds_bits.29 | mask
        case 30: set.fds_bits.30 = set.fds_bits.30 | mask
        case 31: set.fds_bits.31 = set.fds_bits.31 | mask
        default: break
        }
    }
    
    
    /**
     Replacement for FD_CLR macro
    
     - Parameter fd: A file descriptor that offsets the bit to be cleared in the fd_set pointed at by 'set'.
     - Parameter set: A pointer to a fd_set structure.
    
     - Returns: The given set is updated in place, with the bit at offset 'fd' cleared to 0.
     */

    public static func fdClr(_ fd: Int32, set: inout fd_set) {
        let intOffset = Int(fd / 32)
        let bitOffset = fd % 32
        let mask = ~(1 << bitOffset)
        switch intOffset {
        case 0: set.fds_bits.0 = set.fds_bits.0 & mask
        case 1: set.fds_bits.1 = set.fds_bits.1 & mask
        case 2: set.fds_bits.2 = set.fds_bits.2 & mask
        case 3: set.fds_bits.3 = set.fds_bits.3 & mask
        case 4: set.fds_bits.4 = set.fds_bits.4 & mask
        case 5: set.fds_bits.5 = set.fds_bits.5 & mask
        case 6: set.fds_bits.6 = set.fds_bits.6 & mask
        case 7: set.fds_bits.7 = set.fds_bits.7 & mask
        case 8: set.fds_bits.8 = set.fds_bits.8 & mask
        case 9: set.fds_bits.9 = set.fds_bits.9 & mask
        case 10: set.fds_bits.10 = set.fds_bits.10 & mask
        case 11: set.fds_bits.11 = set.fds_bits.11 & mask
        case 12: set.fds_bits.12 = set.fds_bits.12 & mask
        case 13: set.fds_bits.13 = set.fds_bits.13 & mask
        case 14: set.fds_bits.14 = set.fds_bits.14 & mask
        case 15: set.fds_bits.15 = set.fds_bits.15 & mask
        case 16: set.fds_bits.16 = set.fds_bits.16 & mask
        case 17: set.fds_bits.17 = set.fds_bits.17 & mask
        case 18: set.fds_bits.18 = set.fds_bits.18 & mask
        case 19: set.fds_bits.19 = set.fds_bits.19 & mask
        case 20: set.fds_bits.20 = set.fds_bits.20 & mask
        case 21: set.fds_bits.21 = set.fds_bits.21 & mask
        case 22: set.fds_bits.22 = set.fds_bits.22 & mask
        case 23: set.fds_bits.23 = set.fds_bits.23 & mask
        case 24: set.fds_bits.24 = set.fds_bits.24 & mask
        case 25: set.fds_bits.25 = set.fds_bits.25 & mask
        case 26: set.fds_bits.26 = set.fds_bits.26 & mask
        case 27: set.fds_bits.27 = set.fds_bits.27 & mask
        case 28: set.fds_bits.28 = set.fds_bits.28 & mask
        case 29: set.fds_bits.29 = set.fds_bits.29 & mask
        case 30: set.fds_bits.30 = set.fds_bits.30 & mask
        case 31: set.fds_bits.31 = set.fds_bits.31 & mask
        default: break
        }
    }
    
    
    /**
    Replacement for FD_ISSET macro
    
     - Parameter fd: A file descriptor that offsets the bit to be tested in the fd_set pointed at by 'set'.
     - Parameter set: A pointer to a fd_set structure.
    
     - Returns: 'true' if the bit at offset 'fd' is 1, 'false' otherwise.
     */

    public static func fdIsSet(_ fd: Int32, set: inout fd_set) -> Bool {
        let intOffset = Int(fd / 32)
        let bitOffset = fd % 32
        let mask = 1 << bitOffset
        switch intOffset {
        case 0: return set.fds_bits.0 & mask != 0
        case 1: return set.fds_bits.1 & mask != 0
        case 2: return set.fds_bits.2 & mask != 0
        case 3: return set.fds_bits.3 & mask != 0
        case 4: return set.fds_bits.4 & mask != 0
        case 5: return set.fds_bits.5 & mask != 0
        case 6: return set.fds_bits.6 & mask != 0
        case 7: return set.fds_bits.7 & mask != 0
        case 8: return set.fds_bits.8 & mask != 0
        case 9: return set.fds_bits.9 & mask != 0
        case 10: return set.fds_bits.10 & mask != 0
        case 11: return set.fds_bits.11 & mask != 0
        case 12: return set.fds_bits.12 & mask != 0
        case 13: return set.fds_bits.13 & mask != 0
        case 14: return set.fds_bits.14 & mask != 0
        case 15: return set.fds_bits.15 & mask != 0
        case 16: return set.fds_bits.16 & mask != 0
        case 17: return set.fds_bits.17 & mask != 0
        case 18: return set.fds_bits.18 & mask != 0
        case 19: return set.fds_bits.19 & mask != 0
        case 20: return set.fds_bits.20 & mask != 0
        case 21: return set.fds_bits.21 & mask != 0
        case 22: return set.fds_bits.22 & mask != 0
        case 23: return set.fds_bits.23 & mask != 0
        case 24: return set.fds_bits.24 & mask != 0
        case 25: return set.fds_bits.25 & mask != 0
        case 26: return set.fds_bits.26 & mask != 0
        case 27: return set.fds_bits.27 & mask != 0
        case 28: return set.fds_bits.28 & mask != 0
        case 29: return set.fds_bits.29 & mask != 0
        case 30: return set.fds_bits.30 & mask != 0
        case 31: return set.fds_bits.31 & mask != 0
        default: return false
        }

    }


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.