'UIApplication.Main(string[]?, string?, string?)' is obsolete: 'Use the overload with 'Type' instead of 'String' parameters for type safety.' [duplicate] - xamarin.ios

After upgrade my Xamarin.Forms version to 5.0.0.2244, I'm getting the following warning in Main.cs file inside my iOS project:
Method UIKit.UIApplication.Main is obsolete: Use the overload with Type instead of String parameters for type safety.
This my Main.cs file:
using UIKit;
namespace LindeGctMobileApplication.iOS
{
public class Application
{
private static void Main(string[] args)
{
UIApplication.Main(args, null, "AppDelegate"); // << warning
}
}
}
What do I need to change to remove this warning?

Class reference through a string is now deprecated. You need to change this line:
UIApplication.Main(args, null, "AppDelegate");
to this:
UIApplication.Main(args, null, typeof(AppDelegate));
In that way, you explicitly inform the type of the class.

Related

Groovy execute code using custom annotation

I would like to execute a function (with parameters) through an annotation tag in a groovy script.
If we execute a method in our groovy script with this annotation it would print in the console (stderr) a custom message like:
warning: '<function_name>' is deprecated [[Use '<Deprecated.instead>' instead.][More info: '<Deprecated.more_info>']]
So, I have created a custom annotation like this
public #interface Deprecated {
public String instead() default null
public String more_info() default null
}
The goal is to use it like this:
def new_call() {
//new version of the method
}
#Deprecated(instead="new_call")
def call() {
//do something
}
In my example, it would output like this:
warning: 'call' is deprecated. Use 'new_call' instead.
I saw this post Groovy: How to call annotated methods, it's over 7 years old now but looks good so i'll look deeper.
I saw also Delegate.deprecated but i'm not sure if that's what i want
I'm not sure I am doing right. So if you have any advice or suggestions, I'll be happy to hear you.
Simple AOP Approach
This is very-very basic implementation with groovy out-of the box.
Deprecated Annotation
#Target([ElementType.METHOD])
#Retention(RetentionPolicy.RUNTIME)
#interface Deprecated {
String instead() default 'null'
String more_info() default 'null'
}
Class which should get this functionality
The class has to implement GroovyInterceptable - invokeMethod.
class SomeClass implements GroovyInterceptable {
#Override
def invokeMethod(String name, args) {
DeprecatedInterception.apply(this, name, args)
}
def new_call() {
println('new_call invoked')
}
#Deprecated(instead = 'new_call', more_info = '... the reason')
def depr_call() {
println('depr_call invoked')
}
}
Interception Util
import org.codehaus.groovy.reflection.CachedMethod
class DeprecatedInterception {
static apply(Object owner, String methodName, Object args) {
MetaMethod metaMethod = owner.metaClass.getMetaMethod(methodName, args)
Deprecated d = extractAnnotation(metaMethod)
if (d) {
println("warning: '$methodName' is deprecated. Use '${d.instead()}' instead. More info: '${d.more_info()}'")
}
// handle methods with var-args
metaMethod.isVargsMethod() ?
metaMethod.doMethodInvoke(owner, args) :
metaMethod.invoke(owner, args)
}
static Deprecated extractAnnotation(MetaMethod metaMethod) {
if (metaMethod instanceof CachedMethod) {
metaMethod.getCachedMethod()?.getAnnotation(Deprecated)
} else {
null
}
}
}
Simple Test
Just check that no exceptions/errors..
class TestWarnings {
#Test
void test() {
new SomeClass().with {
new_call()
depr_call()
}
}
}
Output:
new_call invoked
warning: 'depr_call' is deprecated. Use 'new_call' instead. More info: '... the reason'
depr_call invoked
Disclaimer
This should work for most cases, but has some limitations:
will not work for static methods (unless invoked on Object instance)
you have to implement GroovyInterceptable per each class, to apply
you might faced with some side-effects in some groovy syntax or features (at least I've found the issue with vararg methods invocation, but this already fixed)
So this should be tested and potentially improved before widely using for some production projects.
Other options:
Shortly, because implementation might be more complex (not sure, at least I not able to provide some example in a short time), but potentially this is more solid.
Adding AST Transformations.
Use some AOP library.

C#8 nullable : string.IsNullOrEmpty is not understood by compiler as helping for guarding against null

I am using C# 8 with .NET framework 4.8
I'm currently guarding against a potential string that can be null with IsNullOrWhitespace (same problem with IsNullOrEmpty) , but the compiler is still complaining :
public MyImage? LoadImage(string? filename)
{
if (string.IsNullOrWhiteSpace(filename))
{
return null;
}
return OtherMethod(filename); // here : warning from Visual Studio
}
// signature of other method :
public MyImage OtherMethod(string filepath);
currently, I have workarounds to make the compiler understand :
use null forgiving operator filename!
disable warning by using #pragma warning disable CS8604 // Possible null reference argument.
add another check for null if(string == null || string.IsNullOrWhitespace(filename))
But none of the seems satisfactory, mainly because I'll need to repeat the workaround for each call to IsNullOrEmpty.
Is there any other way to tell the compiler that IsNullOrEmpty effectively guards against null ?
If you don't have .net standard 2.1 or .net core 3, the IsNullOrEmpty is not nullable ready. So, I would create an extension method for this:
#nullable enable
public static class StringExt {
public static bool IsNullOrEmpty([NotNullWhen(false)] this string? data) {
return string.IsNullOrEmpty(data);
}
}
#nullable restore
You also need to activate NotNullWhen attribute like this:
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NotNullWhenAttribute : Attribute {
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
public bool ReturnValue { get; }
}
}

Is the #Repeatable annotation not supported by Groovy?

I'm coding in Groovy and am having trouble with the Java 8 #Repeatable meta-annotation. I think I'm doing everything right, but it appears that Groovy is not recognizing #Repeatable. Here's my sample code; I'm expecting the information from both annotations to get stored in MyAnnotationArray:
import java.lang.annotation.*
class MyClass
{
#MyAnnotation(value = "val1")
#MyAnnotation(value = "val2")
void annotatedMethod()
{
println("annotated method called")
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
public #interface MyAnnotationArray
{
MyAnnotation[] MyAnnotationArray()
}
What happens is that I get this error:
Caught: java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
Which is exactly what I get if I leave out the #Repeatable meta-annotation.
The code works fine if I leave out one of the duplicate MyAnnotations; then there is no error, and I then can read the annotation value as expected.
Is it possible that Groovy doesn't support the #Repeatable meta-annotation? I couldn't find any documentation that states this outright, though this page hints that maybe this is the case (scroll down to item 88).
seems to be not supported
i used java 1.8 and groovy 2.4.11
after compiling and de-compilig the same code i got this:
java:
#MyAnnotationArray({#MyAnnotation("val1"), #MyAnnotation("val2")})
public void annotatedMethod()
{
System.out.println("annotated method called");
}
groovy:
#MyAnnotation("val1")
#MyAnnotation("val2")
public void annotatedMethod()
{
System.out.println("annotated method called");null;
}
so, as workaround in groovy use
//note the square brackets
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
full script (because there were some errors in annotation declaration)
import java.lang.annotation.*
class MyClass
{
//#MyAnnotation(value = "val1")
//#MyAnnotation(value = "val2")
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotationArray
{
MyAnnotation[] value()
}
also tried against groovy 3.0.0-SNAPSHOT - the result is the same as for 2.4.11
Yes, Groovy has supported "repeatable" annotations for a long time even in Java 5 so long as retention policy was only SOURCE. This is what allows multiple #Grab statements for instance without the outer #Grapes container annotation. Being only retained in SOURCE makes them useful for AST transformations and within the Groovy compiler itself (and other source processors) but not really useful anywhere else. We don't currently support #Repeatable at all but plan to in a future version.

Bug? "Reference to method is ambiguous" in Groovy

package bug
import groovy.transform.CompileStatic
#CompileStatic
class BugCheck
{
static void main(String[] args)
{
new BugCheck()
}
BugCheck()
{
new Child().method(1f) // causes the problem
}
class Parent
{
void method(float f, boolean b=true)
{
println("Parent")
}
}
class Child extends Parent
{
#Override
void method(float f)
{
println("Child")
}
}
}
Compiling this piece of code with Groovy 2.3.4 leads to the following error:
/mirror/dev/Groovy/src/bug/BugCheck.groovy: 17: [Static type checking] - Reference to method is ambiguous. Cannot choose between [void bug.BugCheck$Child#method(float), void bug.BugCheck$Child#method(float)]
Is this a bug in Groovy, or do I miss something here?
The method signatures vary, but since the Parent method has a default value, calling it with no boolean value creates an ambiguity: do you mean the Child method with no parameter, or the parent with a default boolean?
If Child declares a method with the exact same signature the ambiguity is resolved.
From a language design (or usage?) standpoint this is pretty shaky reasoning, though; IMO the Child method should be called if no boolean is provided. IMO the confusion is warranted.

Error CS1061: AppDelegate does not contain a definition for GetNativeField

I'm writting my first iPhone app using mono touch. I have only written a little bit of code, and suddenly, it does not compile anymore, I get this error:
/MyRoute/MainWindow.xib.designer.cs(85,85): Error CS1061: Type xxxx.AppDelegate' does not contain a definition forGetNativeField' and no extension method GetNativeField' of typexxx.AppDelegate' could be found (are you missing a using directive or an assembly reference?) (CS1061) (xxx)
Any idea where this error comes from and how to solve it?
Thanks! :-D
Edited: Added aditional information:
THIS IS THE MAINWINDOW DESIGNER CODE:
namespace GuiaTeleIphone {
// Base type probably should be MonoTouch.Foundation.NSObject or subclass
[MonoTouch.Foundation.Register("AppDelegate")]
public partial class AppDelegate {
private MonoTouch.UIKit.UIWindow __mt_window;
#pragma warning disable 0169
[MonoTouch.Foundation.Connect("window")]
private MonoTouch.UIKit.UIWindow window {
get {
this.__mt_window = ((MonoTouch.UIKit.UIWindow)(this.GetNativeField("window")));
return this.__mt_window;
}
set {
this.__mt_window = value;
this.SetNativeField("window", value);
}
}
}
}
THIS IS THE MAIN.CS:
namespace GuiaTeleIphone
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
List<RSSChannel> RemoteChannelsData;
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// If you have defined a view, add it here:
// window.AddSubview (navigationController.View);
window.MakeKeyAndVisible ();
// do things here
return true;
}
}
}
The other partial class of xxxx.AppDelegate is missing or in a different namespace. It specifies the base class.

Resources