1
votes
  • (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { self.progress.completedUnitCount = totalBytesSent; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this hangs on ios 9.0 any ideas what to do about this???

  • (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend; is invoked on the main thread not that it should matter

(lldb) bt * thread #1: tid = 0xd6e1, 0x00000001984a0c6c libsystem_kernel.dylibsemaphore_wait_trap + 8, queue = 'com.apple.main-thread', activity = 'send control actions', 1 messages, stop reason = signal SIGSTOP * frame #0: 0x00000001984a0c6c libsystem_kernel.dylibsemaphore_wait_trap + 8 frame #1: 0x000000019857a97c libsystem_platform.dylib_os_semaphore_wait + 24 frame #2: 0x00000001007bd428 libdispatch.dylib_dispatch_barrier_sync_f_slow + 600 frame #3: 0x00000001835af270 Foundation-[NSConcreteObservationBuffer _receiveBox:] + 248 frame #4: 0x00000001836180b0 Foundation_NSKVO1AdaptorDeliver + 388 frame #5: 0x0000000183617ea0 Foundation_NSKVO1AdaptorSlowDeliver + 264 frame #6: 0x0000000183523b84 Foundation-[NSKeyValueObservance observeValueForKeyPath:ofObject:change:context:] + 424 frame #7: 0x00000001834ffdd4 FoundationNSKeyValueNotifyObserver + 304 frame #8: 0x00000001834ff8fc FoundationNSKeyValueDidChange + 404 frame #9: 0x00000001834ea114 Foundation-[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 120 frame #10: 0x000000018258fab0 CoreFoundation__53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 132 frame #11: 0x000000018258f9a8 CoreFoundation-[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 308 frame #12: 0x00000001836cc158 Foundation-[NSProgress _setValueForKeys:settingBlock:] + 600 frame #13: 0x00000001836cc87c Foundation`-[NSProgress setCompletedUnitCount:] + 124

PS: if I avoid setting UIProgressView::observedProgress to that NSProgress it works fine!?

2

2 Answers

1
votes

resolved with busy wait

-(void)showUploadingUI
{
myHardAssert([[NSThread currentThread] isMainThread], @"");
self.progressView.hidden = NO;
NSProgress *progress = urlsession.progress;
if( [self.progressView respondsToSelector:@selector(observedProgress)]) {
// this causes hang     self.progressView.observedProgress = progress;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    while(progress.completedUnitCount < progress.totalUnitCount) {
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.progressView.progress = progress.fractionCompleted;
        });
        [NSThread sleepForTimeInterval:0.033];
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
        self.progressView.progress = 1;
    });

....

the side benefit is backwards compatibility for ios < 9

0
votes

Boy did that help me. My app was freezing when incrementing Progress.completedUnitCount. (On the main thread.) I'm assuming this triggers a setter since there is a side-effect — moving the progress bar, the whole reason for doing it.

My Swift 4 solution was to wrap the call like this:

DispatchQueue.global(qos: .utility).async {
    self._decompressionProgress.completedUnitCount += 1
}

I still don't quite understand why this works... not unlike a lot of things.