Update the progress bar of function C

I am working on an iOS 8 audio app in Swift. The MIDI file is loaded and when the user clicks the Save button, it is displayed in the file in a C function that manually pulls the samples.
Now I would like to update the progress bar in the interface for this save action.
I added a property watcher to var in the ViewController and I passed a pointer to that var to the C function, hoping it would update it during the loop ... well, no. Even if the C function updates the var value inside the loop, this update is "fired" only once, at the end. Is there a way to update the progress bar?
Here's the code.
Thank!

In ViewController:

var outProgressBarValue:Float = 0.0 {
    willSet {
        dispatch_async(dispatch_get_main_queue(), {
            println("New value received! -> \(newValue)")
            self.progressBarOutlet.setProgress(newValue, animated: true)
        })
    }
}

@IBAction func saveButton(sender: AnyObject) {
    [...]
    let backgroundQueue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)
    dispatch_async(backgroundQueue, {
        WriteOutputFile(url, self.musicSequence!, Sound.sharedInstance.musicPlayer, self.processingGraph,  &self.outProgressBarValue)

    dispatch_async(dispatch_get_main_queue(), {
            restoreOnlineRendering(processingGraph: self.processingGraph, mainMixerNode: self.mainMixerNode, ioNode: &(self.ioNode))
            self.saveButtonOutlet.setTitle("Done", forState: UIControlState.Normal)
    [...]
}

      

In the linked C file:

void WriteOutputFile(CFURLRef url, MusicSequence musicSequence, MusicPlayer musicPlayer, AUGraph processingGraph, float *outProgressBarValue) {  
[] 
    CheckError(MusicPlayerStart(musicPlayer), "MusicPlayerStart");
    do {
        CheckError(AudioUnitRender (outputUnit, &actionFlags, &tStamp, 0, numFrames, bufferList), "AudioUnitRender");
        tStamp.mSampleTime += (Float64)numFrames;
        CheckError(ExtAudioFileWrite(outfile, numFrames, bufferList), "ExtAudioFileWrite");
        CheckError(MusicPlayerGetTime (musicPlayer, &currentTime), "MusicPlayerGetTime");
        *outProgressBarValue = currentTime / sequenceLength;
        printf("outProgressBarValue:\t %f\n", *outProgressBarValue);
    } while (currentTime < sequenceLength);

    CheckError(MusicPlayerStop(musicPlayer), "MusicPlayerStop"); 
[] 
}  

      

+3


source to share


1 answer


If monitoring doesn't work, why not send the update explicitly to the controller? For example, via NSNotification.

Here's what I did as a proof of concept:



  • Add an Objective-C class file with .h and .m files. No need to define a class in this file, just put your c-function in .m and declaration in .h.

  • Set up the bridge header where you import the .h file. The bridge header is usually named "-Bridging-Header.h".

  • Now you can just call your function in any swift class.

  • In the .m file, use the c function to import " <UIKit/UIkit.h>

    " (or Foundation).

  • If necessary, send a notification from your c function similar to this:

    NSNotification *notif = [[NSNotification alloc] initWithName:@"Update"
       object:nil userInfo:@{@"progress" : @0.42}];
    [[NSNotificationCenter defaultCenter] postNotification:notif];
    
          

  • In the swift file, follow the normal procedure to add self

    as an observer for the notification and call the update function with the values ​​passed in the dictionary userInfo

    .

+1


source







All Articles