因此,iOS 7支持更广泛的后台模式,是否有可能最终在iOS上拥有与Android服务相同的功能?
我所追求的实际上是在后台运行应用程序A并且有一个或多个应用程序B和C与该应用程序通信(不显示应用程序A的GUI)。
请注意,使用连接和推送通知可能不是一种选择,尽管这是建议的方法。 有任何想法吗?
答案 0 :(得分:5)
编辑:未按预期工作。请参阅此答案以获取最佳解决方案:Push Notifications
编辑:下一个解决方案仅在用户在应用中时保持同步才有用。
无法永久地在后台执行任务,但您可以使用有限长度的任务来执行此操作,当您进行有限长度时,这将在应用程序处于活动状态时始终运行,但是当您单击时主页按钮,ios只给你10分钟的时间来执行你的任务并使它无效,但它让你有机会制作一个'无效处理程序块',你可以在完成之前做最后的动作。
因此,如果您使用该处理程序块在其他时间调用有限长度的任务,您可以通过运行任务10分钟来模拟服务,当它结束时,在其他10分钟内调用它,因此德尔>
我在创建界面“服务”的项目中使用它。我在这里给你代码:
//
// 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
在你的app delegate或你需要提升服务的地方,你写下一行:
Service myService = [[SomeService alloc] initWithFrequency: 60]; //execute doInBackground each 60 seconds
[myService startService];
如果你需要阻止它:
[myService stopService];
可能已经解释了超过必要的,但我想对任何人保持清醒! 我希望得到帮助,对不起我的英语。
答案 1 :(得分:2)
不,没有相当于Android服务。 MansApps代码不起作用,至少在iOS7上没有。在到期处理程序中调用[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
只会在应用程序返回到前台时返回,即,当应用程序停留在后台时,将不会执行[self startBackgroundTask];
的调用。
答案 2 :(得分:0)
我找到了最好的标准解决方案:
(Matthijs Hollemans的原帖,Ali Hafizji的更新)。
在iOS中,应用程序在后台无法做很多事情。应用程序只允许进行有限的活动,因此可以节省电池寿命。 但是,如果发生了一些有趣的事情并且您希望让用户知道这一点,即使他们目前没有使用您的应用程序,该怎么办? 例如,也许用户收到了新的推文,他们最喜欢的球队赢得了比赛,或者他们的晚餐准备好了。由于应用程序当前未运行,因此无法检查这些事件。 幸运的是,Apple为此提供了解决方案。您可以编写服务器端组件来代替您的应用程序不断检查事件或在后台执行工作。 当感兴趣的事件发生时,服务器端组件可以向应用程序发送推送通知! 推送通知可以执行以下三项操作:
教程链接:http://maniacdev.com/2011/05/tutorial-ios-push-notification-services-for-beginners
答案 3 :(得分:0)
如果你的应用程序没有实现下面列出的任何功能,基本上是不可能的。他们在将应用程序上传到商店之前很难对其进行调查,您需要证明使用该权限
这就是Apple对此的评价:
实施长期运行的任务
对于需要更多执行时间来实现的任务,您必须请求特定权限才能在后台运行它们而不会被暂停。在iOS中,只允许特定的应用类型在后台运行:
实施这些服务的应用必须声明其支持的服务,并使用系统框架来实现这些服务的相关方面。声明服务可以让系统知道您使用哪些服务,但在某些情况下,系统框架实际上会阻止您的应用程序被暂停。