I'm quite new to xamarin iOS programming, so this might be a dumb question..
Background: I'm making an application that should send alarms to users within a certaint range of an incident location. Sice the incidens can happen "anywhere", geofencing is not an option. I have tried using remote notifications, but I need to alert just the clients that is within range of incident, and not disturb the rest of the clients (that are too far from the incident). That means that i first have to get the current location of all users, and the notify just the ones that are within range. So i thought maybe SignalR might be a solution.
How can i get the ios application (iOS 7 and 8) to respond to a request from a SignalR hub when the application is backgrounded (as in user pressed home button on phone so that the application is no longer in the foreground). I need to be able to ask the client to send its current location back to the server when the server requests it. I might add that the client sends significant location changes back to the server, so the application is enabled for background tasks.
I have set up the hub to send a GetLocation request:
public void SendLocationRequest()
{
Clients.Others.locationRequestReceived();
}
On the client in the ViewDidLoad method:
_client.OnLocationRequestReceived +=
(sender, message) => InvokeOnMainThread(() => LocRequestReceived());
and the LocReuestReceived (i have just set it up to display a local notification for now):
void LocRequestReceived()
{
var notification = new UILocalNotification
{
FireDate = DateTime.Now.AddSeconds(1),
AlertAction = "Get Location",
AlertBody = "Should retrieve currentLocation",
ApplicationIconBadgeNumber = 1,
SoundName = UILocalNotification.DefaultSoundName
};
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
this woks fine as long as the app is on the foreground on the phone, but nothing happens when the app is bacgrounded. (it works on the simulator when backgrounded, but that migh be a bug in the simulator see http://krumelur.me/2014/09/23/my-ios8-adventure-as-a-xamarin-developer/ )
I quess my problem is that im calling InvokeOnMainThread(() => LocRequestReceived()), where I should perhaps call it on a background thread?? As i've said, i just started xamarin iOS development, so any input is greatly appreciated.
I ended up with a slightly different approach. I used native CFStreams to set up a persistent tcp connection instead of SignalR.
public CFReadStream readStream;
public CFWriteStream writeStream;
public void Connect()
{
if (readStream == null) {
CFStream.CreatePairWithSocketToHost ("SERVER_ADDRESS", "PORT", out readStream, out writeStream);
ConfigureStream (readStream);
//Added handler for streamevents
.....
readStream.Open ();
}
}
To enable the stream to be open even if app is backgrounded, this is essential (in addition to add the necessary background modes in Info.plist):
void ConfigureStream(CFStream stream)
{
var nsstream = new NSStream (stream.Handle);
if (stream.GetType () == typeof(CFReadStream)) {
**nsstream [NSStream.NetworkServiceType] = NSStream.NetworkServiceTypeVoIP;**
}
}