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>
Related
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.
Dark mode support was added to version 2.20.31 (released in March of 2020) of the WhatsApp client. This is an iOS 13-only feature, and from the look & feel it appears to be a fully native implementation. I think it is safe to assume that the app is now being compiled with iOS SDK 13.0 or above.
The thing is, as of iOS 13, Apple now requires the native call screen to be shown whenever a VoIP notification is received - otherwise, the app will not receive any further VoIP notifications. In previous version of iOS, some apps (including WhatsApp) appear to use "fake" incoming VoIP calls to silently wake up the app in background when the user attempted to use the web client, so that the latter could then connect and exchange data directly with the phone.
However, as of the latest version, the web client still appears to work as it did before despite the restriction introduced by Apple. Using a debugger it is possible to observe the iOS app waking up whenever the user opens the web client on a PC, but no call screens are ever shown. This can be done repeatedly and as often as we want.
The logs from WhatsApp seems to confirm what is written above:
default 17:09:44.515731+0000 callservicesd Call source <CXXPCCallSource 0x111ecb0a0 identifier=UKFA9XBX6K.net.whatsapp.WhatsApp isConnected=1 processIdentifier=417 isPermittedToUsePublicAPI=1 isPermittedToUsePrivateAPI=0> registered with configuration <CXProviderConfiguration 0x111e9bb40 localizedName=WhatsApp ringtoneSoundURL=(null) iconTemplateImageData=0x0 maximumCallGroups=1 maximumCallsPerCallGroup=1 supportsAudioOnly=1 supportsVideo=1 supportsEmergency=0 supportsVoicemail=0 supportsCurrentPlatform=1 includesCallsInRecents=1 audioSessionID=1151157 supportedHandleTypes=2>
If we try to do this with our app, the results are quite different:
error 18:56:19.949023+0000 callservicesd Killing VoIP app com.xxxxx.xxxxx.xxxxx because it failed to post an incoming call in time.
Any idea what's going on here? Is WhatsApp using any sort of undocumented workaround or exploiting some sort of private API?
This is WhatsApp latest entitlements file:
<?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.icloud-container-identifiers</key>
<array>
<string>57T9237FN3.net.whatsapp.WhatsApp</string>
</array>
<key>com.apple.developer.pushkit.unrestricted-voip</key>
<true/>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>57T9237FN3.net.whatsapp.WhatsApp</string>
</array>
<key>application-identifier</key>
<string>UKFA9XBX6K.net.whatsapp.WhatsApp</string>
<key>com.apple.developer.carplay-messaging</key>
<true/>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.icloud-container-environment</key>
<string>Production</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:api.whatsapp.com</string>
<string>applinks:v.whatsapp.com</string>
<string>applinks:chat.whatsapp.com</string>
<string>applinks:wa.me</string>
</array>
<key>com.apple.developer.siri</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>57T9237FN3</string>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudDocuments</string>
<string>CloudKit</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.net.whatsapp.WhatsApp.shared</string>
<string>group.com.facebook.family</string>
<string>group.net.whatsapp.WhatsApp.private</string>
<string>group.net.whatsapp.WhatsAppSMB.shared</string>
<string>group.net.whatsapp.family</string>
</array>
</dict>
</plist>
This specific entitlement seems to be the reason that they are allowed to not report an incoming call:
com.apple.developer.pushkit.unrestricted-voip
I can't find any documentation regarding this entitlement, so I'm pretty sure they have been given a special permission by Apple.
I've asked eurodev support about this and just received:
At this point we don’t have any additional information about the unrestricted entitlement that you are asking about. The only information that’s available is linked here.
https://developer.apple.com/documentation/bundleresources/entitlements
Pushing back to them to get more info.
Thanks.
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.
I've created a new question for this since this is more linked to Xamarin. I was looking for a way to uniquely identify a device in iOS when I stumbled upon this question in StackOverflow. It took me a while to figure out how to add anything into Keychain and them I stumbled upon this question.
After all the stumbling, I came up with this piece of code for generating the unique token.
var s = new SecRecord(SecKind.GenericPassword)
{
AccessGroup = "kSecAttrAccessGroupToken",
ValueData = NSData.FromString(value),
Generic = NSData.FromString(key)
};
SecKeyChain.Add(s);
Now the problem is that even though I'm adding this entry to keychain I am unable to find it. I'm also interested to know if I am using the kSecAttrAccessGroupToken correctly.
My Enlistments.plist file
<?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>my app id</string>
<string>kSecAttrAccessGroupToken</string>
</array>
</dict>
</plist>
kSecAttrAccessGroupToken is writable only by CryptoTokenKit smart card drivers. Apps can query the keychain using that attribute in order to find items stored on a particular smart card. This attribute is not for any other use.
There was a bug in 10.3.x beta that would allow any app to also write to it, but that has been patched.
Re: https://forums.developer.apple.com/thread/72271
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.