I'm trying to print the progress of data transfer while using multipeer connectivity.
The progress
information is available on the receiver side, in the didStartReceivingResourceWithName
method and on the sender side, in the sendResource
method.
Here is how I have implemented the receiver side:
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
DispatchQueue.main.async {
print (progress)
}
}
And here is how I implemented the sender side:
func sendFileAction()->Progress{
var filePath = Bundle.main.url(forResource: "10MO", withExtension: "file")
if mcSession.connectedPeers.count > 0 {
do {
let data = try Data(contentsOf: filePath!)
fileTransferProgressInSender = mcSession.sendResource(at: filePath!, withName: "filename", toPeer: mcSession.connectedPeers[0]) { (error) -> Void in
DispatchQueue.main.async {
if error != nil {
print("Sending error: \(String(describing: error))")
}else{
print("sendAFile with no error "+"filename")
}
}
}
}
catch let error as NSError {
let ac = UIAlertController(title: "Send file error", message: error.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}
return(fileTransferProgressInSender)
}
The receiver function does display the progress
only once, at the beginning.
<NSProgress: 0x1c0133740> : Parent: 0x0 / Fraction completed: 0.0000 / Completed: 0 of 10485760
And I can't figure out where I can call the return of sendFileAction
to display the progress on the sender side.
Any help please? Thanks.
Edit: I tried with the following code:
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
startTime = Date()
DispatchQueue.main.async {
self.endTransfer = false
self.sendProgressBar.progress = 0.0
self.updateProgress(progress: progress)
}
}
func updateProgress(progress:Progress){
DispatchQueue.main.async {
while !self.endTransfer {
print (progress.fractionCompleted)
self.sendProgressBar.progress = Float(progress.fractionCompleted)
}
}
}
While the print
gives real progress in the console, the progress bar jumps from 0 to 1 (reaches 1 before the print
does).
What am I doing wrong?
Thanks again.
Thanks @CodeBender for the hint. Indeed, I needed a timer. So here is how I did:
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
startTime = Date()
self.receptionProgress = progress
DispatchQueue.main.async {
self.receptionTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.updateReceptionProgress), userInfo: nil, repeats: true)
self.receptionTimer.fire()
}
}
And the corresponding function:
@objc func updateReceptionProgress(){
self.receptionProgressBar.progress = Float(self.receptionProgress.fractionCompleted)
if self.receptionProgress.completedUnitCount >= self.receptionProgress.totalUnitCount{
self.receptionTimer.invalidate()
}
}