后台服务科尔多瓦离子应用程序。背景插件在 ios 8.3 上不起作用

Posted

技术标签:

【中文标题】后台服务科尔多瓦离子应用程序。背景插件在 ios 8.3 上不起作用【英文标题】:Background service cordova ionic app. Backgroudn plugin not working on ios 8.3 【发布时间】:2015-07-31 03:22:27 【问题描述】:

我想实现一个将地理位置发送到服务器的后台服务。因此我使用了来自https://github.com/katzer/cordova-plugin-background-mode 的插件cordova-plugin-background-mode,它适用于android

但是,如果我在 ios 8.3 上运行应用程序并按下主页按钮,应用程序将停止将地理位置发送到服务器。在插件的文档中它说:

支持的平台

    iOS(包括iOS8) Android(SDK >=11) WP8

我错过了什么吗?

编辑:这是我的控制器中的一些代码

$ionicPlatform.ready(function() 

  var watchOptions = 
    frequency : 1000,
    timeout : 5*60*1000,
    enableHighAccuracy: true 
  ;

  var watch = $cordovaGeolocation.watchPosition(watchOptions);
  watch.then(
    null,
    function(err) 
      alert("WatchPosition failed: "+JSON.stringify(err));
    ,
    function(position) 

      $scope.position = position;
    );
);

【问题讨论】:

【参考方案1】:

虽然我在探索相同的东西,但基本上没有纯粹的混合方式来实现后台位置跟踪。但是,如果您有兴趣,可以使用原生 iOS 实现来实现相同的功能。

在继续使用 Apple 后台位置跟踪之前,您必须了解一些可能的方法的详细信息。

一个苹果应用可以通过两种方式追踪位置,它们如下:


startUpdatingLocations

StartUpdatingLocations 是一种位置跟踪启动方法,它将导致每秒调用一次位置更改回调,除非您的应用程序处于前台/后台。

无论位置是否发生变化,每秒都会调用一次回调,由方法来处理和决定位置变化,实际上是位置变化。

当应用程序处于暂停/终止状态时,StartUpdatingLocations 将不起作用。这实质上意味着即使在应用启动时调用了 StartUpdatingLocations,只要应用在后台移动,即使位置发生任何变化,也将不再调用回调。

StartUpdatingLocations 提供最准确的位置更新。


startMonitoringSignificantLocationChanges

    StartMonitoringSignificantLocationChanges 是一种位置跟踪启动方法,只要用户位置发生重大变化,就会调用位置更改回调。

    此方法主动使用蜂窝塔位置更改,并且据记录,每 500-1000 米提供一次位置更新。

    即使应用处于后台/终止/暂停状态,StartMonitoringSignificantLocationChanges 也可以继续更新位置。

    这种方法的位置更新不是很可靠,个人使用表明位置更新有点随意,并且严重依赖于蜂窝位置更新。


现在您要尝试做的事情在 Android 中非常简单,但在 iOS 中却不是这样。

我不会重新发明循环,但您可以探索完整的细节here

iOS 7和8在后台连续获取位置的方法是使用“startUpdatingLocation”方法

[myLocationManager startUpdatingLocation];

然后下一个技巧将是委托方法“didUpdateLocations”。您将不得不使用计时器并适当地处理后台任务。任何遗漏的步骤和位置都不会持续更新。

但在应用终止/挂起时获取位置的情况下,不能使用[myLocationManager startUpdatingLocation];使其工作的唯一方法是使用:-

[anotherLocationManager startMonitoringSignificantLocationChanges];

另一个重要的技巧是,您必须知道如何处理应用程序委托“didFinishLaunchingWithOptions”上的键“UIApplicationLaunchOptionsLocationKey”。这是示例代码:-

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    self.shareModel = [LocationShareModel sharedModel];

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])  
      self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
      self.shareModel.anotherLocationManager.delegate = self;
      self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
      self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

      if(IS_OS_8_OR_LATER) 
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
      
     [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];   

        
        return YES;
    

除了 didFinishLaunchingWithOptions 方法之外,您还必须在应用程序处于活动状态时创建一个 locationManager 实例。以下是一些代码示例:

    - (void)applicationDidEnterBackground:(UIApplication *)application
    
        [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

        if(IS_OS_8_OR_LATER) 
            [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
        
        [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
    

    - (void)applicationDidBecomeActive:(UIApplication *)application
    
        if(self.shareModel.anotherLocationManager)
            [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

        self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
        self.shareModel.anotherLocationManager.delegate = self;
        self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

        if(IS_OS_8_OR_LATER) 
            [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
        
        [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
    

【讨论】:

哇,感谢您的帮助,但有一种纯粹的混合方式可以在后台获取地理位置跟踪。使用 $cordovaGeolocation.watchPosition 并将位置更新添加到您的 info.plist 中,就像我的回答一样。 $cordovaGeolocation.watchPosition 必须在 $ionicPlatform.ready 函数中使用。稍后我将使用我的应用程序中的一些代码编辑我的问题。 您必须知道Apple对运行后台进程的应用程序非常严格。是的,请使用您的一些代码更新问题,以便更清晰地了解您的方法。 @Kingalione,这种方式仅在您的应用程序处于前台时才有效。一旦它在后台移动,它迟早会被终止。 好的,现在我遇到了后台模式的问题。就像你说的那样,它迟早会终止。那我怎么理解你的回答呢?我是否必须为自己的目的编写本机插件? 有没有人把所有这些放在一起,准备在 ionic[2]/cordova 中使用?在我开发代码时,如果没有 Mac 进行测试,我真的不想盲目地编写 Objective-C。此外,只看 Objective-C 会导致偏头痛。【参考方案2】:

我发现我必须在 xcode 中的资源下的 projectname-Info.plist 中添加背景模式,如下所示:

现在,即使应用处于后台或设备已锁定,它也会发送地理位置。

【讨论】:

已将其应用提升至App Store?不久前,我遇到了一个在后台运行的插件的问题。看那里!并且如下所述,可以更好地使用原生形式 @sioesi 不,它目前不在 App Store 中。感谢您的建议,我会密切关注这一点。我正在 Iphone 5s iOS 8.3 上进行测试,它工作正常。如果我遇到问题,我将实现原生表单。

以上是关于后台服务科尔多瓦离子应用程序。背景插件在 ios 8.3 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

科尔多瓦离子框架:获取位置后台服务

用于普通科尔多瓦的科尔多瓦离子插件?

离子 ios 应用程序无法访问互联网

离子/科尔多瓦谷歌地图插件的问题

如何编辑离子科尔多瓦插件

离子的背景服务