How to obtain iOS device CPU architecture in Xamarin? - xamarin.ios

In my Xamarin iOS application, I can obtain many device characteristics such as model, system name, etc. from UIKit.UIDevice.CurrentDevice instance. However, I don't see any method to obtain CPU architecture (x86, arm, etc.) on the class.
How can I get the iOS device CPU architecture in runtime shows a way to get this information using Objective C. I am wondering if there a way to get the CPU information in C# using any of the predefined Xamarin classes.

Create a new file with this class on your iOS project:
public static class DeviceInfo
{
public const string HardwareSysCtlName = "hw.machine";
public static string HardwareArch { get; private set; }
[DllImport(ObjCRuntime.Constants.SystemLibrary)]
static internal extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output, IntPtr oldLen, IntPtr newp, uint newlen);
static DeviceInfo()
{
var pLen = Marshal.AllocHGlobal(sizeof(int));
sysctlbyname(HardwareSysCtlName, IntPtr.Zero, pLen, IntPtr.Zero, 0);
var length = Marshal.ReadInt32(pLen);
var pStr = Marshal.AllocHGlobal(length);
sysctlbyname(HardwareSysCtlName, pStr, pLen, IntPtr.Zero, 0);
HardwareArch = Marshal.PtrToStringAnsi(pStr);
}
}

Today, I found that this code works not only for Windows(UWP), but also for iOS With Xamarin:
System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString();
With iOS Simulator, RuntimeInformation has more information, like OSArchitecture, but with real iOS device, only ProcessArchitecture was available.
I used all available recent softwares: Xcode 12.4, Visual Studio for Mac 8.9 (1651), etc.

Related

Node.js/Electron - Can I reset the system idle time?

It's quite easy to get the system idle time in Electron with powerMonitor.getSystemIdleTime() However, I wonder if there is any easy way to reset this? I tried both the powerSaveBlocker.start('prevent-app-suspension') and the powerSaveBlocker.start('prevent-display-sleep') but they don't really reset the idle time.
When I use the Caffeine on the Mac OSX I noticed it works perfectly. It keeps reseting the system idle time.
Checked into the Caffeine source code. It's written in C#, not sure how can we make it in Node.js/Electron.
internal static class NativeMethods {
[DllImport("kernel32.dll")]
public static extern uint SetThreadExecutionState(uint esFlags);
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
public const uint ES_DISPLAY_REQUIRED = 0x00000002;
}
Any good ideas?

UDP sockect about string in UWP

I find a strange problem when I write code in UWP.
I use UDP sockect to send a coordinates to hololens.
The coordinate is like "1.0_1.0_1.0", it was send as string and will be cut according to "_",then the coordinate will be used to control the moving of a sphere.
First of all, it run all right in the unity editor.
But in the hololens, for example, I only receive "1.0_1.0_1.0", but cannot change it to vector3:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity;
#if !UNITY_EDITOR
using System;
using Windows.Foundation;
#endif
public class pre : MonoBehaviour
{
public TextMesh tm = null;
public TextMesh tmmm = null;
public GameObject sphere;
string test;
public void ResponseToUDPPacket(string incomingIP, string incomingPort, string data)
{
string[] centre = data.Split('_');
float[] num= new float[3];
if (tm != null)
tm.text = data;
num[0] = float.Parse(centre[0]);
num[1] = float.Parse(centre[1]);
num[2] = float.Parse(centre[2]);
Debug.Log(num[1]);
if (tmmm != null)
tmmm.text = num[1].ToString();
sphere.transform.position = new Vector3(num[0], num[1], num[2]);
//var headPosition = Camera.main.transform.position;
//headPosition.z = headPosition.z+10;
//sphere1.transform.position = headPosition;
}
}
I use two testmesh to show the result, "data"is the string I have received, the first "tm" doesn't have problem.for example, it will show"1.0_1.0_1.0".
But the "tmm" which is get according to num[1] is never work.
I have thought it is the problem of UWP.
BUT!!!!!!!!!!!!!!!!!!!!!!!
I send the UDP string by a c++ program, but when I use a software(UDPsender or something like it) to send string manually, the problem in hololens disappeared!
But I don't think there is a problem in my C++ program, because at least it run well in unity editor.
Is there anyone has idea about the problem?
Maybe your emulator and your device have different cultures and one understands 1.0 while the other expects 1,0 in the float.Parse.
You can pass your culture (or InvariantCulture) to float.Parse if that is the case.
Does the Debug.Log(num[1]) print the correct number in all cases? If not, this could confirm the above theory.

Is ServiceStack ORMLite available for .NET Core

I saw some commits for ServiceStakck ORMLite for .NET Core specifically this
Can we try it right now or it is just nuget spec update? I am looking to integrate ServiceStack ORMLite for .Net core project (ServiceStack.OrmLite.PostgreSQL.Core).
All of OrmLite's supported packages contains both .NET Framework v4.5 and .NET Standard 2.0 builds which can be used in both .NET Framework and .NET Core projects which can be used like normal:
public class Person
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
}
public class Program
{
public static string PostgreSqlDb = "{Connection String}";
public static void Main(string[] args)
{
var dbFactory = new OrmLiteConnectionFactory(
PostgreSqlDb, PostgreSqlDialect.Provider);
using (var db = dbFactory.Open())
{
db.DropAndCreateTable<Person>();
5.Times(i => db.Insert(new Person { Name = "Name {i}" }));
var results = db.Select<Person>();
results.PrintDump();
}
Console.ReadLine();
}
}
As say in NuGet package's details page, you can use it with .Net Core with at least .NETStandard 1.3.
But if you look into the latest release note. They say :
Just like the other .NET Core libraries .NET Core builds of
ServiceStack.Redis is released with a *.Core suffix until development
of .NET Core has stabilized.

Reusable generic LightSwitch screen with WCF RIA Services

I'm new to WCF RIA Services, and have been working with LightSwitch for 4 or so months now.
I created a generic screen to be used for editing lookup tables all over my LightSwitch application, mostly to learn how to create a generic screen that can be used with different entity sets on a dynamic basis.
The screen is pretty simple:
Opened with arguments similar to this:
Application.ShowLookupTypesList("StatusTypes", "StatusTypeId"); which correspond to the entity set for the lookup table in the database.
Here's my WCF RIA service code:
using System.Data.Objects.DataClasses;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Server;
namespace WCF_RIA_Project
{
public class LookupType
{
[Key]
public int TypeId { get; set; }
public string Name { get; set; }
}
public static class EntityInfo
{
public static Type Type;
public static PropertyInfo Key;
public static PropertyInfo Set;
}
public class WCF_RIA_Service : LinqToEntitiesDomainService<WCSEntities>
{
public IQueryable<LookupType> GetLookupTypesByEntitySet(string EntitySetName, string KeyName)
{
EntityInfo.Set = ObjectContext.GetType().GetProperty(EntitySetName);
EntityInfo.Type = EntityInfo.Set.PropertyType.GetGenericArguments().First();
EntityInfo.Key = EntityInfo.Type.GetProperty(KeyName);
return GetTypes();
}
[Query(IsDefault = true)]
public IQueryable<LookupType> GetTypes()
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var types = from e in set
select new LookupType
{
TypeId = (int)EntityInfo.Key.GetValue(e, null),
Name = (string)EntityInfo.Type.GetProperty("Name").GetValue(e, null)
};
return types.AsQueryable();
}
public void InsertLookupType(LookupType lookupType)
{
dynamic e = Activator.CreateInstance(EntityInfo.Type);
EntityInfo.Key.SetValue(e, lookupType.TypeId, null);
e.Name = lookupType.Name;
dynamic set = EntityInfo.Set.GetValue(ObjectContext, null);
set.AddObject(e);
}
public void UpdateLookupType(LookupType currentLookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
dynamic modified = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == currentLookupType.TypeId);
modified.Name = currentLookupType.Name;
}
public void DeleteLookupType(LookupType lookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var e = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == lookupType.TypeId);
Debug.Assert(e.EntityState != EntityState.Detached, "Entity was in a detached state.");
ObjectContext.ObjectStateManager.ChangeObjectState(e, EntityState.Deleted);
}
}
}
When I add an item to the list from the running screen, save it, then edit it and resave, I receive data conflict "Another user has deleted this record."
I can workaround this by reloading the query after save, but it's awkward.
If I remove, save, then readd and save an item with the same name I get unable to save data, "The context is already tracking a different entity with the same resource Uri."
Both of these problems only affect my generic screen using WCF RIA Services. When I build a ListDetail screen for a specific database entity there are no problems. It seems I'm missing some logic, any ideas?
I've learned that this the wrong approach to using LightSwitch.
There are several behind-the-scenes things this generic screen won't fully emulate and may not be do-able without quite a bit of work. The errors I've received are just one example. LightSwitch's built-in conflict resolution will also fail.
LS's RAD design means just creating a bunch of similar screens is the way to go, with some shared methods. If the actual layout needs changed across many identical screens at once, you can always find & replace the .lsml files if you're careful and make backups first. Note that modifying these files directly isn't supported.
I got that error recently. In my case I create a unique ID in my WCF RIA service, but in my screen behind code I must explicitly set a unique ID when I create the object that will later be passed to the WCF RIA Service insert method (this value will then be overwritten with the unique counter ID in the table of the underlying database).
See the sample code for this project:
http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/157/A-Visual-Studio-LightSwitch-Picture-File-Manager.aspx

MonoTouch, NSLog, and TestFlightSdk

I am trying to integrate the TestFlightSdk into an app I've made using MonoTouch.
I am trying to implement logging in my app in such a way that it is picked up by the TestFlightSdk. It supposedly picks up NSLogged text automatically, but I can't seem to find the right combination of code to add to my own app, written in C#/MonoTouch, that does the same.
What I've tried:
Console.WriteLine("...");
Debug.WriteLine("..."); (but I think this just calls Console.WriteLine)
Implementing support for NSlog, but this crashed my app so apparently I did something wrong (I'll ask a new question if this is the way to go forward.)
Is there anything built into MonoTouch that will write log messages through NSLog, so that I can use it with TestFlightSdk? Or do I have to roll my own wrapper for NSLog?
In order to implement NSLog myself, I added this:
public static class Logger
{
[DllImport("/System/Library/Frameworks/Foundation.framework/Foundation")]
private extern static void NSLog(string format, string arg1);
public static void Log(string message)
{
NSLog("%s", message);
}
}
(I got pieces of the code above from this other SO question: How to I bind to the iOS Foundations function NSLog.)
But this crashes my app with a SIGSEGV fault.
using System;
using System.Runtime.InteropServices;
using Foundation;
public class Logger
{
[DllImport(ObjCRuntime.Constants.FoundationLibrary)]
private extern static void NSLog(IntPtr message);
public static void Log(string msg, params object[] args)
{
using (var nss = new NSString (string.Format (msg, args))) {
NSLog(nss.Handle);
}
}
}
Anuj pointed the way, and this is what I ended up with:
[DllImport(MonoTouch.Constants.FoundationLibrary)]
private extern static void NSLog(IntPtr format, IntPtr arg1);
and calling it:
using (var format = new NSString("%#"))
using (var arg1 = new NSString(message))
NSLog(format.Handle, arg1.Handle);
When I tried just the single parameter, if I had percentage characters in the string, it was interpreted as an attempt to format the string, but since there was no arguments, it crashed.
Console.WriteLine() works as expected (it redirects to NSLog) on current xamarin.ios versions. Even on release builds (used by hockeyapp, etc). No need to use DllImport anymore.

Resources