Xamarin iOS: Value cannot be null. Parameter name: key - entity-framework

I have a xamarin forms solution, where I have everything working, except for physical iOS devices. It works 100% on emulated iOS, Android, and physical Android devices, but not physical iOS devices.
Let me elaborate. The solution runs on physical iOS Devices and it goes to a login screen, where I then connect to my database and login. This works on everything except physical iOS devices.
The error that I get is:
The type initializer for 'Microsoft.EntityFrameworkCore.SqlServer.Query.ExpressionTranslators.Internal.SqlServerCompositeMethodCallTranslator' threw an exception.
The inner exception:
Value cannot be null.
Parameter name: key
This is the stack trace:
at System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) [0x00008] in <c4da4bcb0a614f31bf9f25261a36b747>:0
at System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) [0x00000] in <c4da4bcb0a614f31bf9f25261a36b747>:0
at Microsoft.EntityFrameworkCore.SqlServer.Query.ExpressionTranslators.Internal.SqlServerDateAddTranslator..ctor () [0x000c5] in <841b527f2aa54cccaf5150a4cca376c9>:0
at Microsoft.EntityFrameworkCore.SqlServer.Query.ExpressionTranslators.Internal.SqlServerCompositeMethodCallTranslator..cctor () [0x00016] in <841b527f2aa54cccaf5150a4cca376c9>:0
I am using Entity Framework Core 2.1.2 and my target framework, on my data project, is .NET Standard 2.0
Why would a physical iOS Device be different from a emulated one?
What can I do to get past this error?
Is there anyway that I can find out what value it is finding to be null?
Edit
I found out that my problem is that I am not connecting to my database. Though I can't figure out what is wrong with my connection.
Is there anything wrong with this method of connecting to a sql server?
(Note: the dev and main DB are correct as everything else works just fine using
those connection strings)
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
//optionsBuilder.UseSqlServer(
// "System.Data.SqlClient",
// options => options.EnableRetryOnFailure(1, TimeSpan.FromSeconds(30), null));
string cn;
if(Debugger.IsAttached)
{
cn = devDB;
}
else
{
cn = mainDB;
}
SqlConnectionStringBuilder cns = new SqlConnectionStringBuilder();
cns.ConnectionString = cn;
optionsBuilder.UseSqlServer(cns.ConnectionString, options => options.EnableRetryOnFailure(1, TimeSpan.FromSeconds(60), null));
}

Why would a physical iOS Device be different from a emulated one?
The answer is in your question :) At first - iOS uses Simulator, not emulator. :)
The difference is that the simulator does not try to emulate the real performance of the device (clock speed, i/o, and etc). It would allocate the RAM of the device (like on iPhone 5S it would show you 512MB of maximum RAM, but in iPhone X 2 GB). But for everething else, it would use the full performance of your machine (like CPU or writing/reading speed).
Anyway, the main problem is that in order to run the app in the simulator you need all frameworks to be built for x86 architecture. That the problem. Sometimes people do not build the library for mobile or desktop architecture. You are very lucky that you did not face that problem so far :))) The difference in build process may introduce unpredictable bugs, so it's always a MUST to test on the device.
What can I do to get past this error?
It's hard to tell because the error message is so generic. I would personally begin by making sure that DB is present on the device and my code could at least open a connection to it.
Is there anyway that I can find out what value it is finding to be
null?
It's something related to insert. Maybe, just maybe you were reading from a DB all that time, and only now try to insert. If yes, then your reading from your DB that is located in Bundle. You would need to copy it into documents folder in order to write to it.
Hope it helps!

Related

Corebluetooth glitch on iPhone 4S?

I have been working extensively testing out the BLE capabilities of the iPhone 4s as well as the iPhone 5.
At the moment, all I have been accomplishing is pulling in the advertisement data from multiple TI BLE keyfobs and populating a UITableView with the kCBAdvDataLocalName, ManufacturingData, and ServiceUUIDs for each respective device.
Basically, as I pull in the advertisement data, I am also pulling in the peripheral's UUID and using this to populate the datasource array for the tableview. (i.e. if a new UUID is found and it is not in the datasource array, add it to the array and use that to retrieve the respective peripheral).
With the iPhone 5 this works flawlessly. However, when I test with an iPhone 4S (and I have tested with multiple) the BLE hardware pulls in NULL UUIDs therefore preventing me from adding any peripheral's info to the datasource array. In my console log, the phone does indeed discover each peripheral, and displays its localname, and manufacturing data, but every single device has a null UUID.
I have also ran my testing app on a 4S and a 5 simultaneously with the exact same code, and it will work on the 5 and not the 4S. So I was wondering if anyone has been having this same issue, whether it was a bug in the SDK or the hardware, or if there is a known workaround? Any feedback will be greatly appreciated, thanks.
The problem in iOS 6 is that the UUID's are not generated until you've actually connected to the device. UUID's are generated on the iOS side for each peripheral, so that's why you'll typically see a different UUID for the same peripheral when using different iOS devices. I usually check the UUID, and then if it is NULL, I will go off of the name. If the name is NULL however, then I do not populate it in the device list. Your other option is to quickly connect and then disconnect from the device. A big time hack, but it will generate the UUID and then be non-null from then on. Supposedly this problem will be fixed in the next version of iOS.

Safely achieving three and four way device synchronisation without [[UIDevice] uniqueIdentifier]?

Switching to custom generated device UUID's is turning out to truly be a nightmare! I am hoping someone has come across this before and might know a way to deal with it.
Assume a user has an application with a data set of 500,000 (small) records, its not feasible to simply copy the entire db of a device and merge them. A user has this application installed on an:
iPhone,
MacBook
Android tablet.
When connected to the same physical network, each device can see each other and can initiate a synchronisation.
To achieve three way data synchronisation (that does not depend on a central server or an internet connection).
Each device keeps a list of timestamped changes.
Each device knows the last time it synchronised with each of the other two devices.
When a device sees another device, it sends through all known changes since the last time they spoke to that device.
If a new device is discovered, no problem just send through all data ever entered.
The problem comes along if a user backs up their iphone or ipad, and restores it onto another iphone or ipad. Under this scenario we are ending up with a user that has two devices on the local network with the same UUID. Updates end up (randomly) going to one or the other identically identified devices.
I know we can continue to use the device unique identifier for now, but I am worried whats going to happen once its gone!
On application start you search for a file in the applications documents folder called udid.txt. If this file is not available create it and generate your custom UDID, save it to this file. Use the following function to add a flag to this file, to exclude it from the backup and sync routines.
#include <sys/xattr.h>
- (void) AddSkipBackupAttributeToFile: (NSURL*) url
{
  u_int8_t b = 1;
  setxattr([[url path] fileSystemRepresentation], "com.apple.MobileBackup", &b, 1, 0, 0);
}
The problem with this solution is that a user might use iPhoneExplorer or something similar to change the UDID. Try to encrypt or hide the file to prevent him from doing this.
Note: Works only since iOS 5.0.1.
You can instead store your generated device UDID in a file in the Caches directory, where it will not be backed up. When a backup is restored onto a new device, the database will be present but there will be no UDID file. In this case create a new UDID; the other instances will see this as a new instance and can push any recent changes across. You might want to change the logic so the other instances will query the timestamp on a new UDID instead of assuming the new instance is totally empty.
Before iOS 5.0, your UDID file will not be automatically deleted by the system. However in iOS 5.0 you will need to put up with the fact that it may get purged in low disk space situations. If that happens, just follow the same procedure as when restored onto a new device: create a new UDID; the other instances will see this as a new instance and push recent changes across.
As Floix said, there is a new mechanism in iOS 5.0.1 (yet to be released) which will let you specify that the file should be neither backed up nor purged.

iPhone app crashing on some devices -- looking for advice

Hey everyone, I'm in a bit of a pickle and am looking for some advice.
I have an app that's been released to the app store..nothing special just a first time sort of thing. The app runs perfectly fine on my device(s) but a couple buddies always get a crash.
So here's the details:
It crashes by sometimes stalling and other times by just exiting to the main screen.
I've tried to replicate the crash (or any crash) using
the same iPhone generation/model
on an ipod touch as well
the same OS
different OS
using debug/release/distribution/downloading from app store builds
since it's an app that connects to a google maps service, I've tried with both
a wifi connection and the att network.
The only thing that MAY be different is any other apps on their phones that are not on mine.
The fact that I cannot replicate with exactly the same setup leads me to believe it's a memory issue, maybe uninitialized variables or incorrect cleanup at some point (i'm from C++, so I know this sort of thing can vary from machine to machine). I'm somewhat new to obj C and may very well be missing something there. I'm just curious to hear what others have to say, does this sound like a memory issue with the info I've provided? Any other ideas to test/suggestions come to mind to try and reproduce the crash?
Thanks!
One possibility is that it's a backgrounding issue. You don't say whether your app tries to use those features or whether your friends experience the crash in that context, so it's hard to say.
I would provision your friends with a beta that logs verbosely if you can't pin it down.

about WifiManager.bundle

What will be the result of the
libHandle = dlopen("/System/Library/SystemConfiguration/WiFiManager.bundle/WiFiManager", RTLD_LAZY);
I'm using this for getting wifi info on ipod os 3.1.2., because when I NSLog(#"Result %#",libhandle); I'm getting null what should be the answer,
thanks
According to this discussion, doing the above will return NULL on the iPhone Simulator, because it lacks the required bundle. If you are still running into issues with this on the device, it might be that Apple has changed the internal file structure for that system item. This is one of the reasons why it is bad to rely in private APIs.
For more on WiFi snooping, you might refer to the source code for this project, because they might have resolved these issues. However, once again I'd like to remind you that you will not be able to submit an application to the App Store that uses this, because of the private API calls. Apple is now scanning all submitted applications for these calls and instantly rejecting them.

Debugging j2me on a Device

Has anybody had any success ever attaching a debugger to a tethered device? I am able to debug my j2me application in the emulator, but have a lot of trouble sorting out phone-specific problems when they come up. The phone I'm using is a Nokia N95, but ideally the debug process would work on any phone.
Is this possible? If so does anyone have steps they've used to set it up?
Sony Ericsson supports debugging on ebery phone at least since K700, this is done by using KDWP. UIQ 3 communicators also can be debugged the same way.
By the way, it the latest phones by SE it is even possible to monitor memory consumption and CPU profiling. So if you wanna debug your apps on real phones, I would suggest also using SE phones, they are really good at it. I use Netbeans, and it works without any problems with any SE phone.
Motorola phones support a debugging interface called KDWP(Motodev registration required).Their MIDway tool can also be useful for getting debug trace information from a midlet running on a device.
As other stated, on device debug is something that strictly depends on manufacturer's will and often it's nearly impossible. However, i can address you to Gear Java Mobile Framework that gives you the opportunity to use an on-device debug console to print your messages and thus read phone specific issues. If you need some explanation on how to use it, take a look to this tutorial
Unfortunately this is not generally possible. Some makers (like Sony-Erricson) support this on some of their phones but not all. I am not sure if there is on-device-debugging tool for N95 but you can use Nokia's emulator which should be pretty close to the device. The new Java ME SDK comes with promise of real ODD in near future. But it still very much depends on OEM cooperation.
I find a good debugging method is to control a string value which gets painted on top of everything else when it is not null. This will work anywhere, though obviously isn't ideal, but can be used to catch Exceptions, print values etc. Of course you're limited to the small screen, but in theory you could even code some scrolling functionality.
Some people use RMS logging but personally I could never be bothered.
As others have said here, Motorola have Midway which I think is great.
Others are correct here in that on-device debugging is very much device specific. I haven't done anything with Series 60, but at least on Series 40 phones, I had to open up a CommConnection and write out to it in order to see much of anything going on. The device emulators are again a mixed bag, but you usually can get 90% of the way to your application working on them and can usually get your debugger connected to them. If you aren't making use of any of the hardware on the phone, that should get you most of the way there.
I've used the Blackberry tools on occasion to debug J2ME applications (without using RIM APIs) but it is very slow and still is only emulation, not the actual device (but it sometimes does help to shake the odd thing out). I agree it is frustrating when you have something running on an emulator only to find that it doesn't run on the hardware.
You can not debug step by step like android or other SDK.
In J2ME you can trace the error by adding the log statement in the code and add another midlet and display that log screen in that midlet.
Example: add Log.p("Log statement.....");
LogMidlet.java
// Add the following line in the startup method of this midlet.
Log.getInstance().showLog();
This way you can somehow track the error in j2me.
I think it is possible to add additional debugging information on preprocess step. Like this:
public void myMethod() {
Debug.traceMethod("myMethod");
int var = 1;
Debug.newLine();
var++;
Debug.newLine();
...
}