I'm wondering why does some monotouch features works well in simulator but fails on real device?
the same Ping class. it works perfectly from simulator but fails on the device. What is the difference? it there a way to make it work on device?
More over, I've found this article on how to implement ping in mac OS:
http://developer.apple.com/library/mac/#samplecode/SimplePing/Listings/SimplePing_m.html#//apple_ref/doc/uid/DTS10000716-SimplePing_m-DontLinkElementID_5
will it be possible to port this code to monotouch? being honest, I havent yet tried if it works on iOS, but I dont see anything why wouldn't it work there.
PS. I know about Reachability class, and yes, I do use it in my projects instead of ping!
This is most likely an issue with what iOS allows you to do.
Here is from one guy who tried to implement ping using raw sockets, and ran into iOS restrictions.
The original bugreport states that: "To do a ping requires a linux kernel capability (capget) or the ping binary on the device which doesn't exist." In other words: root access.
Here is a workaround, but it's not a ping implementation.
That said, it looks like somebody tried to port the SimplePing sample to iOS with success, so maybe it is possible after all - but it just hasn't been a priority to look into it (the Reachability class is after all available).
SimplePing for MonoTouch is now available here.
https://github.com/theonlylawislove/MonoTouch.SimplePing
Simple add this git repo as a submodule to your project, then "Add existing project" and add the "MonoTouch.SimplePing" to your project. There is one small helper class that will make things a little easier in the "MonoTouch.SimplePing.Test" project called "SimplePingHelper".
Then use the following code.
SimplePingHelper.Ping (
"192.168.5.77",
1000,
() => {
NSThread.MainThread.BeginInvokeOnMainThread (new NSAction (() => {
var alertView = new UIAlertView ("Response", "Success", null, null, new string[] { "Ok" });
alertView.Show ();
}));
},
() => {
NSThread.MainThread.BeginInvokeOnMainThread (new NSAction (() => {
var alertView = new UIAlertView ("Response", "Failure", null, null, new string[] { "Ok" });
alertView.Show ();
}));
});
This solution works in the simulator and every device I have tested.
Do not use any of the "RawSocket" hacks found on the internet. It is riddled with bugs with async code and issues with it working on some devices and not others. After pulling my hair out, I figured I would port that SimplePing project since I discovered that it does actually work.
Enjoy!
I'm wondering why does some monotouch features works well in simulator but fails on real device?
MonoTouch ask the operating system, e.g. the networking stack in this case, to do its bidding. The operating system is allowed to be different (and is) between the iOS simulator and devices and also behave differently at runtime.
What is the difference?
Just to re-enforce the main fact that Apple SDK provides an iOS simulator is not an emulator. It does not even try to emulate most of the restrictions of devices. E.g. it:
execute x86 code, not ARM code (like the Android emulator would require);
allows JIT'ing (which is nice since it allows MonoTouch to build really fast to debug under the simulator). That is not allowed (or even possible) on devices and we must use AOT compilation;
provide full access to the file system (as much as the current user can read);
does not provide simulated support for the some specific devices features (e.g. accelerometer);
the list goes on...
Some of the differences are great (it's much faster than an emulator running ARM code would be) while others can be pretty limiting (e.g. lack of support for hardware features) in certain scenarios.