随着iOS 7支持更广泛的后台模式,是否有可能在iOS上终于拥有等效于Android服务的功能?
我所追求的是,在后台运行应用程序A,并让一个或多个应用程序B和C与该应用程序通信(而不显示应用程序A的GUI界面)。
请注意,使用连接性和推送通知可能不是一种选择,尽管这是推荐的做法。有什么想法?
随着iOS 7支持更广泛的后台模式,是否有可能在iOS上终于拥有等效于Android服务的功能?
我所追求的是,在后台运行应用程序A,并让一个或多个应用程序B和C与该应用程序通信(而不显示应用程序A的GUI界面)。
请注意,使用连接性和推送通知可能不是一种选择,尽管这是推荐的做法。有什么想法?
编辑:无法按预期工作。请查看此答案以获取最佳解决方案:推送通知
编辑:下一个解决方案仅在用户在应用程序中时有用,以保持同步。
没有办法永久后台执行任务,但您可以使用有限长度的任务来执行操作,当您制作有限长度时,只要应用程序处于活动状态,它就会一直运行,但是当您单击主屏幕按钮时,iOS 仅给您10分钟来执行任务并使其无效,但它为您提供了一个机会,即可以制作“使其无效处理程序块”,在其中可以在最终完成之前执行最后一些操作。
因此,如果您使用该处理程序块调用其他时间的有限长度任务,则可以通过运行10分钟的任务来模拟服务,并在其结束时调用其相同的任务,然后再进行10分钟,依此类推。
我在创建一个名为“Service”的接口项目中使用它。这里是代码:
//
// Service.h
// Staff5Personal
//
// Created by Mansour Boutarbouch Mhaimeur on 30/09/13.
// Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Service : NSObject
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;
@property (nonatomic) NSInteger frequency;
@property (nonatomic, strong) NSTimer *updateTimer;
- (id) initWithFrequency: (NSInteger) seconds;
- (void) startService;
- (void) doInBackground;
- (void) stopService;
@end
//
// Service.m
// Staff5Personal
//
// Created by Mansour Boutarbouch Mhaimeur on 30/09/13.
// Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//
#import "Service.h"
@implementation Service
@synthesize frequency;
-(id)initWithFrequency: (NSInteger) seconds{
if(self = [super init]){
self.frequency = seconds;
return self;
}
return nil;
}
- (void)startService{
[self startBackgroundTask];
}
- (void)doInBackground{
//Español //Sobreescribir este metodo para hacer lo que quieras
//English //Override this method to do whatever you want
}
- (void)stopService{
[self.updateTimer invalidate];
self.updateTimer = nil;
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
- (void) startBackgroundTask{
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:frequency
target:self
selector:@selector(doInBackground)
userInfo:nil
repeats:YES];
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundTask];
}];
}
- (void) endBackgroundTask{
[self.updateTimer invalidate];
self.updateTimer = nil;
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
[self startBackgroundTask];
}
@end
我使用这个类来执行我的服务,但是我已经很长时间没有进行测试了。 我进行的最好的测试在模拟器上持续了16小时,一切都正常!
编辑:那是在模拟器上测试的,但是在手机上,在应用程序被终止后就无法工作。
我给你举个例子:
// SomeService.h
@interface SomeService : Service
@end
// SomeService.m
#import "SomeService.h"
@implementation SomeService
// The method to override
- (void)doInBackground{
NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining);
NSLog(@"Service running at %.1f seconds", [self getCurrentNetworkTime]);
}
// Your methods
- (long) getCurrentNetworkTime{
return ([[NSDate date] timeIntervalSince1970]);
}
@end
在你的AppDelegate或者需要启动服务的地方,你可以写下以下的代码:
Service myService = [[SomeService alloc] initWithFrequency: 60]; //execute doInBackground each 60 seconds
[myService startService];
如果您需要停止它:
[myService stopService];
可能解释得有点多,但我希望对任何人来说都清晰明了!希望这有所帮助,对我的英语表示抱歉。
没有类似于Android Service的东西。MansApps的代码不起作用,至少在iOS7上不行。在到期处理程序中调用[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
只会在应用回到前台时返回,也就是说,在应用保持在后台时,[self startBackgroundTask];
将不会被执行。
我找到了最好的标准解决方案:
(原始帖子由Matthijs Hollemans发布,由Ali Hafizji更新)。
iOS中,应用程序不能在后台做很多事情。应用程序只允许进行有限的活动,以节省电池寿命。 但是,如果发生了一些有趣的事情,并且您希望让用户知道这一点,即使他们当前没有使用您的应用程序呢? 例如,也许用户收到了新的推文,他们最喜欢的团队赢得了比赛,或者他们的晚餐已经准备好了。由于应用程序当前未运行,因此无法检查这些事件。 幸运的是,苹果提供了解决方案。您可以编写一个服务器端组件来代替您的应用程序持续检查事件或在后台执行工作。 当发生感兴趣的事件时,服务器端组件可以向应用程序发送推送通知!推送通知可以执行三个操作: