草庐IT

ios - 在 apple iWatch 中,后台任务未被调用或按计划时间触发

coder 2023-09-23 原文

当应用程序在后台触发任务时更新位置。但无法以后台模式执行任务。我的 scheduleBackgroundRefreshWithPreferredDate 示例代码如下

[WKExtension.sharedExtension scheduleBackgroundRefreshWithPreferredDate:[NSDate dateWithTimeIntervalSinceNow:60] userInfo:nil scheduledCompletion:^(NSError * _Nullable error) {

        if(error == nil) {
            NSLog(@"background refresh task re-scheduling successfuly  ");

        } else{

            NSLog(@"Error occurred while re-scheduling background refresh: %@",error.localizedDescription);
        }
    }];

handleBackgroundTasks: 中调度任务重新调度后

- (void)handleBackgroundTasks:(NSSet<WKRefreshBackgroundTask *> *)backgroundTasks
{
    for (WKRefreshBackgroundTask * task in backgroundTasks) {

        if ([task isKindOfClass:[WKApplicationRefreshBackgroundTask class]]) {
            WKApplicationRefreshBackgroundTask *backgroundTask = (WKApplicationRefreshBackgroundTask*)task;
            // location update methods schedule as background task
            [self startLocationUpdate];
            [backgroundTask setTaskCompleted];

        } else if ([task isKindOfClass:[WKSnapshotRefreshBackgroundTask class]]) {
            WKSnapshotRefreshBackgroundTask *snapshotTask = (WKSnapshotRefreshBackgroundTask*)task;
            [snapshotTask setTaskCompletedWithDefaultStateRestored:YES estimatedSnapshotExpiration:[NSDate distantFuture] userInfo:nil];

        } else if ([task isKindOfClass:[WKWatchConnectivityRefreshBackgroundTask class]]) {
            WKWatchConnectivityRefreshBackgroundTask *backgroundTask = (WKWatchConnectivityRefreshBackgroundTask*)task;
            [backgroundTask setTaskCompleted];

        } else if ([task isKindOfClass:[WKURLSessionRefreshBackgroundTask class]]) {
            WKURLSessionRefreshBackgroundTask *backgroundTask = (WKURLSessionRefreshBackgroundTask*)task;
            [backgroundTask setTaskCompleted];

        } else {
            [task setTaskCompleted];
        }
    }
}

后台任务方法如下

-(void)startLocationUpdate {

    locationMgr = [[CLLocationManager alloc] init];
    [locationMgr setDelegate:self];

    locationMgr.desiredAccuracy = kCLLocationAccuracyBest;
    locationMgr.distanceFilter = kCLDistanceFilterNone;

    //    locationMgr.allowsBackgroundLocationUpdates = YES;

    [locationMgr requestAlwaysAuthorization];
    [locationMgr startUpdatingLocation];

    [WKExtension.sharedExtension scheduleBackgroundRefreshWithPreferredDate:[NSDate dateWithTimeIntervalSinceNow:60] userInfo:nil scheduledCompletion:^(NSError * _Nullable error) {

        if(error == nil) {
            NSLog(@"background refresh task re-scheduling successfuly  ");

        } else{

            NSLog(@"Error occurred while re-scheduling background refresh: %@",error.localizedDescription);
        }
    }];

}
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray<CLLocation *> *)locations {

    NSTimeInterval locationAge = -[[locations lastObject].timestamp timeIntervalSinceNow];

    NSLog(@"Location Age : %f",locationAge);

    if (locationAge > 5.0) return;

    NSLog(@"latitude: %f longitude: %f",[locations lastObject].coordinate.latitude,[locations lastObject].coordinate.longitude);

    //NSString *strLocation = [NSString stringWithFormat:@"%f,%f" ,[locations lastObject].coordinate.latitude , [locations lastObject].coordinate.longitude];
    NSString *strLocation = @"bgLocation";

    NSDictionary *applicationData = [[NSDictionary alloc] initWithObjects:@[strLocation] forKeys:@[@"watchlocation"]];

   [[WCSession defaultSession] transferUserInfo:applicationData];

}

最佳答案

后台执行在 watchOS3 上非常困难。有很多限制,即使您成功安排了后台刷新任务,也不能保证 watchOS 会启动它。

根据我深入研究 WWDC session 和文档后的经验:

  1. 如果应用程序不在 Dock 中或当前表盘上没有事件的复杂功能,watchOS3 将不会为您的应用程序提供任何后台执行时间
  2. 对于 Dock 中的应用,后台刷新任务的数量限制为每小时 1 次左右,对于具有事件并发症的应用,每小时限制为 2 次
  3. 后台执行的时间也是有限制的,如果app超过这个时间,就会被watchOS daemon终止
  4. 调用 setTaskCompleted 后,应用会进入挂起状态,因此不应执行代码中的异步 locationManager:didUpdateLocations: 方法

关于ios - 在 apple iWatch 中,后台任务未被调用或按计划时间触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44649768/

有关ios - 在 apple iWatch 中,后台任务未被调用或按计划时间触发的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  3. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  6. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  7. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  10. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

随机推荐