Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage

Greetings!

I use the latest xcode and solar2d versions.

I did some changes in my build.settings for one of my apps.
The changes was for appodeal plugin and among other things I added the SKAdNetworkItems.

The build was rejected and I got this email:
We noticed that your app urges or manipulates users into granting consent to access the AppTrackingTransparency framework. Specifically, your app displays its own permission request prompt to the user before presenting the iOS permission request.

The permission request process on iOS is designed to give users control of their personal information. It is important to respect the user’s decisions about how they want their data used. If they decide to not grant permission to your app, they should not be prompted to change their mind or be forced to reject the request multiple times. You can provide users with additional information about why you’re requesting access to their data before the iOS permission request appears, as long as you don’t include your own custom permission request.

Next Steps

To resolve this issue, please remove any permission requests in your app that appear before the iOS permission request.

My build.settings is:

settings =
{

    orientation =
    {
        default = "portrait",
        supported =
{
"portraitUpsideDown",
             },
     },
     
    splashScreen =
    {
        enable = false
    },
     
iphone =
    {
      xcassets = "Images.xcassets",
       plist =
        {
        CFBundleDisplayName = "My App",
        UILaunchStoryboardName = "LaunchScreen",
       
            GADApplicationIdentifier = "ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxxxxxxxx",
            NSAppTransportSecurity = { NSAllowsArbitraryLoads = true },
            UIRequiredDeviceCapabilities = {"location-services" },
            NSBluetoothAlwaysUsageDescription = "This app would like to access bluetooth.",
       
        --NSLocationAlwaysUsageDescription = "This app would like to use location services.",
                   
            NSLocationWhenInUseUsageDescription = "The app needs your location for analytics and advertising purposes",
            NSCalendarsUsageDescription = "The app needs your calendar to provide personalised advertising experience tailored to you",
            NSUserTrackingUsageDescription = "This identifier will be used to deliver personalized ads to you.",
            SKAdNetworkItems = {
                { SKAdNetworkIdentifier = "4pfyvq9l8r.skadnetwork" },
                { SKAdNetworkIdentifier = "yclnxrl5pm.skadnetwork" },
                { SKAdNetworkIdentifier = "v72qych5uu.skadnetwork" },
                { SKAdNetworkIdentifier = "tl55sbb4fm.skadnetwork" },
                { SKAdNetworkIdentifier = "t38b2kh725.skadnetwork" },
                { SKAdNetworkIdentifier = "prcb7njmu6.skadnetwork" },
                { SKAdNetworkIdentifier = "ppxm28t8ap.skadnetwork" },
                { SKAdNetworkIdentifier = "mlmmfzh3r3.skadnetwork" },
                { SKAdNetworkIdentifier = "klf5c3l5u5.skadnetwork" },
                { SKAdNetworkIdentifier = "hs6bdukanm.skadnetwork" },
                { SKAdNetworkIdentifier = "c6k4g5qg8m.skadnetwork" },
                { SKAdNetworkIdentifier = "9t245vhmpl.skadnetwork" },
                { SKAdNetworkIdentifier = "9rd848q2bz.skadnetwork" },
                { SKAdNetworkIdentifier = "8s468mfl3y.skadnetwork" },
                { SKAdNetworkIdentifier = "7ug5zh24hu.skadnetwork" },
                { SKAdNetworkIdentifier = "4fzdc2evr5.skadnetwork" },
                { SKAdNetworkIdentifier = "4468km3ulz.skadnetwork" },
                { SKAdNetworkIdentifier = "3rd42ekr43.skadnetwork" },
                { SKAdNetworkIdentifier = "2u9pt9hc89.skadnetwork" },
                { SKAdNetworkIdentifier = "m8dbw4sv7c.skadnetwork" },
                { SKAdNetworkIdentifier = "7rz58n8ntl.skadnetwork" },
                { SKAdNetworkIdentifier = "ejvt5qm6ak.skadnetwork" },
                { SKAdNetworkIdentifier = "5lm9lj6jb7.skadnetwork" },
                { SKAdNetworkIdentifier = "44jx6755aq.skadnetwork" },
                { SKAdNetworkIdentifier = "mtkv5xtk9e.skadnetwork" },
                { SKAdNetworkIdentifier = "ludvb6z3bs.skadnetwork" },
                { SKAdNetworkIdentifier = "wg4vff78zm.skadnetwork" },
                { SKAdNetworkIdentifier = "737z793b9f.skadnetwork" },
                { SKAdNetworkIdentifier = "ydx93a7ass.skadnetwork" },
                { SKAdNetworkIdentifier = "w9q455wk68.skadnetwork" },
                { SKAdNetworkIdentifier = "glqzh8vgby.skadnetwork" },
                { SKAdNetworkIdentifier = "av6w8kgt66.skadnetwork" },
                { SKAdNetworkIdentifier = "cj5566h2ga.skadnetwork" },
                { SKAdNetworkIdentifier = "f38h382jlk.skadnetwork" },
                { SKAdNetworkIdentifier = "s39g8k73mm.skadnetwork" },
                { SKAdNetworkIdentifier = "v9wttpbfk9.skadnetwork" },
                { SKAdNetworkIdentifier = "n38lu8286q.skadnetwork" },
                { SKAdNetworkIdentifier = "cstr6suwn9.skadnetwork" },
                { SKAdNetworkIdentifier = "su67r6k2v3.skadnetwork" },
                { SKAdNetworkIdentifier = "n9x2a789qt.skadnetwork" },
                { SKAdNetworkIdentifier = "kbd757ywx3.skadnetwork" },
                { SKAdNetworkIdentifier = "uw77j35x4d.skadnetwork" },
                { SKAdNetworkIdentifier = "3sh42y64q3.skadnetwork" },
                { SKAdNetworkIdentifier = "5l3tpt7t6e.skadnetwork" },
                { SKAdNetworkIdentifier = "mls7yz5dvl.skadnetwork" },
                { SKAdNetworkIdentifier = "5a6flpkh64.skadnetwork" },
                { SKAdNetworkIdentifier = "578prtvx9j.skadnetwork" },
                { SKAdNetworkIdentifier = "f73kdq92p3.skadnetwork" },
                { SKAdNetworkIdentifier = "8m87ys6875.skadnetwork" },
                { SKAdNetworkIdentifier = "488r3q3dtq.skadnetwork" },
                { SKAdNetworkIdentifier = "zmvfpc5aq8.skadnetwork" },
                { SKAdNetworkIdentifier = "97r2b46745.skadnetwork" },
                { SKAdNetworkIdentifier = "6xzpu9s2p8.skadnetwork" },
                { SKAdNetworkIdentifier = "cg4yq2srnc.skadnetwork" },
                { SKAdNetworkIdentifier = "ecpz2srf59.skadnetwork" },
                { SKAdNetworkIdentifier = "238da6jt44.skadnetwork" },
                { SKAdNetworkIdentifier = "22mmun2rn5.skadnetwork" },
                { SKAdNetworkIdentifier = "lr83yxwka7.skadnetwork" },
                { SKAdNetworkIdentifier = "24t9a8vw3c.skadnetwork" },
                { SKAdNetworkIdentifier = "v79kvwwj4g.skadnetwork" },
                { SKAdNetworkIdentifier = "424m5254lk.skadnetwork" },
                { SKAdNetworkIdentifier = "44n7hlldy6.skadnetwork" },
                { SKAdNetworkIdentifier = "4dzt52r2t5.skadnetwork" },
                { SKAdNetworkIdentifier = "wzmmz9fp6w.skadnetwork" },
                { SKAdNetworkIdentifier = "bvpn9ufa9b.skadnetwork" },
                { SKAdNetworkIdentifier = "gta9lk7p23.skadnetwork" },
            },
       
       --UIApplicationExitsOnSuspend = false,
       UIPrerenderedIcon = true,
       UIStatusBarHidden = true,
       MinimumOSVersion = "8.3",
   },
},

plugins =
{

        ['plugin.appodeal.base'] = { publisherId = 'com.coronalabs' },
        ['plugin.appodeal.GoogleAdMob'] = { publisherId = 'com.coronalabs' },
        ['plugin.appodeal.StartApp'] = { publisherId = 'com.coronalabs' },
        ['plugin.appodeal.Chartboost'] = { publisherId = 'com.coronalabs' },
        --['plugin.appodeal.AppLovin'] = { publisherId = 'com.coronalabs' },
        --['plugin.appodeal.InMobi'] = { publisherId = 'com.coronalabs' },
        --['plugin.appodeal.AmazonAds'] = { publisherId = 'com.coronalabs' },
        --['plugin.appodeal.AdColony'] = { publisherId = 'com.coronalabs' },
       
       
        ["plugin.pollfish"] =
        {
            publisherId = "com.coronalabs",
            supportedPlatforms = { iphone=true }
        },      
},

}

Any ideas?
Could it be the NSAppTransportSecurity positioning?
Should I move it after SKAdNetworkItems?

I changed the positioning but the build was rejected again for the same reason.

In Build for iOS window there are two options in iOS SDK.
14.4 and 14.4 Metal.
I used 14.4.
Could this make any difference?

I suspect it is pollfish. Although I have not released an Appodeal app recently. I did release an app with the SKAdNetworkItem with no issue in the last few days. The position of those items has no impact on anything since they are just added to a plist in the final build. What happens when you test it? Do you have a screenshot of the dialog box?

Hello agramonte and thank you for the reply.

I have sent a new build without pollfish and waiting for the result.
If its’s pollfish plugin is there anything I can do to fix it?

When I test it there is a dial box with the same text with or without pollfish.
(I’m translating because it’s not in english)
With bold letters:
“Request to track your activity in applications and websites belonging to other companies.”
Then there is the string I have declared in NSUserTrackingUsageDescription and the buttons to allow it or not.

Do you have a screenshot? So I can see it? if it looks like this it is fine. this one is apple’s:

This is the screenshot. It’s almost the same message in Greek.

I get the same message with or without pollfish enabled.

Translation:
“Request from ‘APP NAME’ to track your activity in applications and websites belonging to other companies.

I will run a test with Appodeal soon. I guess the plugin is asking for permission which is not required and most people will not consent.

1 Like

The build just got rejected again for the same reason although I removed pollfish.

Appodeal plugin was the reason this time.

I don’t get this message at all. Not sure what I am doing wrong.

I just built with the following:

   ['plugin.appodeal.base'] = { publisherId = 'com.coronalabs' },`
   ['plugin.appodeal.Bidmachine'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.GoogleAdMob'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.A4G'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.AppLovin'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.Smaato'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.Unity'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.AmazonAds'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.AdColony'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.IronSource'] = { publisherId = 'com.coronalabs' },
    ['plugin.appodeal.Vungle'] = { publisherId = 'com.coronalabs' },

My iPhone iOS is 14.2
Using corona: 2021.3638
And xCode: 12.4
Tested a build using TestFlight.
Under security my phone is on “Allow apps to ask for permission to track you across apps and websites”.

I red Apple’s email more carefully today.
They are saying that all this is happening because I’m showing my consent pop-up before theirs!

The problem is that their pop-up appears when initializing appodeal.
How am I going to know if the user wants personalized ads or not without asking them first?
Is there a way to know what they have chosen in Apple’s pop-up (allow tracking or ask app not to track)?

Or we don’t need the custom pop-up for personalized advertising anymore?
If a user chose app not to track, idfa will be zeroed and custom pop-up will have no reason to exist.
User consent being true or false in appodeal initializing will make no difference.
Right?

I have chosen not to use the pop-up for my apps. Very few will give you permission. Ad networks will still get install attributions based on the skanetwork keys you add to the plist. What I don’t understand is why you are getting the pop-up and I am not.

Is there any info I could share that would help you figure this out?

No. I am really trying to help you out. I don’t get the pop-up at all with Appodeal. I am just trying to replicate your pop-up on my app to see if I can help you.

1 Like

@agramonte Do you have NSUserTrackingUsageDescription in your plist? That’s the source of the popup.

1 Like

Thank you! No, I do not have NSUserTracking in my plist on either app. So that makes sense.

The app update has been approved.
iOS pop-up must come first.
The only thing missing is a way to know what the user have chosen.

Skadnetwork keys do the exact same job as idfa and there is no revenue loss?

@conradH I believe there are a bunch of plugins that allow record IDFA. If it is a bunch of 0s they did not provide consent. Even now I can see this in the logs:

SKadnetwork does the same thing but it is aggregated and there is a threshold before any installs are reported. For Indy developers that means that if your app doesn’t generate enough installs the ad provider won’t see any of them and won’t be able to charge the customer for any and you will not get paid for any.

About appodeal plugin.

We put “SKAdNetwordItems = {}” in build.settings so if the user chooses app not to track, skadnetwork will be used.

If user allows tracking, idfa will be used instead of skadnetwork and we can ask for permision to personalise the ads.

Is my understanding correct?

From what I have read it depends on the adnetwork.

  1. Some might use hybrid.
  2. Others are going to CPC or CPM model. This is what I read for Unity in one of their recent emails. If I don’t have enough installs to trigger the threshold they might switch my inventory to CPC or CPM to provide me with some revenue.
  3. Others might just use the SKAdNetwork.
1 Like