drshock drshock - 10 months ago 490
Objective-C Question

Privacy Problems with MFMailComposeViewController and iOS 10 only

Rebuilding an already published app with Xcode 8.0 which uses PLCrashReporter, AWS Cognito/SNS, and Google analytics frameworks.

Seeing that on iOS 10.x devices only, the mail compose vc is no longer being presented during running my tests bucket. In the Xcode console I see these messages immediately when if([MFMailComposeViewController.canSendMail]) is reached:

[MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
[MC] Filtering mail sheet accounts for bundle ID: [MY BUNDLE ID], source account management: 1
[MC] Result: YES

I found one reference to these sort of console messages here: UIActivityViewController crash on iOS 10

But my app does not utilize photos, still I tried adding the photos privacy description noted in the link to my info.plist for grins but of course no joy. Problem persists.

My app does use the camera, for scanning barcodes. And the camera privacy description is in the info.plist and has been since last year. The app utilizes no other features for which privacy descriptions are required.

Same exact code and XC8 setup when an iOS 9.3.5 device is attached works as expected.

Anyone seen this yet?

Answer Source

So after much analysis I finally figured this problem out last weekend. The key to knowing it actually had nothing to do with MFMailComposeViewController privacy changes in iOS 10 was this log message:

[MC] Result: YES

If you get a "NO" then you have a privacy problem, but a YES indicates that privacy was not an issue. I finally found, in my case here anyway, that the problem was is a timing issue in my code uncovered running in iOS 10.

On the same exact device model being testing, one with iOS 10 and one with iOS 9.3.5 the problem was an error path UIAlertController present request being called when another alert was already presented. On iOS 9.x and earlier it was just "luck" that the expected one won out and got presented first every single time. But on iOS 10 it failed to do so every single time and this then blocked the MFMailComposeViewController in my situation.

The following code was problematic :

[self presentViewController:crashMailAlertController animated:YES completion:nil];

Replacing it with this code resolved the issue:

[self dismissViewControllerAnimated:YES completion:^{
            [self presentViewController:crashMailAlertController animated:YES completion:nil];

In my case all I wanted was to insure that this error path UIAlertController was always presented first as it was a rare event (only when a crash had happened), so dismissing any previous alert first was the ticket to getting it up so that the MFMailComposeViewController would follow as it was embedded in the alert button action.