Login with Xamarin.Auth in IOS Project is not working - ios

I'm using Xamarin.Auth to login to google and facebook, It works fine with Android Project but seem like presenter is not working with IOS, it can't opon the browser for login.
Here is my code to call Presenter in viewmodel
var authenticator = new OAuth2Authenticator(
clientId,
constants.FacebookScope,
new Uri(constants.FacebookAuthorizeUrl),
new Uri(constants.FacebookAccessTokenUrl),
null,
true
);
authenticator.Completed += OnAuthCompleted;
authenticator.Error += OnAuthError;
AuthenticationState.Authenticator = authenticator;
var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
presenter.Login(authenticator);
And Here is my AppDelegate in IOS project
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
Rg.Plugins.Popup.Popup.Init();
global::Xamarin.Forms.Forms.Init();
global::Xamarin.Auth.Presenters.XamarinIOS.AuthenticationConfiguration.Init();
//global::Xamarin.Auth.WebViewConfiguration.IOS.UserAgent = "moljac++";
XamEffects.iOS.Effects.Init();
FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
CachedImageRenderer.InitImageSourceHandler();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
public override bool OpenUrl
(
UIApplication application,
NSUrl url,
string sourceApplication,
NSObject annotation
)
{
// Convert iOS NSUrl to C#/netxf/BCL System.Uri - common API
Uri uri_netfx = new Uri(url.AbsoluteString);
// load redirect_url Page (send it back to Xamarin.Auth)
// for Url parsing and raising Complete or Error events
AuthenticationState.Authenticator.OnPageLoading(uri_netfx);
return true;
}
}

Related

Onesignal NotificationOpened doesn't work in ios app

I try to work with Onesignal Notifications in my ios app, created in Visual Studio with Xamarin. I want to make application open ViewController when user tap on notification, but it doesn't work. When user tap notification, app opens ViewController which was active when user application go to background.
Hope somebody show, where I made mistake
Here the code:
public class AppDelegate : UIApplicationDelegate
{
public static UIStoryboard Storyboard = UIStoryboard.FromName("Main", null);
public override UIWindow Window {
get;
set;
}
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
OneSignal.Current.StartInit("mykey")
.InFocusDisplaying(OSInFocusDisplayOption.None)
.HandleNotificationOpened(HandleNotificationOpened)
.EndInit();
OneSignal.Current.IdsAvailable(IdsAvailable);
return true;
}
void IdsAvailable(string userID, string pushToken)
{
GlobalUserInfo._token = userID;
}
private static void HandleNotificationOpened(OSNotificationOpenedResult result)
{
OSNotificationPayload payload = result.notification.payload;
Dictionary<string, object> additionalData = payload.additionalData;
if (additionalData != null)
{
UINavigationController NavigationController = (UINavigationController)Storyboard.InstantiateInitialViewController();
NotificationsViewController notificationsController = Storyboard.InstantiateViewController("NotificationsViewController") as NotificationsViewController;
NavigationController.PushViewController(notificationsController, true);
}
}
}
NotificationsViewController is simple list of all notification user received.
UPDATED
As I noticed, function HandleNotificationOpened does not work in iOS.
UPDATED
Error was found. I forgot, that I use OneSignal Init in other place. When I delete duplicate, HandleNotificationOpened begins work correctly.
You should find current root ViewController instead of creating a new instance. So please modify like this:
if (additionalData != null)
{
UINavigationController NavigationController = (UINavigationController)Window.RootViewController;
NotificationsViewController notificationsController = Storyboard.InstantiateViewController("NotificationsViewController") as NotificationsViewController;
NavigationController.PushViewController(notificationsController, true);
}
Moreover, if the root ViewController is a UITabBarController, please present this view controller(NotificationsViewController).

Warning: View is not in Window Hierarchy in Xamarin.Forms

I am doing a Xamarin project, Forms and I have integrated Xam.Plugins.Messaging to send SMS from my app. For this I have created a custom renderer in my iOS project with below code:
AppDelegate smsObj = new AppDelegate();
bool a= smsObj.ShowAndSendSMS(new string[] { "123" }, "Hi there");
And in my AppDelegate, I have the code as below:
public bool ShowAndSendSMS(string[] recipients, string body)
{
UIViewController sms = new UIViewController();
if (MFMessageComposeViewController.CanSendText)
{
MFMessageComposeViewController message = new MFMessageComposeViewController();
message.Finished += (sender, e) => {
message.DismissViewController(true, null);
};
message.Body = body;
message.Recipients = recipients;
sms.PresentModalViewController(message, false);
}
return true;
}
The problem I am facing is on my first-time app launch, the functionality to share SMS doesn't work and the debug log gives me warning like "Attempt to present on whose view is not in the window hierarchy!"
However, if I restart the app, the same functionality works like a charm. Any ideas from where i have made mistake?
I think the problem is with the fact that you're newing up an AppDelegate and calling the ShowAndSendSMS from there. iOS is going to new up that AppDelegate for you upon app startup, and you should always use that, as opposed to creating a new instance of AppDelegate (at least I've never seen a situation that called for a multi-AppDelegate-instance pattern). So, try this:
Create a helper class in your project like this (I don't really like the word "helper", but that's beside the point; name it something fitting for your project):
using Foundation;
using UIKit;
public class SmsHelper
{
public bool ShowAndSendSMS(string[] recipients, string body)
{
if (MFMessageComposeViewController.CanSendText)
{
UIViewController sms = new UIViewController();
MFMessageComposeViewController message = new MFMessageComposeViewController();
message.Finished += (sender, e) => {
message.DismissViewController(true, null);
};
message.Body = body;
message.Recipients = recipients;
sms.PresentModalViewController(message, false);
}
return true;
}
}
And then change your page renderer to consume it like this:
public class SMS_Ios: PageRenderer
{
private readonly TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
SmsHelper smsObj = new SmsHelper();
bool a = smsObj.ShowAndSendSMS(new string[] {"123"}, "Hi there");
}
}
And finally, remove ShowAndSendSMS from your AppDelegate.cs, since you'll be using your SMS helper going forward.
Let me know if that works for you.
If you have already installed the Xam.Plugins.Messaging package in the PCL and your platforms. You can just use the API from it in PCL to implement that without any special codes in your iOS platform.
You can just use the APIs of Xam.Plugins.Messaging in the PCL, like this:
// Send Sms
var smsMessenger = CrossMessaging.Current.SmsMessenger;
if (smsMessenger.CanSendSms)
smsMessenger.SendSms("+27213894839493", "Well hello there from Xam.Messaging.Plugin");
Reference: Messaging Plugin for Xamarin and Windows.

Xamarin iOS: Pass credentials over http

I am trying to pass credentials over http on my xamarin iOS project but its not working.
public partial class WebView : UIViewController
{
protected override void ViewDidLoad()
{
webView.LoadRequest(new NSUrlRequest(new NSUrl("https:example.com")));
webView.AllowsBackForwardNavigationGestures = true;
webView.NavigationDelegate = new WebViewDelegate(this);
}
}
public class WebViewDelegate : WKNavigationDelegate, INSUrlConnectionDataDelegate
{
public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
//base.DidReceiveAuthenticationChallenge(webView, challenge, completionHandler);
completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, new NSUrlCredential("username", "password", NSUrlCredentialPersistence.ForSession));
Console.WriteLine("We are authenticated");
return;
}
}
can anyone advise how to resolve this issue ?
Update:
DidReceiveAuthenticationChallenge is being called and is being called continuously in a loop. Instead of getting the expected page , I am getting a blank page and it just says "Authenticate"
From Apple's doc on PerformDefaultHandling:
Use the default handling for the challenge as though this delegate method were not implemented. The provided credential parameter is ignored.
Try UseCredential instead:
var crendential = new NSUrlCredential("user", "pass", NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, crendential);

iOS app-delegate method taking more than 17 sec

I have a xamarin iOS app which has to accept audio files from other apps. For eg: it accepts audio (.mp3) file from mailing app. In the OpenURL method I have the function to save file and create a new entry in xml file. This task I suppose is taking longer than 17 sec and the app crashes.
There is a comment in AppDelegate.cs // You have 17 seconds to return from this method, or iOS will terminate your application.
Here is the code in AppDelegate.cs:
public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
return this.Upload(url).Result;
}
async public Task<bool> Upload(NSUrl SharedUri)
{
await SomeUploadTask();
return true;
}
Can you try this,
I am not sure if this works or not.
Let's try not to block a method for more time.
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
Task.Run(() => SomeUploadTask());
return true;
}
private Task SomeUploadTask()
{
throw new NotImplementedException();
}

Invoke javascript method from ASP.NET MVC controller using SignalR

I am using SignalR in my application in order to be able to automatically invoke one JavaScript method whenever a specific action method of a ASP.NET MVC controller is accessed/hit/invoke. Everything works fine on the first hit. But when I try to hit the controller action second time my HttpWebRequest times out. Following is my controller:
public class ShowRoomHubController : Controller
{
public void UpdateDressingRoomData()
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ShowRoomHub>();
hubContext.Clients.All.acceptGreet();
}
}
My hub is as follow:
public class ShowRoomHub : Hub
{
public void Hello()
{
Clients.All.hello();
}
public void GreetAll()
{
// Call the addNewMessageToPage method to update clients.
Clients.All.acceptGreet("test now");
}
}
Calling UpdateDressingRoomData action from HttpWebRequest or HttpClient works for first time only then it starts timing out. Here is my console application code (HTTP client):
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:81/ShowRoomHub/UpdateDressingRoomData");
var response = request.GetResponse();
response.Close();
Or
var httpClient = new HttpClient();
var response = httpClient.GetAsync("http://localhost:81/ShowRoomHub/UpdateDressingRoomData").Result;
Here is my javascript client side code:
connection = $.hubConnection();
//Creating proxy
this.proxy = connection.createHubProxy('showRoomHub');
connection.logging = true;
//Publishing an event when server pushes a greeting message
this.proxy.on('acceptGreet', function () {
//alert('message');
$rootScope.$emit("acceptGreet", null);
});
//Starting connection
connection.start().done(function () {
//alert('started');
});
Any idea what's wrong in my code?

Resources