Using NSCrossWebsiteTrackingUsageDescription to request user disable ITP for WKWebView - ios

The iOS 14 release is catching third-party auth/device cookies and it appears we need to disable Intelligent Tracking Prevention (ITP). The documentation available (planet.webkit.org) suggests we would set a specific setting key and "Purpose String" in the project's Info.plist:
Intelligent Tracking Prevention in WKWebView
Additionally in iOS 14.0 and macOS Big Sur, Intelligent Tracking Prevention (ITP), is enabled
by default in all WKWebView applications. [...]
In some extreme cases, users might need to disable ITP protections,
for example when relying on web content outside of the app developer’s
control. Applications can signal the need to allow users to disable
ITP by adding a Purpose String for the key
NSCrossWebsiteTrackingUsageDescription to the app’s Info.plist. When
present, this key causes the application’s Settings screen to display
a user control to disable ITP. The setting cannot be read or changed
through API calls.
https://planet.webkit.org/
I believe I have done this:
<!-- Info.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>NSCrossWebsiteTrackingUsageDescription</key>
<string>Allow authentication and device trackers.</string>
...
</dict>
</plist>
I would expect a modal iOS dialog to display asking for the permission using that text to explain the permission request. However, I never receive any dialog or request and ITP is still interfering in the auth/device recognition process.
It might hinge on what the following means in practice.
this key causes the application’s Settings screen to display a user control to disable ITP.
How do I get this process to work and allow for disabling ITP?

The solution here is to add a Settings bundle (or similar) that allows the iOS device to present a settings page from the device's Settings app. Essentially, follow the Settings.bundle tutorial and the Info.plist setting for NSCrossWebsiteTrackingUsageDescription will trigger the setting toggle in the screenshot below.
Not sure why it doesn't use the "Purpose String" value, however.

Related

desktopCapturer.getSources and getUserMedia not working

I've an Electron app that uses desktopCapturer, and I also capture audio using getUserMedia.
All this works well when in development. But after building the app using electron-builder for Mac (dmg),
desktopCapturer's getSources only returns the electron app and desktop's thumbnails as the sources, all other windows' thumbnails are not returned (even though their titles are).
I also keep getting asked if I should allow the app to record screen, even when in settings > screen recording, the app has been allowed. (Maybe it keeps asking for audio? Even so, how to allow the app record audio?)
I'm also not able to record any audio, but while in development, I was able to.
The app also is no longer able to record from camera saying getUserMedia error: NotReadableError: Could not start video source electron - even when no other app is using the camera.
I'm completely lost as to were the problem is or how to debug this. Any help is appreciated!
I have found that I have to remove and regrant permissions in system preferences after building a new version of the app (and restart the app for them to take affect).
If that doesn't work you may need to add/edit a build/entitlements.mac.inherit.plist.
Its talked about as a requirement for electron builder here:https://www.electron.build/configuration/mac.html#:~:text=to%20application%20icon.-,entitlements,-String%20-%20The%20path
I think it should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>

Error App Store Connect: 'ITMS-90683: Missing Purpose String in Info.plist' & 'ITMS-90078: Missing Push Notification Entitlement' [Flutter]

I am trying to upload a new version of our app on the App Store Connect. In our old version we are already using push notification and hence, the certificate for Apple Push Services is already active and added in the Apple Developer Portal (as shown in the screenshot below). When we uploaded our previous version of the app to App Store Connect, there was no issue. However, now when I am trying to upload our new version of the app to App Store Connect using Xcode, there is no error shown in the Xcode side and uploading is successful (as shown in the screenshot below).
When I go back to the App Store Connect to check my uploaded build version so that I can submit it for review, it is saying that the build is being processed (as shown in the screenshot below). After sometime I receive an email from the App Store Connect mentioning that our build version has the following issues (detailed email is provided at the end of this question):
ITMS-90683: Missing Purpose String in Info.plist
ITMS-90078: Missing Push Notification Entitlement
For our app's latest build version it is mentioned that ITMS-90683 error for Info.plist (shown below) is missing description for NSContactsUsageDescription, NSCalendarsUsageDescription, NSAppleMusicUsageDescription, NSMotionUsageDescription, NSSpeechRecognitionUsageDescription, NSLocationAlwaysUsageDescription & NSLocationWhenInUseUsageDescription. However, in our app, which is built with Flutter framework, we are not using any of these permissions specifically.
My Questions are as follows:
How can I fix the ITMS-90683 error when I am not using any of these
permissions explicitly in our app such that the build version can be
uploaded for review successfully?
Since, the Apple Push Services' certificate is already added to Apple Developer portal how can I fix the ITMS-90078 and submit the app for review?
Info.plist content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AppName</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Need to upload image</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need to upload image</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Need to upload image</string>
<key>UILaunchStoryboardName</key>
<string>Launch Screen2</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
Any help is much appreciated. Thank you in advance!
Screenshot of "Signing & Capabilities" of my project:
Screenshot of successful upload of the build version from Xcode:
Screenshot of the App Store Connect where the new build version is being processed:
Screenshot of Apple Developer Portal with Apple Push Services Certificate enabled, which is used by previous version fo the app:
Email from App Store Connect regarding the error:
Dear Developer,
We identified one or more issues with a recent delivery for your app,
[APP NAME] 2.0.1 (4). Please correct the following issues, then upload
again.
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSContactsUsageDescription key with a
user-facing purpose string explaining clearly and completely why your
app needs the data. Starting Spring 2019, all apps submitted to the
App Store that access user data are required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSCalendarsUsageDescription key with
a user-facing purpose string explaining clearly and completely why
your app needs the data. Starting Spring 2019, all apps submitted to
the App Store that access user data are required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSAppleMusicUsageDescription key with
a user-facing purpose string explaining clearly and completely why
your app needs the data. Starting Spring 2019, all apps submitted to
the App Store that access user data are required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSMotionUsageDescription key with a
user-facing purpose string explaining clearly and completely why your
app needs the data. Starting Spring 2019, all apps submitted to the
App Store that access user data are required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSSpeechRecognitionUsageDescription
key with a user-facing purpose string explaining clearly and
completely why your app needs the data. Starting Spring 2019, all apps
submitted to the App Store that access user data are required to
include a purpose string. If you're using external libraries or SDKs,
they may reference APIs that require a purpose string. While your app
might not use these APIs, a purpose string is still required. You can
contact the developer of the library or SDK and request they release a
version of their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
Though you are not required to fix the following issues, we wanted to
make you aware of them:
ITMS-90078: Missing Push Notification Entitlement - Your app appears
to register with the Apple Push Notification service, but the app
signature's entitlements do not include the "aps-environment"
entitlement. If your app uses the Apple Push Notification service,
make sure your App ID is enabled for Push Notification in the
Provisioning Portal, and resubmit after signing your app with a
Distribution provisioning profile that includes the "aps-environment"
entitlement. Xcode does not automatically copy the aps-environment
entitlement from provisioning profiles at build time. This behavior is
intentional. To use this entitlement, either enable Push Notifications
in the project editor's Capabilities pane, or manually add the
entitlement to your entitlements file. For more information, see
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#//apple_ref/doc/uid/TP40008194-CH6-SW1.
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSLocationAlwaysUsageDescription key
with a user-facing purpose string explaining clearly and completely
why your app needs the data. Starting Spring 2019, all apps submitted
to the App Store that access user data are required to include a
purpose string. If you're using external libraries or SDKs, they may
reference APIs that require a purpose string. While your app might not
use these APIs, a purpose string is still required. You can contact
the developer of the library or SDK and request they release a version
of their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
ITMS-90683: Missing Purpose String in Info.plist - Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSLocationWhenInUseUsageDescription
key with a user-facing purpose string explaining clearly and
completely why your app needs the data. Starting Spring 2019, all apps
submitted to the App Store that access user data are required to
include a purpose string. If you're using external libraries or SDKs,
they may reference APIs that require a purpose string. While your app
might not use these APIs, a purpose string is still required. You can
contact the developer of the library or SDK and request they release a
version of their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
Best regards,
The App Store Team
How can I fix the ITMS-90683 error when I am not using any of these permissions explicitly in our app such that the build version can be uploaded for review successfully?
This part of app review doesn't care if you're actually using these features. All they check is whether the app has code to do so (which yours obviously does) and comes with the required purpose strings. To solve this, you basically have two options:
figure out which pieces of code/library/whatever you have in your app that brings this baggage along, and get rid of it, or
live with the baggage and provide the required purpose strings.
Since, the Apple Push Services' certificate is already added to Apple Developer portal how can I fix the ITMS-90078 and submit the app for review?
The problem is not with the certificate, but with the app's entitlement, which you're not showing. Make you you have the push notification entitlement enabled in your app.

How to add a credential provider app extension for iOS 12 in xamarin

I’m trying to leverage the new extension to work with a password management app, and I’m running into a road block setting it up. It could be my googling skills but there is almost no documentation on how to do this with xamarin.
What I have so far:
Added com.apple.developer.authentication-services.autofill-credential-provider as a custom property into my iOS project Entitlements.plist
Created an ActivionView extension since there is no credential provider option when creating a iOS extension project.
Changed the ActionViewController to a CredentialProviderViewController
Updated the MainInterface.storyboard to use the CredentialProviderViewController
Added com.apple.developer.authentication-services.autofill-credential-provider as a custom property to the autofill Entitlements.plist
I don’t see the option under Settings>Passwords & Accounts to use my app for the autofill. I must be missing some key pieces. Does anyone know what I should be doing instead?
Here is my Entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.orginization.appname</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.orginization.appname</string>
</array>
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
<true/>
</dict>
</plist>
I have confirmed that this is a bug with Xamarin.iOS. Specifically, there is an enumeration of and validation against a list of known Extension Points. The credential provider point introduced in iOS 12, and any others after iOS 10 are not present.
I've forked the Xamarin.iOS code and made the necessary patches and confirmed that I am now able to successfully deploy a credential provider that shows up in the AutoFill Passwords provider list in iOS settings. I will file a bug and submit a pull request as soon as I can, but I may go through and make sure all the other extension points are present first.
Edit: All of my pull requests have been merged into the main development branch and will hopefully be part of an official release soon.

HKHealthStore preferred units not supported for universal apps?

I have a universal iOS app that references HealthKit. When the app is installed on an iPhone the app uses HKHealthStore to retrieve health data and when it is on an iPad I skip the HealthKit queries by checking if HKHealthStore.isHealthDataAvailable is false. This all works well but in order to have the app run on an iPad I have to remove the "healthkit" entry from my app's .plist under "Required device capabilities". This makes sence because the iPad doesn't have healthkit on it so requiring it makes it so the app won't install on the iPad. All of this has already been done in an app I have submitted to the app store and has been approved.
Now I am making an app update and I want to show unit preferences that a user may have manually adjusted in the Health App. The documentation for HKHeathStore says you can do this using the preferredUnitsForQuantityTypes method. However, calling this method from my iPhone app gives me the following error:
Error Domain=com.apple.healthkit Code=4 "Missing com.apple.developer.healthkit entitlement." UserInfo={NSLocalizedDescription=Missing com.apple.developer.healthkit entitlement.}
Except I have the healthkit entitlement in my app id already. If I add the "healthkit" entery under the "Required device capabilities" section of my .plist, then this error goes away and I get the desired results. But this is not a solution for me because then I can't install the app on an iPad.
My question is, how can I support a universal app where the iPhone version can make a successful call to HKHealthStore.preferredUnitsForQuantityTypes?
EDIT
Here is what my .entitlements file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.healthkit</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.mycompany.myapp</string>
</array>
</dict>
</plist>
I found out what was happening here. There was a threading issue between when the HKHealthStore was requesting access to health types and requesting the preferred units. I'm not sure why the .plist entry fixes this issue... but moving the preferred units request into the completion block of the HKHealthStore's requesting access method fixed the issue.

iOS Facebook SDK openActiveSessionWithReadPermissions never returns on some FB Apps

We're writing a native iOS app which integrates with Facebook. Several months ago we set up a placeholder FB app via developers.facebook.com and have been doing all of our testing via that. Now that we're closer to release I thought I'd set up a new, clean, "proper" FB app, with all of the correct app descriptions/URL fields/etc.
As a first step, I've set up the new app to be as similar to the old one as possible and made a new test user. The old app works fine, so I'm reasonably confident that our iOS code is correct (and yes I've switched the app ID in the XCode project and so forth), but when we run with the new app integrated we get this behaviour when trying to authorise the app with the user:
If the iOS Facebook app is installed and the test user is already logged in:
On calling openActiveSessionWithReadPermissions (requesting #"email" permissions), the iOS Facebook app is launched and shows the user the basic info authorisation page for our app.
The user clicks the "Log in" button at the top of the page.
The FB app pops up another, blank window with a "Cancel" button at the top left.
From this point on, nothing the user does will make Facebook return control to our iOS app.
But checking the test user's page afterwards shows that the app has been authorised.
If I uninstall the Facebook app from the device, thereby forcing the request screens to be shown in Safari instead, we get the same behaviour except point (3) above is replaced with:
3) A device alert saying "Safari cannot open the page because the address is invalid". This is the address it's trying to open: https://m.facebook.com/dialog/permissions.request?_path=permissions.request&app_id=<*our_app_id*>&redirect_uri=fb<*our_app_id*>%3A%2F%2Fauthorize&sdk=ios&display=touch&type=user_agent&perms=email&fbconnect=1&sso=iphone-safari&from_login=1&client_id=<*our_app_id*>&refid=9
I've found this behaviour to be the same on iOS 5.1 and 6.0 hardware devices and the 6.0 simulator. Using out old FB app, the authorisation returns correctly. I'm sure that in the app admin page I just haven't set one of the magical, barely-documented option checkboxes correctly, but I really don't know how to go about finding out what's going wrong.
Thanks for any advice!
As it's not returning to your app, you may have forgot to add the URL scheme to your Info.plist. You should have a new entry, here's the XML representation of it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbYOUR_APP_ID</string>
</array>
</dict>
</array>
</plist>

Resources