How to request Contacts and Calendar Permissions on XamarinMac? - c#

I'm trying to access the ContactStore of MacOS App, did the following implementation
public void Contacts()
{
//Starting
var store = new CNContactStore();
store.RequestAccess(CNEntityType.Contacts, async (bool granted, NSError error) =>
{
if (granted)
{
//Query things
}
});
}
The thing is that the Authorize screen never popup, and the Permission always say denied.
If I go to settings to remove that record, the app is not there.
Can someone please point me to the light?

It works for me with those two lines:
var contactStore = new CNContactStore();
var status = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts);
It could be also that you need to set NSContactsUsageDescription in info.plist.

Related

Multiple destination from xamarin forms

I have functional, which open google maps with route but with one point of destination. I want add several points of stop. How I can do it? See my code:
public Command OpenMap
{
get
{
return _openMap ?? (_openMap = new Command(async () =>
{
await Xamarin.Essentials.Map.OpenAsync(Position.Latitude, Position.Longitude, new MapLaunchOptions
{
Name = Address.Name,
NavigationMode = NavigationMode.Driving
});
}));
}
}
I use Xamarin.Essentials.Map maybe exists another way?
In the end, I want that after btn click have been open google maps with navigation route which consists of several destination.

SharingCapability SharePoint Online Site Collection c#

I want to set the SharingCapability property after provisioning my site collection. I used the documentation of PnP, as you can find here (External Sharing APIs for SharePoint and OneDrive for Business (Core.ExternalSharing))
When I set the property to 'ExternalUserAndGuestSharing', nothing happens. The site collection is still disabled to share with external.
Here is my code:
public static void SetSharingCapability(string fullWebUrl, ClientContext context)
{
Tenant tenant = new Tenant(context);
SiteProperties siteProp = tenant.GetSitePropertiesByUrl(fullWebUrl, true);
context.Load(siteProp);
context.ExecuteQuery();
siteProp.SharingCapability = SharingCapabilities.ExternalUserAndGuestSharing;
siteProp.Update();
context.ExecuteQuery();
}
Do you habe any suggestions for solving the 'problem'?
Most likely the moment once settings (SharingCapability) are applied, the operation itself is not yet completed and that the reason why updated settings are not yet reflected:
siteProp.SharingCapability = SharingCapabilities.ExternalUserAndGuestSharing;
siteProp.Update();
context.ExecuteQuery(); //<- even though the query is submitted to the server there is no guarantee at this moment the update operation is completed
To ensure the update operation is completed you could consider the following solution:
public static void SetSharingCapability(string fullWebUrl, ClientContext context)
{
Tenant tenant = new Tenant(context);
SiteProperties siteProp = tenant.GetSitePropertiesByUrl(fullWebUrl, true);
siteProp.SharingCapability = SharingCapabilities.Disabled;
siteProp.Update();
context.ExecuteQuery();
siteProp = tenant.GetSitePropertiesByUrl(fullWebUrl, true);
context.Load(siteProp, p => p.Status);
context.ExecuteQuery();
while (siteProp.Status == "Updating")
{
Thread.Sleep(TimeSpan.FromSeconds(1));
siteProp = tenant.GetSitePropertiesByUrl(fullWebUrl, true);
context.Load(siteProp);
context.ExecuteQuery();
}
}

Get UserName in a Windows 10 C# UWP Universal Windows app

I am struggling with yet another simple task in the Windows 10 UWP world.
I simply need the UserName of the current Windows user. Environment.UserName is just not a thing in UWP. And no amount of searching the web has helped so far. Hence my post here.
Anyone? Is this just not possible now?
Add "User Account Information" capability to your app in the Package.appxmanifest
Use this code to get user display name:
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
IReadOnlyList<User> users = await User.FindAllAsync();
var current = users.Where(p => p.AuthenticationStatus == UserAuthenticationStatus.LocallyAuthenticated &&
p.Type == UserType.LocalUser).FirstOrDefault();
// user may have username
var data = await current.GetPropertyAsync(KnownUserProperties.AccountName);
string displayName = (string)data;
//or may be authinticated using hotmail
if(String.IsNullOrEmpty(displayName))
{
string a = (string)await current.GetPropertyAsync(KnownUserProperties.FirstName);
string b = (string)await current.GetPropertyAsync(KnownUserProperties.LastName);
displayName = string.Format("{0} {1}", a, b);
}
text1.Text = displayName;
}
// get username
public string UserNameStr { get; set; } = WindowsIdentity.GetCurrent().Name;
This will get you the full domain\username.
As I can see, there is a User class available (UWP): https://msdn.microsoft.com/en-us/library/windows/apps/windows.system.user.aspx
Try this:
var users = await User.FindAllAsync(UserType.LocalUser);
var name = await users.FirstOrDefault().GetPropertyAsync(KnownUserProperties.AccountName);
You can also pickup the User who launched the app from the Application.OnLaunched method see here.
You still need to declare the User Information capability in you manifest though.
quick example (Ellipses denote non applicable generated code):
sealed partial class App : Application
{
...
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
User currentUser = e.User;
...
}
...
}

Office 365 API MVC Authentification

I am using the MVC Office 365 API libraries and I would like to archieve the following thing: Logging into User-Accounts where I know the username / password and then get there calendar entries.
What I have so far is code that makes this redirect and ask the user to enter credentials. But how can I log in for them wihtout asking? The idea is to get the calendar entries for every user (lets say 20 of them) automatically every few minutes.
public static async Task<IEvent[]> GetCalendarEvents()
{
var client = await EnsureClientCreated();
// Obtain calendar event data
var eventsResults = await (from i in client.Me.Events
where i.End >= DateTimeOffset.UtcNow
select i).Take(10).ExecuteAsync();
var events = eventsResults.CurrentPage.OrderBy(e => e.Start).ToArray();
return events;
}
public static async Task<ExchangeClient> EnsureClientCreated()
{
var _discoveryContext = await CacheHelper.GetDiscoveryContext();
var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
return new ExchangeClient(ServiceEndpointUri, async () =>
{
return (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"),
new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret),
ServiceResourceId))
.AccessToken;
});
}
Late answer I know. But if your still looking for this, or anyone else, this blog may be what your looking for.
http://blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
A daemon/service app will get calendar events on behalf of a user, proving the user and the app are registered under the same tennat/organisation.

Facebook SDK and threads (WebBrowser control)

This is probably more of a general c# and simple threading question than it is a Facebook SDK question, but I may be wrong. But I could really use some help. I am reusing the sample code that comes with the SDK which includes a FacebookLoginDialog class. I am currently using it like this. In my GetMessages, GetFriendRequests, and other Get* classes, I always try/catch calls like this:
try
{
var result = (IDictionary<string, object>)fb.Get("/me/inbox");
}
catch (FacebookOAuthException e)
{
FacebookSession.Login();
}
Here's my login method in my FacebookSession class
public static void Login()
{
var fbLoginDialog = new FacebookLoginDialog(APP_ID, EXTENDED_PERMISSIONS);
DialogResult dr = fbLoginDialog.ShowDialog();
DisplayAppropriateMessage(fbLoginDialog.FacebookOAuthResult);
}
And here is the constructor in my FacebookLoginDialog class (this is where I have the problem)
public FacebookLoginDialog(string appId, string[] extendedPermissions, bool logout)
{
try
{
var oauth = new FacebookOAuthClient { AppId = appId };
var loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "display", "popup" }
};
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
loginParameters["scope"] = scope.ToString();
}
var loginUrl = oauth.GetLoginUrl(loginParameters);
if (logout)
{
var logoutParameters = new Dictionary<string, object>
{
{ "next", loginUrl }
};
System.Uri uri =
new Uri("https://www.facebook.com/logout.php?next=" +
"https://www.facebook.com/connect/login_success.html&access_token=" +
FacebookSession._accessToken);
this.navigateUrl = uri;
}
else
{
this.navigateUrl = loginUrl;
}
InitializeComponent(); // crash here... sometimes
}
catch (Exception e)
{
//Log error message
}
}
Sorry for all the code, but now the problem. This code works fine the first time through. If I go to my facebook applications permissions page in Facebook and remove the app (that is, remove its permissions), while my desktop app here is NOT running, when I do start it up, it sees that it does not have permission and shows the login dialog. I can save the access_key and it will work just fine. But if I go to the facebook apps page and yank the permissions while my desktop app is running, then bad things happen. I get an error message about the activex control cannot be instantiated because the current thread is not in a single-threaded apartment. I have seen many posts here that say all you have to do is put [STAThread] above your main(), and my code has that. I have also tried creating a new thread to call the FacebookLoginDialog, but not only did that not work, but since my code is really not designed to run in multiple threads, that started causing more problems.
Is there a simple solution to all this, or do I need to redesign my code so that it properly runs in multiple threads? Or should I just live with the program crashing in those few instances when someone monkeys with the facebook permissions while my app is running?

Categories