AXUIElement available in MonoMac? - cocoa

I'd like to be able to use the Cocoa Accessibility API in a MonoMac application, but I can't find any references to it in the MonoMac documentation. Has AXUIElement.h been mapped yet?

I couldn't find anything on it either.
Some parts can be implemented with DllImport. For example, I did the following:
public const string AccessibilityLibrary = "/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices";
[DllImport (AccessibilityLibrary)]
extern static bool AXAPIEnabled();

Related

How to import Activity of NfcFCardEmulation.EnableService from Xamarin common project, not Android project?

I'm developing an app using Xamarin's HCE feature.
The project structure is as follows.
hceSample
hceSample.Android
hceSample.iOS
I am implementing hce simulation code called hceService in hceSample, not hceSample.Android.
A function called Enable_Card exists in the hce service, and you want to use the NfcFCardEmulation.EnableService function in that function.
Activity and ComponentName are requested as parameters of the function.
The ComponentName area was handled easily, but I don't know how to get the Activity. Please advise.
This is the contents of enable_Card function of hceService.
private Activity activity = null;
private bool enable_Card(cardModel card)
{
try
{
sid = card.cardSN;
tag = "Felica";
emulation.EnableService(, componentName); //<- How to get Activity??
emulation.SetNfcid2ForService(componentName, sid);
return true;
}
catch
{
return false;
}
}
This is my first time asking a question on Stackoverflow.
I would appreciate it if you could point out any missing or incorrect parts.
I trying this
activity = Xamarin.Essentials.Platform.CurrentActivity; //<- this function is not found!
Added missing information!
The namespace of the Enable_Card function is located in hceSample.Service.
Are you using the NfcFCardEmulation.EnableService(Activity, ComponentName) Method, right?
The method is an android api from android sdk,you cannot use it directly in xamarin.form(yours is hceSample) project.
If you want to call the function in xamarin form project(hceSample) from native platform(hceSample.Android, or hceSample.iOS),you can use Xamarin.Forms DependencyService to achieve this.
The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.
For more information about DependencyService, you can check document Xamarin.Forms DependencyService. And there is a sample included in above document,which is helpful for you to understand DependencyService.
Note:
We recognize that hardware service is the right and ideal way to
implement in each OS project. However, I'm curious if there is a way
to code Android and iOS at the same time
Since the api you used is from android sdk, you can call it in native android or use DependencyService to call it on xamarin.form(yours is hceSample) project.
If you call it on xamarin.form(yours is hceSample) project, you also need to find the the corresponding function or interface in iOS.

How can I get Android and iPhone IMEI number using Xamarin.forms

I am developing an Xamarin.forms application, I need to catch the imei number of mobile that is using the application. I am aware of how it is done in Android. But how can I do the same in Xamarin.forms. Please educate me.
There is no 'Forms-way' of doing this. If you know how on Android you can make use of the DependencyService. Which means in your shared project create an interface like:
public interface IImeiService
{
string GetImei();
}
Now in your Android project implement this interface, so it would be something like:
public class ImeiService : IImeiService
{
public string GetImei()
{
// ... Implement your Android code here
}
}
Register your Android code with an attribute on the class above the namespace
[assembly: Xamarin.Forms.Dependency (typeof (ImeiService))]
namespace ImeiApp.Droid {
You can now access it, back in your shared code, with:
var imei = DependencyService.Get<IImeiService>().GetImei();
If you would have an iOS implementation you could repeat the same steps, although you can, of course, use the same interface and call in shared code, so you will only need a iOS specific implementation.
However, since iOS 7 Apple disallows access to this kind of information programmatically, so you cannot get the IMEI number. And if you can, you will use code that will not be allowed through the App Store review process.

Xamarin: 'System.Resources.MissingManifestResourceException' on WinPhone

I found an issue with localization in WinPhone app. I added couple of resources and implemented localization. It is working fine in simulator, but crashing on Phone with exception Exception thrown: 'System.Resources.MissingManifestResourceException' in mscorlib.ni.dll
Any help?
Thanks to a bit of googling and a helpful blog post I have managed to solve this issue that happened intermittently with Xamarin.Forms projects.
This is the blog post that led me to the solution:
http://blog.tpcware.com/2016/06/xamarin-forms-localization/
Basically, the way you access resources on Android and iOS with Xamarin.Forms and Windows Phone is different:
To make it short, we need to “automagically” use the ResourceLoader.GetString(…) method when running on Store apps, while continuing to use the regular ResourceManager.GetString(…) method on all other platform. And because in the Xamarin Forms solution we use a resource file of type RESX, we also have the automatically generated resource class.
The super clever idea contained in the above linked post is to “hack” the resource class injecting a derived class of ResourceManager with an overridden GetString(…) method into the resource class “resourceMan” property (for a more detailed explanation of this hack, you can read the post).
We need to create our own version of ResourceManager like so and swap it for the existing ResourceManager using reflection:
public class WinRTResourceManager : ResourceManager
{
readonly ResourceLoader _resourceLoader;
private WinRTResourceManager(string baseName, Assembly assembly) : base(baseName, assembly)
{
_resourceLoader = ResourceLoader.GetForViewIndependentUse(baseName);
}
public static void InjectIntoResxGeneratedApplicationResourcesClass(Type resxGeneratedApplicationResourcesClass)
{
resxGeneratedApplicationResourcesClass
.GetRuntimeFields()
.First(m => m.Name == "resourceMan")
.SetValue(null, new WinRTResourceManager(
resxGeneratedApplicationResourcesClass.FullName,
resxGeneratedApplicationResourcesClass.GetTypeInfo().Assembly));
}
public override string GetString(string name, CultureInfo culture)
{
return _resourceLoader.GetString(name);
}
}
All that's then left to do is call this when the app starts for the first time:
WinRTResourceManager.InjectIntoResxGeneratedApplicationResourcesClass(typeof(AppResources));
After making these changes everything should work fine now.
Of course this is absolutely a hack but I have notified the Xamarin.Forms team of the issue and they are looking into it so hopefully it will be solved soon!

Xamarin - Using Portable Class Libraries a mandatory way to go?

Recently I am requested to setup the design for a new app, which needs to be build using Xamarin. The team already created a DEMO app for Android, iOS and Windows Phone. So basically this demo version needs to be transformed/refactored into a proper maintainable product.
When looking into the code what currently is implemented in the DEMO app, I found out that some third party libraries are used which are not available as PCL. This means that I cannot build up my app using PCL's unless I can port this third party library into a PCL.
My findings are:
The functionality we use from this third party library works fine on all 3 platforms
I cannot find any blocking reason why I should not use normal Class Libraries
Questions:
Are there any blocking reasons why I cannot make use of normal Class Libraries?
Will the public apps stores accept these apps or is this not an issue at all?
If not.. Can you give recommendations where especially take care of going with normal Class Library's
If there are.. How can I port third party Libraries to PCL or is there any other way to work around?
First: public app stores don't care about the internals of your app, as long as it follows their guidelines. And that's something Xamarin takes care of, so everything that is dropping out of the compiler will be okay.
Second: You're totally fine with not using PCL if that fits your needs in a better way. In addition to PCL you could also make use of Shared Projects or just linking files from common library projects into each platform-specific project.
But from my personal experience PCL are a good way to make sure the code you're writing and the tools you're using are really working on every platform, so you don't have to be afraid of bad surprises afterwards. And with the PCL profile 78 support of stuff like LINQ etc. is pretty good.
What you can do in addition, is to use a facade inside your shared PCL code, that hides away the concrete implementation, that is then provided for each platform individually.
That could look like:
(PCL)
public interface ILogger
{
void Log(string message);
}
public static class SharedUtilities
{
public static ILogger Logger { get; private set; }
public static void SetUp(ILogger logger)
{
Logger = logger;
}
}
// Now Use it from everywhere in your code:
SharedUtilities.Logger.Log("Hello PCL!");
In your iOS app, for example:
public class IOSLogger : ILogger
{
public void Log(string message)
{
// Make use of a native logging library or whatever you want
}
}
// AppDelegate:
SharedUtilities.SetUp(new IOSLogger());

Unmanaged Exports (DLLExport) crashes

I'm using RGiesecke DLLExport library to produce a C# DLL that can be dynamically loaded from legacy application built on VC6. It exported methods and they were called from VC6 code. No problems. However, as long as I tried to declare a variable as of any one of my .net classes, it crashed.
//I tried CallingConvention = CallingConvention.StdCall too
[DllExport(CallingConvention = CallingConvention.Winapi)]
static void GetDwgReferences(string fileName)
{
//OK: inialize System classes of .net
DateTime dateTime = DateTime.Now;
//crashing here: declare a variable of my static class (.net assemebly)
//SafeString safeString;
//crashing here: declare a variable of my class (.net assemebly)
//Email email;
//crashing here: initialize an object of my class (.net assemebly)
//DwgXrefs dwgXrefs = new DwgXrefs();
//crashing here by declcare a variable of third-party library (.net assemebly)
//ExSystemServices _serv;
}
What's wrong? Please help.
I had a similar problem here trying to use unmanaged exports with Metatrader to load associated managed dlls.
After some digging I think I have found the problem. The app domain is probably not where you would expect it to be, the CLR is trying to resolve your assembly but failing with a nondescript error. In my case the app domain was actually executing in the directory of the host application, so I assume this is always the case.
What I would suggest you do is build a bare dll with no dependencies, and place in something such as the following:
static void Initialize()
{
SimpleLog.WriteLog("App -" + AppDomain.CurrentDomain.BaseDirectory);
}
[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
public static void Test()
{
Initialize();
}
I am not sure but I think you possibly cannot use a static constructor here?
In the log you should see the executing directory for that domain. If you put your assemblies here it (hopefully) should work. It has fixed the problem for me here. I guess the next question is can we change the domain at runtime as I might not want to put these assemblies here.
Have a google if you need the source code for a simple logger - obviously do not use a third party logging framework with dll dependencies!
I think mine is an adaptation of this one:
http://www.codeproject.com/Articles/80175/Really-Simple-Log-Writer
As the other answer stated, it is difficult to know what error C# is throwing without explicitly catching the error in a try / catch block within each method of a C# dll.
You likely need to export as CallingConvention.StdCall and additionally marshal the incoming string as an unmanaged LPWStr type:
[DllExport(CallingConvention = CallingConvention.StdCall)]
static void GetDwgReferences([MarshalAs(UnmanagedType.LPWStr)] string fileName)
{
}
Please see Code to Export C# DLL to Metatrader Build 600+ for a working example using Robert Giesecke's C# Project Template for Unmanaged Exports to export a C# dll to a legacy application (MT4).
Additionally, you might find Native and .NET Interopability interesting though it is mostly geared toward accessing native code from within .NET.

Resources