xamarin.ios binding Segment-Analytics errors - xamarin

I am working on the iOSbinding for Segment/Analytics and meeting a block on this.
The oc code I cannot find a good idea to convert to C# code.
-(SEGReachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
when i converted code to below:
[Export("initWithReachabilityRef:")]
unsafe IntPtr Constructor(ref NetworkReachability #ref);
it happened a error:
Error CS0311: The type SystemConfiguration.NetworkReachability' cannot be used as type parameterT' in the generic type or method ObjCRuntime.Runtime.GetNSObject<T>(System.IntPtr)'. There is no implicit reference conversion fromSystemConfiguration.NetworkReachability' to `Foundation.NSObject' (CS0311) (Anayltics.IOS)
[Export ("initWithReachabilityRef:")]
[CompilerGenerated]
public SEGReachability (ref SCNetworkReachabilityRef #ref)
: base (NSObjectFlag.Empty)
{
IntPtr #refValue = IntPtr.Zero;
IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
if (IsDirectBinding) {
InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSend_ref_IntPtr (this.Handle, Selector.GetHandle ("initWithReachabilityRef:"), ref refValue), "initWithReachabilityRef:");
} else {
InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper_ref_IntPtr (this.SuperHandle, Selector.GetHandle ("initWithReachabilityRef:"), ref refValue), "initWithReachabilityRef:");
}
#ref = #refValue != IntPtr.Zero ? Runtime.GetNSObject<Anayltics.SCNetworkReachabilityRef> (#refValue) : null; //**--**error happened in this line.****
}
Any one can help me?

Related

Xamarin.iOS UIApperance setDefaultTextAttributes

I'm trying to figure out how to implement following code in Xamarin:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:#{NSForegroundColorAttributeName:[UIColor greenColor]}];
But I cannot find a way to setDefaultTextAttributes on UIApperance class.
There are a number of missing UIAppearance features in Xamarin.iOS and in regards to your question, there is a missing API.
This is a bug, 🍣 I wrote my own UIAppearance.cs to add the missing features and correct the missing API and assume no other Xamarin.iOS coders really use the newer UIAppearance features as it has been broken since iOS 9 in Xamarin.
First, appearanceWhenContainedIn is deprecated and you should be using appearanceWhenContainedInInstancesOfClasses instead.
AppearanceWhenContainedIn - was deprecated in iOS 9 and is not recommended for use.
Second, appearanceWhenContainedInInstancesOfClasses is incorrectly defined within Xamarin.iOS as only available in tvOS and that is just not true.
#if TVOS
// new in iOS9 but the only option for tvOS
const string selAppearanceWhenContainedInInstancesOfClasses = "appearanceWhenContainedInInstancesOfClasses:";
~~~
UIAppearance.cs#L77
Update: I submitted a Github issue regarding this.
https://github.com/xamarin/xamarin-macios/issues/3230
Thus it is not available via the Xamarin.iOS wrapper API, but of course is available directly from the ObjC runtime as such:
var NSForegroundColorAttributeName = Dlfcn.GetStringConstant(UIKitLibraryHandle, "NSForegroundColorAttributeName");
var defaultAttributes = NSDictionary.FromObjectsAndKeys(new NSObject[] { UIColor.Red }, new NSObject[] { NSForegroundColorAttributeName });
var styleHandle = GetAppearanceEx(Class.GetHandle("UITextField"), typeof(UISearchBar));
void_objc_msgSend_IntPtr(styleHandle, Selector.GetHandle("setDefaultTextAttributes:"), defaultAttributes.Handle);
The next problem there are a number of Xamarin.iOS methods marked internal that are needed for the above code to function, so some copy/paste/modify of some source is needed:
public const string selAppearanceWhenContainedInInstancesOfClasses = "appearanceWhenContainedInInstancesOfClasses:";
public static readonly IntPtr UIKitLibraryHandle = Dlfcn.dlopen("/System/Library/Frameworks/UIKit.framework/UIKit", 0);
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
public static extern IntPtr IntPtr_objc_msgSend_IntPtr(IntPtr receiver, IntPtr selector, IntPtr arg1);
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
public static extern void void_objc_msgSend_IntPtr(IntPtr receiver, IntPtr selector, IntPtr arg1);
public static IntPtr GetAppearanceEx(IntPtr class_ptr, params Type[] whenFoundIn)
{
var ptrs = TypesToPointers(whenFoundIn);
var handles = NSArray.FromIntPtrs(ptrs);
using (var array = handles)
{
return IntPtr_objc_msgSend_IntPtr(class_ptr, Selector.GetHandle(selAppearanceWhenContainedInInstancesOfClasses), array.Handle);
}
}
public static IntPtr[] TypesToPointers(Type[] whenFoundIn)
{
IntPtr[] ptrs = new IntPtr[whenFoundIn.Length];
for (int i = 0; i < whenFoundIn.Length; i++)
{
if (whenFoundIn[i] == null)
throw new ArgumentException(String.Format("Parameter {0} was null, must specify a valid type", i));
if (!typeof(NSObject).IsAssignableFrom(whenFoundIn[i]))
throw new ArgumentException(String.Format("Type {0} does not derive from NSObject", whenFoundIn[i]));
var classHandle = Class.GetHandle(whenFoundIn[i]);
if (classHandle == IntPtr.Zero)
throw new ArgumentException(string.Format("Could not find the Objective-C class for {0}", whenFoundIn[i].FullName));
ptrs[i] = classHandle;
}
return ptrs;
}

wglCreateContext fails with error code 6 (Invalid Handle)

I'm trying to create a wgl context according to the tutorial at https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL). For whatever reason, wglCreateContext returns null, and GetLastError returns 6, or Invalid Handle. I have used the tutorial before, and it worked just fine.
I'm trying to create a dummy context to a hidden window so that I can create another context for the user window. What's going on?
The Windows API is referred through the winAPI identifier, and wgl is a global struct containing function pointers to OpenGL.
struct WglContext
{
winAPI.HDC hdc;
winAPI.HGLRC handle;
}
__gshared Win32GL wgl;
///WGL-specific global data.
struct Win32GL
{
import oswald : OsWindow, WindowConfig, WindowError;
OsWindow helperWindow;
winAPI.HINSTANCE instance;
PFN_wglCreateContext createContext;
PFN_wglDeleteContext deleteContext;
PFN_wglGetProcAddress getProcAddress;
PFN_wglMakeCurrent makeCurrent;
PFN_wglCreateContextAttribsARB createContextAttribsARB;
PFN_wglGetExtensionStringARB getExtensionStringARB;
PFN_wglGetExtensionStringEXT getExtensionStringEXT;
bool extensionsAreLoaded;
static void initialize()
{
if (wgl.instance !is null)
return; //The library has already been initialized
WindowConfig cfg;
cfg.title = "viewport_gl_helper";
cfg.hidden = true;
auto windowError = OsWindow.createNew(cfg, &wgl.helperWindow);
if (windowError != WindowError.NoError)
{
import std.conv : to;
assert(false, "Failed to create helper window: " ~ windowError.to!string);
}
wgl.instance = winAPI.LoadLibrary("opengl32.dll");
if (wgl.instance is null)
assert(false, "Viweport failed to load opengl32.dll");
wgl.bind(cast(void**)&wgl.createContext, "wglCreateContext\0");
wgl.bind(cast(void**)&wgl.deleteContext, "wglDeleteContext\0");
wgl.bind(cast(void**)&wgl.getProcAddress, "wglGetProcAddress\0");
wgl.bind(cast(void**)&wgl.makeCurrent, "wglMakeCurrent\0");
}
static void terminate()
{
if (!wgl.instance)
return;
winAPI.FreeLibrary(wgl.instance);
wgl.helperWindow.destroy();
}
void bind(void** func, in string name)
{
*func = winAPI.GetProcAddress(this.instance, name.ptr);
}
}
struct WglContext
{
winAPI.HDC hdc;
winAPI.HGLRC handle;
}
WglContext wglCreateTmpContext()
{
assert(wgl.instance);
winAPI.PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = winAPI.PIXELFORMATDESCRIPTOR.sizeof;
pfd.nVersion = 1;
pfd.dwFlags = winAPI.PFD_DRAW_TO_WINDOW | winAPI.PFD_SUPPORT_OPENGL | winAPI.PFD_DOUBLEBUFFER;
pfd.iPixelType = winAPI.PFD_TYPE_RGBA;
pfd.cColorBits = 24;
auto hdc = winAPI.GetDC(wgl.helperWindow.platformData.handle);
const pixelFormat = winAPI.ChoosePixelFormat(hdc, &pfd);
if (winAPI.SetPixelFormat(hdc, pixelFormat, &pfd) == winAPI.FALSE)
assert(false, "Failed to set pixel format for temp context");
writeln(hdc);
writeln(pixelFormat);
winAPI.HGLRC context = wgl.createContext(hdc);
if (context is null)
{
import std.conv: to;
assert(false, "Failed to create temp context: Error Code " ~ winAPI.GetLastError().to!string);
}
if (wgl.makeCurrent(hdc, context) == winAPI.FALSE)
{
wgl.deleteContext(context);
assert(false, "Failed to make temp context current");
}
return WglContext(hdc, context);
}
void main()
{
wgl.initialize(); //Fetches function pointers, and loads opengl32.dll
auto context = wglCreateTmpContext();
wglDeleteContext(context); //Delegates to wgl.deleteContext
wgl.terminate(); //Unloads opengl32.dll and nulls function pointers
}
I know nothing on that winAPI you use. Anyhow, I'm sure of:
You must:
Create a window and get its HWND handle (Windows definition of
HWND, see below). Tipically the window uses WS_CLIPCHILDREN | WS_CLIPSIBLINGS
style; but try also the WS_OVERLAPPEDWINDOW as in the link you
posted.
Verify you get a valid HWND, and a valid HDC from it.
HWND and HDC are defined as *void. I would not trust on auto.

Importing native methods in Xamarin.Mac

I'm looking for a way to use SCNetworkInterfaceCopyAll in my Xamarin.Mac app.
I've imported it
[DllImport("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration")]
public static extern IntPtr SCNetworkInterfaceCopyAll();
Then I get an array by calling var array = NSArray.ArrayFromHandle<NSObject>(pointer).
But can't figure out how to get values from the output array of SCNetworkInterface. I've tried to marshal it as
[StructLayout(LayoutKind.Sequential)]
public struct Test
{
IntPtr interface_type;
IntPtr entity_hardware;
}
And then call Marshal.PtrToStructure<Test>(i.Handle) but it gives random pointers instead of meaningful values.
Can you use the information provided from System.Net.NetworkInformation. NetworkInterface (or do you need actually need a SCNetworkInterface?)
Xamarin.Mac Example:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up)
Console.WriteLine(nic.GetPhysicalAddress());
}
Looking at SCNetworkConfiguration.h it appears there are a number of C APIs you are to call on your IntPtr to retrieve the specific information you need.
CoreFoundation APIs often return "baton" pointers that you need to pass to other functions. Where did you see that struct definition?
You can use Objective-C methods in Xamarin to get the MAC Address as C# gives a different MAC Address:
[DllImport("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration")]
public static extern IntPtr SCNetworkInterfaceCopyAll();
[DllImport("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration")]
public static extern IntPtr SCNetworkInterfaceGetHardwareAddressString(IntPtr scNetworkInterfaceRef);
private string MacAddress()
{
string address = string.Empty;
using (var interfaces = Runtime.GetNSObject<NSArray>(SCNetworkInterfaceCopyAll()))
{
for (nuint i = 0; i < interfaces.Count; i++)
{
IntPtr nic = interfaces.ValueAt(i);
var addressPtr = SCNetworkInterfaceGetHardwareAddressString(nic);
address = Runtime.GetNSObject<NSString>(addressPtr);
if (address != null) break;
}
}
return address;
}

Safari plugin crashes on NPN_GetValue

My plugin code crashes when I call the NPN_GetValue. Basically I created a scriptable object which has a 'getDevice' method that can return a device array to JavaScript. Below is the code snippet.
static bool mainNPObjectInvoke(NPObject *obj, NPIdentifier identifier, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
printf("create main object");
MainNPObject *mainObject = (MainNPObject *)obj;
if (identifier == methodIdentifiers[METHOD_ID_GET_DEVICES])
{
NPObject *windowObj = NULL;
browser->getvalue(mainObject->npp, NPNVWindowNPObject, &windowObj);
// it crashed here
....
}
}
I created the MainNPObject instance with below method.
NPObject *createMainNPObject(NPP npp)
{
MainNPObject *object = (MainNPObject *)browser->createobject(npp, &mainNPClass);
object->npp = npp;
theMainObject = object;
return (NPObject *)object;
}
The createMainNPObject is called in the plugin function I provided to browser.
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
PluginObject *obj = instance->pdata;
switch (variable) {
case NPPVpluginCoreAnimationLayer:
if (!obj->rootLayer)
setupLayerHierarchy(obj);
*(CALayer **)value = obj->rootLayer;
return NPERR_NO_ERROR;
case NPPVpluginScriptableNPObject:
if (!obj->mainObject)
{
obj->mainObject = createMainNPObject(instance);
}
....
}
And the allocate function is as below.
static NPObject *mainNPObjectAllocate(NPP npp, NPClass *class)
{
initializeIdentifiers();
MainNPObject *mainObject = malloc(sizeof(MainNPObject));
mainObject->deviceManager = [[DeviceManager alloc] init];
return (NPObject *)mainObject;
}
Definition of MainNPObject:
typedef struct
{
NPObject *npobject;
NPP npp;
DeviceManager *deviceManager;
} MainNPObject;
By debugging the code, I found that the system raised an EXC_BAD_ACCESS when calling the browser->getValue and it looks like the npp pointer is invalid.
0x00007fff83f82dab <+0019> je 0x7fff83f82db9 <_ZN6WebKit14NetscapePlugin7fromNPPEP4_NPP+33>
0x00007fff83f82dad <+0021> incl 0x8(%rax)
Can someone help me out?
Thanks!
Hmm; not seeing anything obvious. Try adding another parameter (an int?) to your structure and set it during allocate or immediately afterwords, then later on check to see if it's still the value you set before you call getvalue. See if your struct is somehow getting corrupt. That happened to me once when I was casting the NPObject funny in a non-obvious way.

maven compilation error cannot find symbol

BUILD FAILURE
----------------------
Compilation failure
work\AccountService\src\com\service\accountinquiry\utils\XMLUtil.java:[103,48] cannot find symbol
ymbol : method parseFloat(java.lang.String,float)
ocation: class com.service.accountinquiry.utils.DataOperationUtils.
having weird problem with maven I checked DataOperationUtils.java is already compiled in target folder same folder where XMLutil.java is so why maven is not be able to find DataOperationutils.class in XMLUtils.java
code snippet for XMLUtils.java
public static float getNodeTextAsFloat(Node node, String xpath,
float defaultValue) {
float returnValue = defaultValue;
if (node != null) {
Node tempNode = node.selectSingleNode(xpath);
if (tempNode != null) {
String nodeValue = tempNode.getText().trim();
returnValue = DataOperationUtils.parseFloat(nodeValue,
defaultValue);
}
}
return returnValue;
I appreciate for your answer thanks in advance
Looks like a compile problem. You sure that the class DataOperationUtils has a method called parseFloat that accepts the following types?
String
float
Possibly you need to typecast the parameters to match?

Resources