Using Shiny with UNO Platform - mobile

Looking for a way to use shinyorg/shiny nuget packages in cross-platform projects built on the UNO platform.
Facing some challenges beyond my (limited) skills for iOS development, I'm specifically looking for how to integrate Shiny.Core into the solution iOS project.
More precisely, I'm looking for where to put this initialization override:
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
Since when I try adding this in the Main.cs (Application class) of the iOS project, I can't find where to start...
The Main.cs class from the iOS project contains a static Main method (which is the main entry point of the app) in which a call to UIApplication.Main(args, null, typeof(App)); is made.
UIApplication being in fact UIKit.UIApplication
Following this guide https://github.com/shinyorg/shiny/tree/master/src/Shiny.Core where it's said:
* Add the following as the first line in your AppDelegate.cs - FinishedLaunching method
using Shiny;
this.ShinyFinishedLaunching(new YourStartup());
** IOS JOBS **
If you plan to use jobs in iOS, please do the following:
1. Add this to your AppDelegate.cs
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);

On iOS, the AppDelegate is actually the App class in your app, created from the default Uno Platform templates.
Windows.UI.Xaml.Application inherits from UIApplicationDelegate and provides a way declare this:
#if __IOS__
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
#endif
in order for the code for the other platforms to ignore this iOS-specific code

Related

Extending DialogService in Prism

On the Prism Library website there is a few notes about Simplify your Application Dialog APIs.
https://prismlibrary.com/docs/wpf/dialog-service.html
Let's say I have a Solution with multiple projects, MainProject, Modules.Module1, CoreProject. So creating this DialogServiceExtensions class in my Core project.
public static class DialogServiceExtensions
{
public static void ShowNotification(this IDialogService dialogService, string message, Action<IDialogResult> callBack)
{
dialogService.ShowDialog(nameof(NotificationDialog), new DialogParameters($"message={message}"), callBack, "notificationWindow");
}
}
I also put NotificationDialog and NotificationDialogViewModel in my Core project
I can call it at any project/module, but the question is how can I tell prism that NotificationDialog ViewModel is NotificationDialogViewModel.
Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
}
Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
If the app wants to show a dialog, you have to do this, as modules are essentially optional (they can be swapped out after deployment or they don't need to exist).
If a module wants to show a dialog (and not the app), you can decide whether it's part of your app's interface to its modules (then put the registration in the app) or not (then put it in the module, each module that uses it, that is, registrations may override each other).

.net conditional compilation according to referrer assembly

I have a WCF service interface in a portable class library referenced by both silverlight and service implementer. It is like this:
#if SILVERLIGHT
[ServiceContract]
public interface IService
{
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginTest(AsyncCallback cb, object state);
void EndTest(IAsyncResult ar);
}
#else
[ServiceContract]
public interface IService
{
[OperationContract]
void Test();
}
#endif
now I referenced it from SL and got a compilation error which shows that the contract is sync version and not supported by SL. I think the reason is that there is no SILVERLIGHT defined in the portable library. But I don't want to define one because it is referenced by another non-silverlight libraries. Is there any way to let compiler automatic select right version to compile according to the category of the referrer project without modifying the portable library?
No. You would need to have two separate assemblies with the different APIs.
You might be able to keep a single portable library if you just use an async method returning Task instead of the Begin/End pattern. You can get async support on Silverlight with the Microsoft.Bcl.Async package, but I'm not sure if you can use that for WCF on Silverlight or not.

Registering Startup Class In Nancy Using AutoFac Bootstrapper

I've been reading through a lot of the Jabbr code to learn Nancy and trying to implement many of the same patterns in my own application. One of the things I can't seem to get working is the concept of an on application start class. The Jabbr code base has an App_Start folder with a Startup.cs file (here) in it with the following implementation.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
...
SetupNancy(kernel, app);
...
}
}
private static void SetupNancy(IKernel kernel, IAppBuilder app)
{
var bootstrapper = new JabbRNinjectNancyBootstrapper(kernel);
app.UseNancy(bootstrapper);
}
When I tried to do something similar to that in my project the Startup.cs file was just ignored. I searched the Jabbr code base to see if it was used anywhere but I wasn't able to find anything and the only differences I could see is Jabbr uses Ninject while I wanted to use AutoFac
Is there a way to register a startup class in nancy?
Take a look at my project over on GitHub, you'll be interested in the Spike branch and may have to unload the ChainLink.Web project to run I can't remember.
I had some trouble finding a way to configure the ILifetimeScope even after reading the accepted answer here by TheCodeJunkie. Here's how you do the actual configuration:
In the bootstrapper class derived from the AutofacNancyBootstrapper, to actually configure the request container, you update the ILifetimeScope's component registry.
protected override void ConfigureRequestContainer(
ILifetimeScope container, NancyContext context)
{
var builder = new ContainerBuilder();
builder.RegisterType<MyDependency>();
builder.Update(container.ComponentRegistry);
}
The application container can be updated similarly in the ConfigureApplicationContainer override.
You should install the Nancy.Bootstrappers.Autofac nuget, inherit from the AutofacNancyBootstrapper type and override the appropriate method (depending on your lifetime scope requirements: application or request). For more info check the readme file https://github.com/nancyfx/nancy.bootstrappers.autofac
HTH
After following the advice from TheCodeJunkie you can use the Update method on the ILifetimeScope container parameter which gives you a ContainerBuilder through an Action:
protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
{
container.Update(builder =>
{
builder.RegisterType<MyType>();
});
}

System.TypeLoadException was unhandled / Inheritance security rules violated while overriding member

Can you create a .NET 4 version of your app for testing was the bosses' innocent question - sure!
But after I changed our 27 projects in our Winforms application to .NET 4, and recompiled, when launching the app, I get
System.TypeLoadException was unhandled
Message=Inheritance security rules violated while overriding member:
'MyCustomORM.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'.
Security accessibility of the overriding method must match the security accessibility of the method being overriden.
Hmmm.....
MyCustomORM does indeed implement the ISerializable interface and thus has this method
[Serializable]
public abstract class MyCustomORM: IMyCustomORM, ISerializable, ICloneable, ISecurable
{
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// do stuff here.......
}
}
and I also have two classes that derive from Exception that override the GetObjectData method.
But what could be wrong here?? Googling around I found some additional attributes to stick onto my method and namespace - so I did:
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
namespace MyApplication.ORM
{
[Serializable]
public abstract class MyCustomORM: IMyCustomORM, ISerializable, ICloneable, ISecurable
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// do stuff here.......
}
}
}
but that doesn't change anything.....
The exception happens even before my first line of code in my static Main() method is reached....
I've combed through the project and removed any references to old .NET 1.1 libraries (yes, the app is that old.....) and replaced them with their .NET 4 counterparts (mostly log4net). Still no luck....
Any ideas??
Is the assembly in which the MyCustomORM class resides marked with SecurityTransparentAttribute? If so, the problem stems from changes in the security transparency model between .NET 3.5 and .NET 4.0. For your testing scenario, you may wish to simply opt into using the older transparency mechanism. To do so, add the following assembly-level attribute:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
For more information on the differences between the Level1 and Level2 transparency models, see http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx.
I know this is pretty old, but I ran into this issue with one of my assemblies recently. It only occurred on some machines and was very difficult to determine what was causing it. I didn't just want to put security rule adjustments in, so after much searching I ran across the SecAnnotate tool that is included with Visual Studio.
Using SecAnnotate to Identify Transparency Violations
Using the tool I was able to determine that one of my assemblies was referencing an older version of a dll which contained some security attributes which were causing the problem. Updating the reference fixed the issue.
The SecAnnotate tool seems like a great way to identify any violations that you may have accidentally overlooked or didn't know about.
Hope this helps someone.

MoSync native UI and deployment

Does anybody know if it's possible to use MoSync to create apps with a native UI?
From what I can tell all the UI/graphics is done with their own UI library and don't the the native ui elements.
Also, now that I'm creating a question anyway. Why does MoSync target specific telephones? Is it not possible to just create a generic install package for whatever platform you're targeting? (like .apk files for android). If it's possible it should make distribution easier.
The standard way up til now has been to create a custom non-native UI through the MAUI library. As of 2011-02-03 there is an experimental native UI framework for Android and iPhone. The user documentation is however rather non-existent, so you will have to check the source code for more information. I'll point you in the right direction, for accessing native widgets you use the maWidget* system calls defined in: maapi.idl. For a list of available widgets and properties see: Types.java. Note that this API is likely to change and be expanded.
A simple native UI example:
#include <MAUtil/Moblet.h>
#include <IX_WIDGET.h>
class NativeUIMoblet : public MAUtil::Moblet
{
public:
NativeUIMoblet()
{
// Create a screen
MAHandle mainScreen = maWidgetCreate( "Screen" );
// Create a 'Hello World' label
MAHandle helloLabel = maWidgetCreate( "Label" );
maWidgetSetProperty( helloLabel, "text", "Hello World!" );
// Add the label to the screen
maWidgetAddChild( mainScreen, helloLabel );
// Show the screen
maWidgetScreenShow( mainScreen );
}
void keyPressEvent(int keyCode, int nativeCode)
{
}
void keyReleaseEvent(int keyCode, int nativeCode)
{
}
};
extern "C" int MAMain()
{
MAUtil::Moblet::run( new NativeUIMoblet( ) );
return 0;
};
Presently, there is no emulator support available, so you will have to run it on a device or in a specific SDKs emulator.
The reason for targeting a specific phone is that there exists bugs specific to a certain device. But in the recent nightly builds of MoSync you can build for generic platforms like Android 2.1.
http://www.mosync.com/blog/2011/03/using-nativeeditbox

Resources