Yesterday I spent two long hours tracking down the solution to a __TCC_CRASHING_DUE_TO_PRIVACY_VIOLATION error and I hope this post might save that time for someone else.
In my project JReader, I use the admob_flutter package to display advertisements to my users. It uses the IDFA, unique device identifier, in order to track users across various services and serve more relevant ads.
This is basically what Google uses to stalk you and if you ever wonder how related ads all of a sudden start appearing after you googled something once, well, this a key contributor.
In iOS 14 however, Apple cracked down on privacy and now require explicitly to ask for access to this identifier. Google has a good article about what is needed and why.
The request will look something like this when you start the app:
So why am I posting about this if Google has already written about exactly what you need to do? Because I didn’t explicitly handle the upgrade to iOS 14 support. I didn’t know that I needed this. I ran it on an iOS 14 device and then had to spend a lot of time googling to figure out what was off.
Let me break down how I went about this.
Run from xcode
I’m building my app in Flutter so when I ran it straight from Android Studio, well, it would just crash and tell me nothing. So if you do experience this, run it through xcode and you should at least get a stack trace.
This one screen though isn’t very helpful. So, dig into the stacktrace.
Clicking the filename opens a drop-down and you can now see a few more useful places where the error occurred.
The key thing I could read out from this, which also gave some results when googling it was the __TCC_CRASHING_DUE_TO_PRIVACY_VIOLATION error. The first thing to do whenever you get an error, find the best most describing error text/code you can find and google it.
Usually, the error will tell you not only what’s failing but the data related but in this case, as you can see from the screenshot, it came up pretty blank.
This led me to the oracle of all programmers. Stackoverflow.
This post highlighted that others got the same error and for pretty obvious reasons, permissions weren’t explicitly requested in the
info.plist file. However, me unknowing about the iOS 14 upgrade changes, didn’t know of anything that could be missing and of all the examples in the post I wasn’t using any of them.
Rule it out
Sometimes when I have no idea, I tend to try ruling things out. So I grabbed a list of common permissions to see if maybe I was missing something. I figured, if I added everything in and it worked, then I could go through them using binary splitting and rule out each half until I found which the perpetrator was.
I wasn’t so lucky though, even with all of these it didn’t work.
Going through the code
At this point, I began thinking about ruling out libraries one by one. I knew the error happened early so it ought to have been something around initialization. My first guess was related to a local notification library so I tried excluding that with no luck. Next up I found the admob and realized that my day-time work team just added some privacy settings for this and very much so, removing the admob initializer from the Flutter code and the app ran.
So, what was needed to make the admob work with my flutter project on iOS 14 was to add an explicit description to requesting the IDFA using these two lines in the
<key>NSUserTrackingUsageDescription</key> <string>Please allow JReader to read your device ID to be able to give you a better AD experience.</string>
My hope is that Google indexes the above error and that the next poor person can find this article helpful. And also, it gives me a chance to say: please apple, add which permission is missing to the error message. If I’m being silly and just missed how to read the exception, I would love for someone to comment on this and help us out track these things down faster in the future!
Fare the well and may the stacktrace be with you