mbl_mw_logger_subscribe not working after app restart

Hello! I want my app to log and retrieve sensor data stored in a device. This task should work well even if the app closes between data logging and retrieving. (i.e. connect to the board -> press the StartLog button in my app -> app close -> app restart -> reconnect to the board -> press RetriveLog button in my app) However, the closure of the mbl_mw_logger_subscribe function does not work after the app restarts.

When I press the RetriveLog button, the function below is called.

func accelerometerBMI160StopLog(device: MetaWear) {
        guard let accelLoggerInt = loggers.removeValue(forKey: "acceleration") else {
            print("Error: Cannot remove loggers")
            return
        }
        let accelLogger = OpaquePointer(bitPattern: accelLoggerInt)
        mbl_mw_acc_stop(metaWearDevice!.board)
        mbl_mw_acc_disable_acceleration_sampling(metaWearDevice!.board)
        mbl_mw_logging_stop(metaWearDevice!.board)
        mbl_mw_logging_flush_page(metaWearDevice!.board)

        mbl_mw_logger_subscribe(accelLogger, bridge(obj: self)) { (context, obj) in
            let acceleration: MblMwCartesianFloat = obj!.pointee.valueAs()
            let _self: DeviceViewController = bridge(ptr: context!)
            _self.accelLogToWrite.append("x: \(acceleration.x), y: \(acceleration.y), z: \(acceleration.z), epoch: \(obj!.pointee.epoch)\n")
        }

        var handlers = MblMwLogDownloadHandler()
        handlers.context = bridgeRetained(obj: self)
        handlers.received_progress_update = { (context, remainingEntries, totalEntries) in
            let _self: DeviceViewController = bridge(ptr: context!)
            let progress = Double(totalEntries - remainingEntries) / Double(totalEntries)

            if progress == 1.0 {
                print(_self.accelLogToWrite)
                try? _self.accelLogToWrite.write(to: _self.fileURL, atomically: true, encoding: .utf8)
            }              
        }
        handlers.received_unknown_entry = { (context, id, epoch, data, length) in
            print("received_unknown_entry")
        }
        handlers.received_unhandled_entry = { (context, data) in
            print("received_unhandled_entry")
        }
        mbl_mw_logging_download(metaWearDevice!.board, 100, &handlers)
    }
}

(The line let accelLogger = OpaquePointer(bitPattern: accelLoggerInt) is needed in order to store and retrieve logger OpaquePointer in UserDefault as an Int.)

Everything works well even if the view disappears and reappears.(Not an app close and restart) Also, the accelLogger parameter is valid after the app restarts. I think the parameter bridge(obj: self) or the line handlers.context = bridgeRetained(obj: self) may be the cause the problem. How can I resolve this?

Comments

  • mbl_mw_logger_subscribe() is just a closure, it probably loses context once the app closes. You need to restart the download by restarting it from accelLogger and whatever ios provides as a callback when the app returns to action.

  • @Laura
    Thank you for replying.
    What do you mean by "restart the download by restarting it from accelLogger"? "accelLogger" is successfully retrieved from UserDefaults after the app restart.

  • @Laura
    Also, the "accelerometerBMI160StopLog" function is called after app restart. The progress is: connect to the board -> press "StartLog" button. Device starts logging -> App close, save logger pointer to UserDefaults -> reconnect to the board -> Retrieve logger pointer from UserDefaults -> press "StopLog" button. "accelerometerBMI160StopLog" function is called.

  • Oh if you stop the log then it's over, the accelLogger will no longer be valid.

Sign In or Register to comment.