TextView binding Text to a fileReader

I started developing an IOS app for iphone using Xcode 10.1 and Swift (4.2.1).
My application mixes some C code that does network access. For the first I would like to have a TextView and I would like to have all what normally the underlying C-code would do using printf() have that output appearing in a TextView in my App.

Is this the right forum actually o ask such?

My idea is to write into a fifo from the C-code and read from that fifo in the TextView.

That would require that the TextView is permanently updated from the fifo.

How could on achieve this whithout having the program caught up in a tight loop?

--
Christoph

I don’t know to how a pipe is converted in Swift, but if it has File handle, you can use DispatchSourceRead, which can be created with DispatchSource.makeReadSource.

Could you give me an idea how to further use this?
Here is my attempt:

C-Code:

int32_t init_udpC(void) {

int32_t fd;
static char *filename="./MYFIFO";

umask(0);
if((mknod(filename, S_IFIFO|0666, 0)) == -1){
    perror("mknod:");
    exit(2);
}
if((fd=open("./MYFIFO",O_RDWR|O_APPEND)) == -1) {
    perror("open:");
    exit(2);
}
return fd;

}
And here is how I'm trying to call it:

 override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.t
   
    let fd = init_udpC()

    textView.text = DispatchSource.makeReadSource(fileDescriptor:fd) as! String
}

I don't have quite the idea. I guess I have to put the reading from the file into an eventhandler. But I'm right starting to use Swift and Xcode (my first App), so bear with me.

--
Christoph

Dispatch is parallelism framework, so mostly you’ll deal with it using callback (using Swift’s closure or Obj-C block/selector).

So DispatchSource is an object that check for event and notify you. DispatchReadSource is a DispatchSource that check if the file handle has data for reading. You can set callback using

source = DispatchSource.makeReadSource(fileDescriptor:fd)
source.setEventHandler() {
    // read fd here
}

Be mindful that you need to keep source around, perhaps saving it in class variable.

Also that there’s a restriction for the UI-related code be running on the main queue (as you learn more about DispatchQueue you’ll stumble upon this) so you’ll need to switch back to main queue. Doing something like this

source.setEventHandler() {
    // read fd here
    DispatchQueue.main.sync {
        textView.text = <#your text#>
    }
}

Lastly, you need to activate the DispatchSource to start using it.

source.activate()
source.setEventHandler() {
    // read fd here
    DispatchQueue.main.sync {
        textView.text = <#your text#>
    }
}

Thanks a lot. This gives me a rough idea. Will try to build up something such around a DispatchSource.

--
Christoph

There’s also a callback function on FileHandler that you can use which IMO is more swifty.

But since you’re updating UI, you’ll need to jump back to main queue anyway so you might as well use Dispatch.

Also, you can even specify the queue you wish to use when you create the DispatchSource:

source = DispatchSource.makeReadSource(fileDescriptor: fd, queue: DispatchQueue.main)
source.setEventHandler() {
    // Already on the main queue
    // read fd
    // update text
}

Be mindful that a rule of thumb when using main queue is to minimize the work there, otherwise your application will freeze.
This is because all of the User Interactions is processed through that queue.