Xamarin Forms Multi-App - MacOS project not showing Xamarin forms - c#

Edit: Added link to project I created:
https://drive.google.com/file/d/1A4XGKdxeC22_wqtNEtenLxYbgCp3I_dA/view?usp=sharing
I have a very basic multi-platform application created I Visual Studio 2019 (Windows 10) with 4 projects:
Source Project
Android
iOS
UWP
I added the MacOS project following these instructions:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/platform/other/mac
The application compiles but loads a blank form and does not show any of the Xamarin forms as per the UWP, iOS and Android apps.
I next created an empty Multi-Platform application natively on a Mac - added the MacOS as per the above instructions and get the same outcome, a blank form loading.
The code I am using in the Mac project is the link above.
// AppDelelegate.cs
using AppKit;
using Foundation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;
using pbTrader;
namespace pbTrader.MacOS
{
[Register("AppDelegate")]
public class AppDelegate : FormsApplicationDelegate
{
NSWindow window;
public AppDelegate()
{
var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Titled;
var rect = new CoreGraphics.CGRect(200, 1000, 1024, 768);
window = new NSWindow(rect, style, NSBackingStore.Buffered, false);
window.Title = "Xamarin.Forms on Mac!"; // choose your own Title here
window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}
public override NSWindow MainWindow
{
get { return window; }
}
public override void DidFinishLaunching(NSNotification notification)
{
Forms.Init();
LoadApplication(new App());
base.DidFinishLaunching(notification);
}
public override void WillTerminate(NSNotification notification)
{
// Insert code here to tear down your application
}
}
}
// Main.cs
using AppKit;
namespace pbTrader.MacOS
{
static class MainClass
{
static void Main(string[] args)
{
NSApplication.Init();
NSApplication.SharedApplication.Delegate = new AppDelegate(); // add this line
NSApplication.Main(args);
}
}
}

Related

Xamarin Android iOS FirebasePushNotificationPlugin not receive message but token receves

i'm using xamarin iOS FirebasePushNotificationPlugin for cloud messages, but i'm receiving the token but i can not receive any notification. CrossFirebasePushNotification.Current.OnNotificationReceived even not firing.
here is how my appDelegate looks likes.
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using Plugin.FirebasePushNotification;
using UIKit;
namespace onlinefirebase.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
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)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
FirebasePushNotificationManager.Initialize(options, true);
FirebasePushNotificationManager.CurrentNotificationPresentationOption =
UserNotifications.UNNotificationPresentationOptions.Alert |
UserNotifications.UNNotificationPresentationOptions.Badge;
return base.FinishedLaunching(app, options);
}
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken);
}
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
FirebasePushNotificationManager.RemoteNotificationRegistrationFailed(error);
}
// To receive notifications in foregroung on iOS 9 and below.
// To receive notifications in background in any iOS version
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired 'till the user taps on the notification launching the application.
// If you disable method swizzling, you'll need to call this method.
// This lets FCM track message delivery and analytics, which is performed
// automatically with method swizzling enabled.
FirebasePushNotificationManager.DidReceiveMessage(userInfo);
// Do your magic to handle the notification data
System.Console.WriteLine(userInfo);
completionHandler(UIBackgroundFetchResult.NewData);
}
}
}
Here is how i receive the notification
using System;
using Plugin.FirebasePushNotification;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace onlinefirebase
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
CrossFirebasePushNotification.Current.OnTokenRefresh += (s, p) =>
{
System.Diagnostics.Debug.WriteLine($"TOKEN : {p.Token}");
};
CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
{
System.Diagnostics.Debug.WriteLine("Received");
};
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
}
I have verified
. Enabled Background Mode -> Remote Notifications
. Info.plist -> "FirebaseAppDelegateProxyEnabled" boolean -> No
I'm successfully getting the token, but i can not receive the notification.
Issue is based on Apple key, apple key should be upload to firebase cloud panel and it'll work

Create Revit Plugin With Windows Form

I've been trying to create a plugin for Revit 2017 with Visual Studio 2015 with windows Form.
Unfortunately I've not found any documentation online for doing so (if you have links, i'll be happy to give them a look)
I've built a simple form using a Listbox and a select button
The Listbox shows all the doors in a Revit project
The select button selects all the selected doors from the Listbox and selects them in the Revit project (that's a lot of selects ...)
It's a test solution, to see how it all works.
WeWillSee class is the class implementing the main RevitAPI function Execute:
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
namespace Test2 {
[Transaction(TransactionMode.Manual)]
class WeWillSee : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiapp = commandData.Application;
/*UIDocument uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;*/
try
{
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
System.Windows.Forms.Application.Run(new Form(commandData));
//System.Windows.Forms.Form wf = new Form1(uiapp);
}
catch (Exception e)
{
TaskDialog.Show("Error", e.ToString());
return Result.Failed;
}
return Result.Succeeded;
}
}
}
The Form I want to open (the rest in not important):
namespace Test2
{
public partial class Form : System.Windows.Forms.Form
{
private UIApplication uiapp;
private UIDocument uidoc;
private Document doc;
public Form(ExternalCommandData commandData)
{
InitializeComponent();
uiapp = commandData.Application;
uidoc = uiapp.ActiveUIDocument;
doc = uidoc.Document;
}
And finally the Program.cs file (the one causing me problems):
namespace Test2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(/*Can't call ExternalCommandData on static class*/));
}
}
}
Thanks for any help you can offer! :)
I don't think you even need the Program.cs class file in your project the way you have it written.
Here is a simple Revit add-in implementing an external command that creates and displays a Windows form on the fly:
http://thebuildingcoder.typepad.com/blog/2012/05/the-schedule-api-and-access-to-schedule-data.html
You don't need to do the Application.Run kind of things (that's only for standalone windows applications). You don't need the Program.cs thing at all.
You can just do as you started to:
Form1 wf = new Form1(uiapp);
if (wf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
return Result.Success

How to calculate App Idle Time in MVVMCross Xamarin.iOS?

I am developing iOS Universal Application in Xamarin.iOS using MVVMCross. I want to calculate App Idle time I found the following useful help
iOS:Convert ObjC code to C#, How to know the time app has been idle
But there is an issue when i try to use this with MVVMCross which is that
AppDelegate.cs in MvvmCross is inherited from MvxApplicationDelegate.cs
I am unable to override the following event in AppDelegate because it is not overriding UIApplication
public override void SendEvent (UIEvent uievent)
{
base.SendEvent (uievent);
var allTouches = uievent.AllTouches;
if (allTouches.Count > 0) {
var phase = ((UITouch)allTouches.AnyObject).Phase;
if (phase == UITouchPhase.Began || phase == UITouchPhase.Ended)
ResetIdleTimer ();
}
}
You were close to the answer.
In a default MvvMCross project, there is a Main.cs, that contains a Application class.
You just have to replace the null in following line with your UIApplication's child class name
UIApplication.Main(args, null, "AppDelegate");
e.g If your class name is MyApplication which is inherited from UIApplication then it should be like
UIApplication.Main(args, "MyApplication", "AppDelegate");
and add a class MyApplication
[Register("MyApplication")]
public class MyApplication : UIApplication
{
public override void SendEvent(UIEvent uievent)
{
base.SendEvent(uievent);
var allTouches = uievent.AllTouches;
if (allTouches.Count > 0)
{
var phase = ((UITouch)allTouches.AnyObject).Phase;
if (phase == UITouchPhase.Began || phase == UITouchPhase.Ended)
ResetIdleTimer();
}
}
}

How change the global tint color in Xamarin forms of the iOS application?

How can I change the global tint color of my iOS app in a Xamarin forms project (C#)?
The global iOS tint color can be set via UIApplication.KeyWindow when it becomes available, the earliest after the application finished launching:
using Foundation;
using UIKit;
namespace MyApp.iOS
{
[Register("AppDelegate")]
public class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
var result = base.FinishedLaunching(uiApplication, launchOptions);
uiApplication.KeyWindow.TintColor = UIColor.Blue;
return result;
}
}
}
Add following code in your applications finished launching method in Xamarin.iOS Project.
Boolean result = base.FinishedLaunching(app, options);
UIApplication.SharedApplication.KeyWindow.TintColor = UIColor.Green;
return result;

DismissViewController sometimes causes the program to freeze or crash

I have the following MonoTouch program:
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System;
namespace Experiment
{
// This is just for the example, I use a singleton in my app to do this.
public class AppSettings
{
public static bool IsLoggedIn = false;
}
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
UIViewController baseViewController = new RootViewController();
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.AddSubview(baseViewController.View);
window.MakeKeyAndVisible();
return true;
}
static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate");
}
}
public class RootViewController : UITableViewController
{
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
if (!AppSettings.IsLoggedIn) {
this.PresentViewController(new LoginPopupController(), false, () => {});
}
}
}
public class LoginPopupController : UIViewController
{
public override void LoadView()
{
View = new UIView(UIScreen.MainScreen.ApplicationFrame);
View.BackgroundColor = UIColor.White;
UIButton button = new UIButton();
button.SetTitle("press me", UIControlState.Normal);
button.Frame = new RectangleF(50, 50, 80, 80);
button.TouchUpInside += delegate {
LoginSucceeded();
};
button.BackgroundColor = UIColor.Purple;
View.AddSubview(button);
}
public void LoginSucceeded()
{
AppSettings.IsLoggedIn = true;
Console.WriteLine("This line causes multiple problems at random");
DismissViewController(true, () => {});
}
}
}
It has two controllers the RootViewController and the LoginPopupController. The FinishedLoading method adds the RootViewController to the window. The RootViewController in the ViewDidAppear method checks if the app is logged in. If not, it will present the LoginPopupController.
The LoginPopupController has a button, which when pressed will set IsLoggedIn to true, and dismiss itself.
Basically, I want a login window to appear if the user isn't logged in, and then dismiss itself after it has entered login details into a singleton settings object.
However, the app is very unreliable at the moment. Pressing the "press me" button can cause the following to happen at random:
Work as expected
Freeze the app
Crash the app
Do nothing on first press, crash the app on the second press
The Console.WriteLine line has a big effect on this - if you remove it the code succeeds more often (but not always).
Can anyone figure out what is causing this problem? It seems like a race condition (as the results change between runs), however I can't figure out what could be causing that.
I'm running the code on the simulator using iOS 5.1. I have MonoTouch version 5.2.10 installed with Mono 2.10.8.
I have done two changes in your code and it never crashed, at least for my number of tries.
First, move the UIButton declaration to the class:
UIButton button;
public override LoadView()
{
//...
}
Second, initialize the button with the UIButton.FromType(UIButtonType) static method:
button = UIButton.FromType(UIButtonType.Custom);
The UIButton() constructor had problems in previous versions of MonoTouch. In some versions it was not even available. I could not find anything specific for its current state, however creating buttons with the static method is the normal way to go, according to Apple docs.

Categories