Xamarin iOS Program: HealthKit User Permission Dialog not Shown - c#

I follow the tutorial here (Code from Git Code repo here) for Xamarin building the first ios health-kit app but the permission dialog is not shown in the user's end. Both keywords NSHealthShareUsageDescription and NSHealthUpdateUsageDescription are in the info.plist. The code asking permission is
private void ValidateAuthorization ()
{
//Request / Validate that the app has permission to store heart-rate data
var heartRateId = HKQuantityTypeIdentifierKey.HeartRate;
var heartRateType = HKObjectType.GetQuantityType (heartRateId);
var typesToWrite = new NSSet (new [] { heartRateType });
//We aren't reading any data for this sample
var typesToRead = new NSSet ();
healthKitStore.RequestAuthorizationToShare (
typesToWrite,
typesToRead,
ReactToHealthCarePermissions);
}
If I run the app on iOS simulator, the output reports "Missing com.apple.developer.healthkit entitlement" error.
I have enabled the HealthKit permission in the Entitlements.plist file and selected the option accordingly.
HKWork[935:10236] [default] connection error: Error
Domain=com.apple.healthkit Code=4 "Missing
com.apple.developer.healthkit entitlement."
UserInfo={NSLocalizedDescription=Missing com.apple.developer.healthkit
entitlement.} Thread started: #2 HKWork[935:10236] [auth] Failed to
determine authorization status: Error Domain=com.apple.healthkit
Code=4 "Missing com.apple.developer.healthkit entitlement."
UserInfo={NSLocalizedDescription=Missing com.apple.developer.healthkit
entitlement.} HKWork[935:10241] [plugin] AddInstanceForFactory: No
factory registered for id <CFUUID 0x60000167c9a0>
F8BB1C28-BAE8-11D6-9C31-00039315CD46
Any amount of help would be appreciated.

I found my problem is: at Project Options->iOS Bundle signing, I need to configure both the platform of iPhoneSimulator and the platform of iPhone (select the dropdown menu to configure both). Both the signing identity and provisioning profile can't be automatic. The custom Entitlements needs to include Entitlemets.plist. I didn't set under the platform of iPhone. This change enables poping up permission page when simulating on iPhone, but not on the simulator.
Meanwhile, in Entitlement.pList, enabling capability of HealthKit might change the value of the key "com.apple.developer.healthkit". This might be a bug in Visual Studio and just don't manually change the value back because that will disable the healthkit capability.

Related

WebView2 Not Respecting Windows Account (allowSingleSignOnUsingOSPrimaryAccount)

I have a .NET 5.0 WinForms app that uses WebView2 with the evergreen runtime. I create my own environment with allowSingleSIgnOnUsingOSPrimaryAccount set to true (see snippet below). This results in the user opening up the app viewing our AzureAD fronted web app and authenticating against our app reg without the need to type in a user/pass or go through MFA.
var _cacheFolderPath = Path.Combine(Application.UserAppDataPath, "Myappname.exe.WebView2");
CoreWebView2EnvironmentOptions webViewEnvironmentOptions = new CoreWebView2EnvironmentOptions(allowSingleSignOnUsingOSPrimaryAccount: _config.UseWindowsAuth);
var webView2Environment = CoreWebView2Environment.CreateAsync(browserExecutableFolder: null, userDataFolder: _cacheFolderPath, options: webViewEnvironmentOptions).Result;
webView.EnsureCoreWebView2Async(webView2Environment);
On most machines, this works as expected, but there are a few machines where users are prompted for password. So a user that seamlessly logs in to our web app when logged into Windows on their primary machine may go to one of these particular machines and get prompted for an email/pass and MFA. I'm not seeing errors, event logs, etc....it just seems as though setting this value to true in code is simply being ignored or overridden.
I've tried to look for documentation related to Group Policy settings possibly being the cause, but there is not a lot I found regarding this for WebView2. Is there anything that is/can be set explicitly through GP, or some other mechanism that may be having some effect WebView2's behavior regarding allowSingleSignOnUsingOSPrimaryAccount?
Maybe try to go with something like this:
var options = new CoreWebView2EnvironmentOptions
{
AllowSingleSignOnUsingOSPrimaryAccount = true,
AdditionalBrowserArguments = "--auth-server-whitelist=_"
};
var userdatafolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Incognito", new Random().Next().ToString());
var environment = await CoreWebView2Environment.CreateAsync(null, userdatafolder, options: options);
Debug.WriteLine("InitializeAsync");
await WebView21.EnsureCoreWebView2Async(environment);
Debug.WriteLine($"WebView2 Runtime version: {WebView21.CoreWebView2.Environment.BrowserVersionString}");

Is it possible to retrieve Facebook Leads from ads that aren't active?

I've developed a C# Windows (desktop) app to retrieve ad leads details from Facebook, which works - but only active ads.
Is there a way to get the details for all adds even if they are not active, or is this a Facebook default setting.
The URL I'm using is...
https://graph.facebook.com/[pageid]?access_token=[token]&fields=leadgen_forms{leads{form_id,ad_name,platform,created_time,field_data,custom_disclaimer_responses,retailer_item_id,is_organic}}
yes you can get leads even if they are not active.
If you are using sdk you can use the following code
$ads = $adset->getAds(array(
AdFields::NAME,
AdFields::CONFIGURED_STATUS,
AdFields::EFFECTIVE_STATUS,
AdFields::CREATIVE,
));
foreach ($ads as $ad) {
$ad_id = $ad->id;
$ad_name = $ad->name;
if($ad->configured_status=="ACTIVE"){}
}
check complete code here https://stackoverflow.com/a/56500241/2588592

Cannot link bot to bot framework emulator

This is my current screen when I have tried to load my bot into the bot Framework Emulator:
And this is what I have entered within the setting for my bot:
But for some reason my bot framework emulator remains empty.
I have also tried setting the Endpoint URL to http://localhost:3979/api/messages but no luck. I am trying to run this locally off of visual studio.
Any help with this is much appreciated!
L. Full, if you followed the instructions from the Azure portal to create a QnA bot from a template, you will need to tweak the code a bit to have it work locally, and in turn work in the emulator.
After you have created your bot using the template (which it sounds like you have done), in ABS, going to Build (under Bot Management)> "Download zip file", you get a copy of your project locally.
If you look at the template Bot code, it works in Azure, because in summary, it is accessing your QnA credentials from within your Application Settings inside the Azure portal, but locally you will need to put the credentials somewhere like your .config file.
Ultimately what we'll have to do now is plug in your QnA credentials into your .config file of your project, as this is not automatically downloaded into the code when you download the zip.
Below I'm just using the QnA Template bot that you can find in the Azure portal (Create Resource > AI + Machine Learning > Web App Bot with Bot template of "Question and Answer")
In Web.config add key-value pairs for AzureWebJobsStorage (if using), QnAAuthKey, QnAKnowledgebaseId, and QnAEndpointHostName
Your own credential values can be found under Application Settings of the Azure portal
<appSettings>
<!-- update these with your Microsoft App Id and your Microsoft App Password-->
<add key="MicrosoftAppId" value="" />
<add key="MicrosoftAppPassword" value="" />
<add key="AzureWebJobsStorage" value="DefaultEndpointsProtocol=https...."/>
<add key="QnAAuthKey" value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
<add key="QnAKnowledgebaseId" value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
<add key="QnAEndpointHostName" value="https://YOURQNA.azurewebsites.net/qnamaker" />
<add key="QnASubscriptionKey" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</appSettings>
In your Dialog (QnA template as of 7/5/18 has default dialog file named BasicQnAMakerDialog.cs), instead of Utils (default in template), we'll use ConfigurationManager.AppSettings["KeyName"] to access the values you just placed in your Web.config:
Below you can see I've changed the variables (commented out) in QnA template to retrieve values using ConfigurationManager.AppSettings. You may also have to edit the variables in your if-statement as well, depending on the logic your own app needs.
In Root Dialog
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result as Activity;
// OLD
//var qnaAuthKey = GetSetting("QnAAuthKey");
//var qnaKBId = Utils.GetAppSetting("QnAKnowledgebaseId");
//var endpointHostName = Utils.GetAppSetting("QnAEndpointHostName");
// NEW
var qnaAuthKey = ConfigurationManager.AppSettings["QnAAuthKey"];
var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
var endpointHostName = ConfigurationManager.AppSettings["QnAEndpointHostName"];
// QnA Subscription Key and KnowledgeBase Id null verification
if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
{
// Forward to the appropriate Dialog based on whether the endpoint hostname is present
if (string.IsNullOrEmpty(endpointHostName))
await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
else
await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
}
else
{
await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
}
}
In the children Dialogs that get called by your root (BasicQnAMakerDialog for example), be sure to also replace anything that calls for a QnA key with ConfigurationManager.AppSettings["KeyName"].
For example in BasicQnAMakerDialog:
[Serializable]
public class BasicQnAMakerDialog : QnAMakerDialog
{
static readonly string qnaAuthKey = ConfigurationManager.AppSettings["QnAAuthKey"];
static readonly string qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
static readonly string endpointHostName = ConfigurationManager.AppSettings["QnAEndpointHostName"];
public BasicQnAMakerDialog() : base(new QnAMakerService(
new QnAMakerAttribute
(
qnaAuthKey,
qnaKBId,
"No good match in FAQ.",
0.5,
1,
endpointHostName
)))
{
}
}
One of the possible solution you can do is:
Right click your project in Solution Explorer in Visual Studio.
Click Properties.
Go to Debug Tab. Scroll down a little bit you will see Web Server Settings.. Check the URL and set it to new port. For example if it is: http://localhost:3798 change it to http://localhost:3979 or vice-versa. Changing the port number might solve your issue. Press Ctrl + S to save it.
Build the solution and re-run the project without Debugging (Ctrl +F5).
Open your Bot Framework Emulator and enter the URL that you mentioned in step 3 above.
Note: This doesn't mean it will 100% work, but this is one of the solution that I come across. I had the same problem and I solved it same way.
Hope this helps.

How can I get the HTML5 GeoLocation feature to work on GeckoFX v22 web browser control for WinForms using C#?

I wanted to implement a web browser control to Geo-location enable my WinForm desktop application.
I have successfully implemented the GeckoFX web browser in my WinForm project. The problem is when visiting a HTML5 Gelocation enabled website/address the "Allow/Deny access" popup does not appear.
As a result the Geo-location does not work. I have confirmed that Geo-location is enabled in preferences and have tested my WinForm using http://html5test.com and the control is listed as supporting Geo-location.
I have already tried to set permissions via the XPCom API for a specific domain so that the pop-up asking for permission would not be needed:
//CREATE nsSTRING
nsAUTF8String i = new nsAUTF8String("http://html5demos.com");
//CREATE NEW URI
var nsII = Xpcom.CreateInstance<nsIIOService>("#mozilla.org/network/io-service;1");
nsIURI uri = nsII.NewURI(i, "Unicode", null);
//CREATE PERMISSION MANAGER
var instancePM = Xpcom.CreateInstance<nsIPermissionManager>("#mozilla.org/permissionmanager;1");
//GEO PERMISSION SETTINGS
uint permission = Convert.ToUInt32(1);
uint expiretype = Convert.ToUInt32(0);
long expireTime = (long)0;
//ADD GEO PERMISSION SETTINGS (THIS SHOULD ALLOW GEO LOCATION TO JUST RUN WITH NO PROMPT)
instancePM.Add(uri, "geo", permission, expiretype, expireTime);
//TEST PERMISSIONS http://html5demos.com
uint testResult = instancePM.TestExactPermission(uri, "geo"); //RETURN SCORRECT SETTING OF 1 = OK
This did return a tested value of 1 but still the Geo-location does not work.
I have already seen this stackoverflow question:
Gecko for windows forms and geolocation. How to accept request for share my location?, but not really sure where to go from there.
I am sure I need to implement the call myself as the control is just the browser window and not all the other bits n bobs that make up a browser application. Does anyone have any suggestions or perhaps have already implemented Geo-location in GeckoFX using WinForms and C#?
Thanks
Andre

Not receiving push notification on iOS with Azure Notification Hub- didReceiveRemoteNotification is not called

I've followed these Notification Hub resources and have not been successful in receiving push notifications on my iOS device.
http://msdn.microsoft.com/library/jj927169.aspx
http://channel9.msdn.com/Blogs/Subscribe/Service-Bus-Notification-Hubs-Code-Walkthrough-iOS-Edition
I've checked, rechecked, and rechecked my setup:
Created a new notification hub: myhubname
Followed all the certificate provisioning steps.
Exported the private cert and uploaded to Notification Hub under Sandbox to ensure correct APS gateway is used
Downloaded the provisioning profile, which matches the bundle id for my project, auto detected for code signing, and compiles succesfully. Do NOT use the 'V2D7FJQXP.' of this string that shows up in your App ID if you are wondering: V2D7FJQXP.com.yourcompany.yourproject
Running on physical device - not under simulator
A demo application that is generating push notifications:
while (true)
{
string connectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSecretWithFullAccess("myhubname-ns", "…snip");
var hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, "myhubname");
var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
iosPayload.CustomFields.Add("inAppNotification", "Hello!");
hubClient.SendAppleNativeNotification(iosPayload.ToJsonString());
Console.WriteLine("Sent");
Thread.Sleep(20000);
}
No exceptions or issues are generated. Mangling any of the namespace, keys or hub names causes exceptions to be thrown, and fiddler response code from Azure is 2xx so all looks well.
I see registration occur correctly per code below:
I accepted push notifications on the device
I see the createDefaultRegistrationWithTags call once, then see that exists is true on subsequent calls.
No calls to didFailToRegisterForRemoteNotificationsWithError, which is OK
In the code example here: http://msdn.microsoft.com/library/jj927168.aspx, I have replaced sb:// with https://, as it would throw otherwise. Non-issue I'm thinking
:
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) deviceToken {
NSString* connectionString = [SBConnectionString stringWithEndpoint:#"https://gift-ns.servicebus.windows.net/" listenAccessSecret:#"…snip"];
self.hub = [[SBNotificationHub alloc] initWithConnectionString:connectionString notificationHubPath:#"gift-usw-dev"];
[self.hub refreshRegistrationsWithDeviceToken:deviceToken completion:^(NSError* error) {
if (error == nil) {
[self.hub defaultRegistrationExistsWithCompletion:^(BOOL exists, NSError* error2) {
if (error2 == nil) {
if (!exists) {
[self.hub createDefaultRegistrationWithTags:nil completion:^(NSError* error3) {
if (error3 != nil) {
NSLog(#"Error creating default registration: %#", error3);
}
}];
}
} else {
NSLog(#"Error retrieving default registration: %#", error2);
}
}];
} else {
NSLog(#"Error refreshing device token: %#", error);
}
}];
}
After starting the demo app, then running the iOS application, here is the resultant dashboard which I have no idea how to read effectively.
Thinking that my certificates were not correct, or something was lost between Azure and APS, I dug into troubleshooting the APS service and found this: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html and jumped to the section Problems Connecting to the Push Service
And ran this command:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert YourSSLCertAndPrivateKey.pem -debug -showcerts -CAfile server-ca-cert.pem
But I didn't have a .pem file (OSX), so I found this command to get them:
openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes
where keyStore.pfx was the renamed version of the .p12 exported from the Keychain for the push notification cert.
The command ran fine. What is happening?
I work in the Service Bus team on the Notification Hub feature.
As you already found out, the payload is not correctly formatted.
The CustomFields takes JSON encoded strings, so that you can set integer and objects as custom fields, for instance:
iosPayload.CustomFields.Add("inAppNotification", "{ \"my\": {\"new\" : "jsonObject"}}");
So if you want to add a string you have to put a json encoded string.
iosPayload.CustomFields.Add("inAppNotification", "\"Hello!\"");
Given the confusion, we might consider changing this behavior, or add a JSON safety check at serialization time.
Regarding the Notification Hub dashboard.
The notification hubs reports successful notifications when APNs accepts the notification. You can also visualize the graph for "Invalid payload" which will show if APNs rejected the notification from the notification hub.
Unfortunately I am not aware of a method to monitor the traffic on the device besides capturing the notification when the app is running with the callback: didReceiveRemoteNotification.
The AppleNotificationJsonBuilder does not serialize the payload correctly using the latest nuget of Service Bus preview features.
So, per the examples from msdn instructions:
var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
iosPayload.CustomFields.Add("inAppNotification", "Hello!");
Console.Log(iosPayload.ToJsonString());
Generates:
{"aps":{"alert":"This is a test"},"inAppNotification":Hello! This is a test}
Which is malformed. Well formed is "string"
{"aps":{"alert":"This is a test"},"inAppNotification":"Hello! This is a test"}
Custom payloads are fine per http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
One solution is to use Json.NET, or ping someone internally at Microsoft.
Open issues:
How could I have monitored network traffic off the iOS device?
Did the 'JSON' reach the device, but parse incorrectly? Or was it killed in the APS?
Azure Notification Hub dashboard did not help much
Hopefully this saves someone their afternoon.
Try this:
var iosPayload = AppleNotificationJsonBuilder.Create("This is a test");
iosPayload.CustomFields.Add("inAppNotification", "\"Hello!\"");
--> {"aps":{"alert":"This is a test"},"inAppNotification":"Hello!"}
More complicated ones:
iosPayload.CustomFields.Add("inAppNotification", "[ \"bang\", \"whiz\" ]");
--> {"aps":{"alert":"This is a test"},"inAppNotification":[ "bang", "whiz" ]}
iosPayload.CustomFields.Add("inAppNotification", "42");
--> {"aps":{"alert":"This is a test"},"inAppNotification":42}

Categories