Search code examples
iosswiftphotokit

Showing a View Controller within a Photos Access request callback throws exception


I am using the following code to request access to the users Photo library upon startup of my app.

@IBAction func requestPhotoLibraryAccess(sender: UIButton) {
    PHPhotoLibrary .requestAuthorization { (status) -> Void in
        if (status == PHAuthorizationStatus.Authorized) {
            self.showViewController(HomeViewController(), sender: self);
        }
    }
}

What I don't understand is that when I call

self.showViewController(HomeViewController(), sender: self); 

it throws

2015-10-04 20:21:13.520 Bokeh[11284:1352415] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.
Stack:(
  0   CoreFoundation                      0x000000010b48ef65 __exceptionPreprocess + 165
  1   libobjc.A.dylib                     0x000000010d249deb objc_exception_throw + 48
  2   CoreFoundation                      0x000000010b48ee9d +[NSException raise:format:] + 205
  3   Foundation                          0x000000010b9ff3b5 _AssertAutolayoutOnMainThreadOnly + 79
  4   Foundation                          0x000000010b8601be -[NSISEngine withBehaviors:performModifications:] + 31
  5   UIKit                               0x000000010c653637 -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 58
  6   UIKit                               0x000000010c653fb9 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 154
  7   UIKit                               0x000000010c653c29 -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 309
  8   UIKit                               0x000000010c653fe5 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 198
  9   UIKit                               0x000000010c653c29 -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 309
  10  UIKit                               0x000000010c653fe5 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 198
  11  UIKit                               0x000000010c65461d __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 98
  12  UIKit                               0x000000010c653640 -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 67
  13  UIKit                               0x000000010c65417a -[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 254
  14  UIKit                               0x000000010c654e8f -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeeded] + 272
  15  UIKit                               0x000000010be7360c -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 159
  16  UIKit                               0x000000010be83143 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 749
  17  QuartzCore                          0x000000011267a36a -[CALayer layoutSublayers] + 146
  18  QuartzCore                          0x000000011266ebd0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
  19  QuartzCore                          0x000000011266ea4e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
  20  QuartzCore                          0x00000001126631d5 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
  21  QuartzCore                          0x00000001126909f0 _ZN2CA11Transaction6commitEv + 508
  22  QuartzCore                          0x0000000112690cd4 _ZN2CA11Transaction14release_threadEPv + 224
  23  libsystem_pthread.dylib             0x000000010e09939c _pthread_tsd_cleanup + 470
  24  libsystem_pthread.dylib             0x000000010e098f78 _pthread_exit + 117
  25  libsystem_pthread.dylib             0x000000010e097596 pthread_attr_getschedpolicy + 0
  26  libsystem_pthread.dylib             0x000000010e095375 start_wqthread + 13
)

If I move the call out of the callback, it works without an issue.

The Apple documentation doesn't say anything about it being ran on a background thread, although I assume that's the whole point of it being callback.

This method always returns immediately. If the user has previously granted or denied photo library access permission, it executes the handler block when called; otherwise, it displays an alert and executes the block only after the user has responded to the alert.

Do I have to marshall the navigation back to the UI thread?


Solution

  • Try

    dispatch_async(dispatch_get_main_queue(),{
    
        self.showViewController(HomeViewController(), sender: self);
    
     })
    

    Instead of

    self.showViewController(HomeViewController(), sender: self);