Get App Version and Build - c#

I am working on a Xamarin.Forms app but the iOS versions don't seem to be displaying correctly.
I set the info.plist to Version: 0.0 and Build: 9 but in the app it displays as Version 1.5.174 and Build 674
[assembly: Xamarin.Forms.Dependency(typeof(SocialNetwork.iOS.Version_iOS))]
namespace SocialNetwork.iOS
{
public class Version_iOS : IAppVersion
{
public string GetVersion()
{
return NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
}
public int GetBuild()
{
return int.Parse(NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString());
}
}
}
IAppVersion is simply
public interface IAppVersion
{
string GetVersion();
int GetBuild();
}
and I get the value using
public static string AppVersion = DependencyService.Get<IAppVersion>().GetVersion();
public static int AppBuild = DependencyService.Get<IAppVersion>().GetBuild();

SHARED
declaration:
public interface IYourName
{
string GetAppVersion();
}
usage:
var AppVersion = DependencyService.Get<IYourName>().GetAppVersion();
IOS
//****************************************************
class YourNameHelpers : IYourName
//****************************************************
{
//-------------------------------------------------------------
public string GetAppVersion()
//-------------------------------------------------------------
{
return NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleVersion")].ToString();
}
}
Android
//****************************************************
class YourNameHelpers : IYourName
//****************************************************
{
//-------------------------------------------------------------
public string GetAppVersion()
//-------------------------------------------------------------
{
Context context = Forms.Context;
PackageManager manager = context.PackageManager;
PackageInfo info = manager.GetPackageInfo(context.PackageName, 0);
return info.VersionName;
}
}

Related

You must add a reference to assembly 'UnityEngine.AndroidJNIModule

I am very new at Unity and I tried to integrate Huawei Mobile Service plugin and I got this error.
The type 'AndroidJavaObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'UnityEngine.AndroidJNIModule
Is there anyone who encounter this problem before?
Thank you.
Edit
This code is belong to plugin.
using HuaweiMobileServices.Id;
using HuaweiMobileServices.Utils;
using System;
using UnityEngine;
namespace HmsPlugin
{
public class AccountManager : MonoBehaviour
{
public static AccountManager GetInstance(string name = "AccountManager") => GameObject.Find(name).GetComponent<AccountManager>();
private static HuaweiIdAuthService DefaultAuthService
{
get
{
Debug.Log("[HMS]: GET AUTH");
var authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM).SetIdToken().CreateParams();
Debug.Log("[HMS]: AUTHPARAMS AUTHSERVICE" + authParams);
var result = HuaweiIdAuthManager.GetService(authParams);
Debug.Log("[HMS]: RESULT AUTHSERVICE"+ result);
return result;
}
}
public AuthHuaweiId HuaweiId { get; private set; }
public Action<AuthHuaweiId> OnSignInSuccess { get; set; }
public Action<HMSException> OnSignInFailed { get; set; }
private HuaweiIdAuthService authService;
// Start is called before the first frame update
void Awake()
{
Debug.Log("[HMS]: AWAKE AUTHSERVICE");
authService = DefaultAuthService;
}
public void SignIn()
{
Debug.Log("[HMS]: Sign in " + authService);
authService.StartSignIn((authId) =>
{
HuaweiId = authId;
OnSignInSuccess?.Invoke(authId);
}, (error) =>
{
HuaweiId = null;
OnSignInFailed?.Invoke(error);
});
}
public void SignOut()
{
authService.SignOut();
HuaweiId = null;
}
}
}
Picture of the problem is here.
The problem is about my unity. I had no AndroidJNI module so I got this error. Finally I uninstall current version then install new version of Unity and problem is solved. In the new version AndroidJNI module is came automatically.

Static context is null after been set

This .Net Core 3.1 (NUnit 3) test works under Visual Studio 2019.
But as soon I use JetBrains Rider the test fails because the static property (DataA) returns null in mostly all contexts.
Has some a idea what goes wrong and how to solve this issue?
public static class ClassA
{
public static string DataA { get; set; }
public static string DataB { get; set; }
public static void SetAppConfig(string appSettingsPfad)
{
IList<JProperty> appSettings = JsonConvert.DeserializeObject<JToken>(appSettingsPfad).Select(j => (JProperty)j).ToList();
var appKonfiguration = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.Static);
foreach (JProperty property in appSettings)
{
var appKonfigurationProperty = appKonfiguration.SingleOrDefault(p => p.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase));
var value = ((JValue)property.Value).Value;
if (appKonfigurationProperty != null)
appKonfigurationProperty.SetValue(null, Convert.ChangeType(value, appKonfigurationProperty.PropertyType));
}
}
}
[TestFixture]
public class DummyTest
{
[Test]
public void TestA()
{
LoadAppConfig();
// DataA returns null here
Console.WriteLine(ClassA.DataA);
new BusinessLogicClass.DoSomething();
// [...]
}
private void LoadAppConfig() {
// [...]
string appSettings = File.ReadAllText(jsonConfigFiles.Single());
ClassA.SetAppConfig(appSettings);
// here it works and a result is the proper string
Console.WriteLine(ClassA.DataA);
// [...]
}
}
public class BusinessLogicClass {
public void DoSomething() {
// DataA returns null here
Console.WriteLine(ClassA.DataA);
// [...]
}
}
(I have simplfied this code to the bare minimum, the orginal code would run into a Exception after a null check)

C# InteropServices and Visual Basic 6.0 error reference error

I created C# dll to use with Visual Basic 6. When I create a reference in VB6 I get the error:
Error 91: Object variable or With block variable not set
I tried to set the object of different ways but i still having the same problem.
VISUAL BASIC 6.0 Code:
Private Sub Command1_Click()
Dim objhacienda As SolcomFE.clsHacienda
Set objhacienda = New SOLCOMFE.clsHacienda' Error can not create the object 429
Dim blnResult As Boolean
blnResult = objhacienda.tengoAcceso Error 91: Object variable or With block variable not set
end sub
C# Code:
namespace SolcomFE
{
[
ComVisible(true), //Hace visible las interfaces
GuidAttribute("4F52E06E-29C6-4168-8AC2-F836CD7A1C4A"), //Tomado del asembly del proyecto
Description("Interfaces para acceso de factura electronica")
// ClassInterface(ClassInterfaceType.None)
]
//----------------------------------------------------DiseƱo de interfaces -------------------------------------//
public interface IclsHacienda
{
[DispId(1)]
bool tengoAcceso();
[DispId(2)]
void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio = "C://HACIENDA/Almacenamiento/",
string pStrRutaArchRespuesta = "C://HACIENDA/Almacenamiento/");
[DispId(3)]
string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
DocumentoEncabezado pLstEncabezadoDoc
);
}
//-------------------------------------------Clases ---------------------------------------------------------//
[ClassInterface(ClassInterfaceType.None)]
[Guid("64B7C116-BA68-4EE0-8340-74F64846CB3D")]
public class clsHacienda : IclsHacienda
{
//------------------------------------------ Atributos de la clase --------------------------------------//
private bool EnvioProduccion //
{
get
{
return envioProduccion;
}
set
{
envioProduccion = value;
}
}
private string UsuarioHacienda //
{
get
{
return usuariohacienda;
}
set
{
usuariohacienda = value;
}
}
private string ClaveHacienda //
{
get
{
return clavehacienda;
}
set
{
clavehacienda = value;
}
}
private string RutaCertificado
{
get
{
return rutacertificado;
}
set
{
rutacertificado = value;
}
}
private string RutaArchEnvio
{
get
{
return rutaarchenvio;
}
set
{
rutaarchenvio = value;
}
}
private string RutArchrespuesta
{
get
{
return rutaarchrespuesta;
}
set
{
rutaarchrespuesta = value;
}
}
private string PinCertificado
{
get
{
return pincertificado;
}
set
{
pincertificado = value;
}
}
public clsHacienda() { }
public bool tengoAcceso() { return true; }
public void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio = "C://HACIENDA/Almacenamiento/",
string pStrRutaArchRespuesta = "C://HACIENDA/Almacenamiento/")
{
EnvioProduccion = pBlnEnvioProduccion;
UsuarioHacienda = pStrUsuarioHacienda;
ClaveHacienda = pStrClaveHacienda;
PinCertificado = pStrPinCerti;
RutaCertificado = pStrRutaCerti;
RutaArchEnvio = pStrRutaArchEnvio;
RutArchrespuesta = pStrRutaArchRespuesta;
}
public string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
DocumentoEncabezado pLstEncabezadoDoc
)
{
string[] strArrValores = new string[10];
return strArrValores;
}
}
}
It's difficult to find out whats wrong. Specially because i don't have VB6 ;-). Anyway, I've found some differences on your implementation. Check if this rings a bell:
Interfaces:
[ComVisible(true)]
[Guid("E449B0E6-2F27-46B7-9CC0-C7032B7B5BF1")]
public interface IclsHacienda
{
[DispId(1)]
bool tengoAcceso();
[DispId(2)]
void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio,
string pStrRutaArchRespuesta);
[DispId(3)]
string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
IDocumentoEncabezado pLstEncabezadoDoc
);
}
[ComVisible(true)]
[Guid("97F8901F-EEDA-4DE1-8B4B-826ED43E17D8")]
public interface IDocumentoEncabezado
{
int MyProperty { get; set; }
}
Implementation:
[ComVisible(true)]
[Guid("4726F93F-D102-442E-AF7D-3255B87E740C")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IDocumentoEncabezado))]
public class DocumentoEncabezado : IDocumentoEncabezado
{
public int MyProperty { get; set; }
}
[ComVisible(true)]
[Guid("500941FB-3F7B-4285-BF4A-A642D60AD923")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IclsHacienda))]
public class ClsHacienda : IclsHacienda
{
public void configuracion(bool pBlnEnvioProduccion, string pStrUsuarioHacienda, string pStrClaveHacienda, string pStrPinCerti, string pStrRutaCerti, string pStrRutaArchEnvio , string pStrRutaArchRespuesta)
{
Debug.WriteLine("Called configuracion");
}
public string[] registrarDocElectronico(string pStrVerificador, byte pBytSituacionEnCom, IDocumentoEncabezado pLstEncabezadoDoc)
{
Debug.WriteLine("Called registrarDocElectronico");
return new string[] { "Whatever" };
}
public bool tengoAcceso()
{
Debug.WriteLine("Called tengoAcceso");
return false;
}
}
If not, there is something wrong on the VB side...
Thank your for your help.
I found a solution
create 2 clases, one inteface class, another method class
Example iInterface, COMInterface,
COMIterface implements iInterface.
Go to tools and create GUID
Then create a key. Implement_OleCreate and paste it to iInterface class,
After create a new key a 5.Guid Class
More documentation
https://social.technet.microsoft.com/wiki/contents/articles/37338.com-interop-detail-steps-to-create-com-interop-dll.aspx

Return results from lists of different type via interface c#

I have created an interface that in theory should be able to return multiple generic lists of different types to provide the client with various information. When I attempt to loop through the results of the list it is only able to return first collection, can you help me to understand how I should be returning results from the following:
Interface class:
public interface IExampleInterface{}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
}
Interface provider:
public class ExampleInterfaceProvider
{
private static readonly string conn = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
public static List<IExampleInterface> ExampleResults(int id)
{
//declare variables, read from database query using ExecuteReader...
var sT = new ExampleType
{
First = first;
Last = last;
}
var sA = new ExampleAmount
{
Amount = amount;
TotalFee = totalFee;
}
var sF = new ExampleFacts
{
TooHigh = tooHigh;
TooLow = tooLow;
}
var exampleResults = new List<IExampleInterface> {sT, sA, sF};
return exampleResults;
}
}
On the page I need to return the data:
foreach (dynamic item in ExampleResults(0))
{
Response.Write(item.First.ToString())
Response.Write(item.Last.ToString())
//The first two for 'sT' read fine, it breaks here
Response.Write(item.Amount.ToString())
//... And so on
}
Any help would be much appreciated,
Thanks
I think, there is no another solution except comparing implementations;
foreach (IExampleInterface item in ExampleResults(0))
{
if (item is ExampleType)
{
var exampleType = (ExampleType)item;
Response.Write(exampleType.First.ToString())
Response.Write(exampleType.Last.ToString())
}
else if (item is ExampleAmount)
{
var exampleAmount = (ExampleAmount)item;
Response.Write(exampleAmount.Amount.ToString())
}
//... And so on
}
If you are using C# 7, you can perform it as switch case
foreach (IExampleInterface item in ExampleResults(0))
{
switch (item)
{
case ExampleType c:
Response.Write(c.First.ToString());
Response.Write(c.Last.ToString());
break;
case ExampleAmount c:
Response.Write(c.Amount.ToString());
break;
default:
break;
}
//... And so on
}
You can find the documentation.
So basically, the items implementing IExampleInterface should all be written to a Response in a way that is somewhat specific to the actual type implementing the interface?
Then how about this:
public interface IExampleInterface
{
void WriteTo(Response response);
}
public class ExampleType : IExampleInterface
{
public int First;
public int Last;
public void WriteTo(Response response)
{
response.Write(First.ToString());
response.Write(Last.ToString());
}
}
public class ExampleAmount : IExampleInterface
{
public decimal Amount;
public decimal TotalFee;
public void WriteTo(Response response)
{
response.Write(Amount.ToString());
response.Write(TotalFee.ToString());
}
}
public class ExampleFacts : IExampleInterface
{
public bool TooLow;
public bool TooHigh;
public void WriteTo(Response response)
{
response.Write(TooLow.ToString());
response.Write(TooHigh.ToString());
}
}
And then:
foreach (IExampleInterface item in ExampleResults(0))
{
item.WriteTo(Response);
}
Assuming that Response is a variable holding an instance of the response rather than a static class.

How to get the app version from ContentPage?

I tried this: iPhone MonoTouch - Get Version of Bundle
NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString();
But this didn't work. As NSBundle can't be found.
How can I get the app version (iOS and Android) from ContentPage?
The code which i ended up with (thanks to Steven Thewissen):
PCL (shared code)
using System;
namespace MyApp.Interfaces
{
public interface IApplicationVersion
{
string ApplicationsPublicVersion { get; set; }
string ApplicationsPrivateVersion { get; set; }
}
}
Android
using System;
using MyApp.Droid.Helpers;
using MyApp.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(ApplicationVersion))]
namespace MyApp.Droid.Helpers
{
public class ApplicationVersion : IApplicationVersion
{
public string ApplicationsPublicVersion { get; set; }
public string ApplicationsPrivateVersion { get; set; }
public ApplicationVersion()
{
var context = Android.App.Application.Context;
var info = context.PackageManager.GetPackageInfo(context.PackageName, 0);
ApplicationsPublicVersion = info.VersionName;
ApplicationsPrivateVersion = info.VersionCode.ToString();
}
}
}
iOS
using System;
using MyApp.Interfaces;
using MyApp.iOS.Helpers;
using Foundation;
using Xamarin.Forms;
[assembly: Dependency(typeof(ApplicationVersion))]
namespace MyApp.iOS.Helpers
{
public class ApplicationVersion : IApplicationVersion
{
public string ApplicationsPublicVersion { get; set; }
public string ApplicationsPrivateVersion { get; set; }
public ApplicationVersion()
{
ApplicationsPublicVersion = NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleShortVersionString")].ToString();
ApplicationsPrivateVersion = NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleVersion")].ToString();
}
}
}
You can do this by implementing a Dependency Service. First you define an interface in your shared code:
namespace MyApp
{
public interface IAppVersionProvider
{
string AppVersion { get; }
}
}
In each platform project you then implement the interface.
iOS
[assembly: Dependency(typeof(AppVersionProvider))]
namespace MyApp.iOS
{
public class AppVersionProvider : IAppVersionProvider
{
public string AppVersion => NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleVersion")].ToString();
}
}
Android
[assembly: Dependency(typeof(AppVersionProvider))]
namespace MyApp.Droid
{
public class AppVersionProvider : IAppVersionProvider
{
public string AppVersion
{
get
{
var context = Android.App.Application.Context;
var info = context.PackageManager.GetPackageInfo(context.PackageName, 0);
return $"{info.VersionName}.{info.VersionCode.ToString()}";
}
}
}
}
You can then retrieve the version number from shared code through:
var version = DependencyService.Get<IAppVersionProvider>();
var versionString = version.AppVersion;
If you don't want to use dependency services, you can just use the class VersionTracking.
The property VersionTracking.CurrentVersion will give you the Version you can set in your Android properties and your iOS info.plist.
This class is provided by Xamarin.Essentials and can give you a lot of informations. Please, check the documentation here for more informations.
Edit: listed incorrect nuget package, changes made below.
You should in theory be able to use something like the below inside the OnStart(); method of your App.cs in your forms project.
Context context = this.ApplicationContext;
SupportFunctions.Version = context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName;
However we use a plugin created by Mark Trinder called "Xam.Plugin.Version" which can be found on nuget1 and on GitHub2. Once it's installed into your forms & native projects it's simply called as so:
using Version.Plugin;
private void SomeMethod()
{
MyLabel.Text = CrossVersion.Current.Version;
}
1 nuget package Here
2 Github Here :

Categories

Resources