当应用程序后台运行时,让iOS客户端响应SignalR请求

时间:2014-10-01 07:30:49

标签: ios iphone xamarin signalr background-process

我对xamarin iOS编程很新,所以这可能是一个愚蠢的问题..

背景: 我正在制作一个应该在事件位置的某个范围内向用户发送警报的应用程序。可以“任何地方”发生犯罪,地理围栏不是一种选择。我尝试过使用远程通知,但我需要提醒事件范围内的客户端,而不是打扰其他客户端(距离事件太远)。这意味着我首先必须获取所有用户的当前位置,并通知范围内的用户。所以我想也许SignalR可能是一个解决方案。

当应用程序处于后台时,如何让ios应用程序(iOS 7和8)响应来自SignalR集线器的请求(如用户在电话上按下主页按钮,以便应用程序不再位于前台) 。我需要能够要求客户端在服务器请求时将其当前位置发送回服务器。我可能会添加客户端将重要的位置更改发送回服务器,因此应用程序已启用后台任务。

我已设置集线器以发送GetLocation请求:

public void SendLocationRequest()
{
    Clients.Others.locationRequestReceived();
}

在ViewDidLoad方法中的客户端上:

_client.OnLocationRequestReceived +=
          (sender, message) => InvokeOnMainThread(() => LocRequestReceived());

和LocReuestReceived(我刚刚设置它以显示本地通知):

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);
    }
只要应用程序位于手机的前台,这就好了,但是当应用程序被禁止时没有任何反应。 (它在后台运行时可以在模拟器上运行,但这很可能是模拟器中的一个错误,请参阅http://krumelur.me/2014/09/23/my-ios8-adventure-as-a-xamarin-developer/

我问我的问题是我调用 InvokeOnMainThread (()=> LocRequestReceived()),我应该在后台线程上调用它? 正如我所说的,我刚刚开始使用xamarin iOS开发,因此非常感谢任何输入。

1 个答案:

答案 0 :(得分:1)

我的结果略有不同。我使用本机CFStreams来设置持久的tcp连接而不是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 ();
    }
}

要启用流,即使应用程序是后台运行,这也是必不可少的(除了在Info.plist中添加必要的后台模式):

void ConfigureStream(CFStream stream)
    {
        var nsstream = new NSStream (stream.Handle);
        if (stream.GetType () == typeof(CFReadStream)) {
            **nsstream [NSStream.NetworkServiceType] = NSStream.NetworkServiceTypeVoIP;**
        }
    }