8

那么随着 iOS 7 支持更广泛的后台模式,是否有可能最终在 iOS 上拥有与 Android Service 相当的功能呢?

我所追求的本质上是在后台运行应用程序 A,并让一个或多个应用程序 B 和 C 与该应用程序对话(不显示应用程序 A 的 GUI)。

请注意,使用连接和推送通知可能不是一种选择,尽管这是推荐的方式。有任何想法吗?

4

4 回答 4

6

编辑:没有按预期工作。请参阅此答案以获得最佳解决方案:推送通知


编辑:下一个解决方案仅在用户在应用程序中以保持同步时有用。

没有办法在后台永久执行任务,但是您可以使用有限长度的任务来执行此操作,当您制作有限长度时,这将始终在应用程序处于活动状态时运行,但是当您单击主页按钮时, ios 只给您 10 分钟的时间来执行您的任务并使其无效,但它让您有机会制作一个“无效处理程序块”,您可以在明确完成之前执行最后的操作。

因此,如果您在其他时间使用该处理程序块来调用有限长度的任务,您可以通过运行一个任务 10 分钟来模拟服务,当它结束时,在其他 10 分钟内调用它。

我在创建接口“服务”的项目中使用它。我在这里给你代码:


  • 服务.h

//
//  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

  • 服务.m

//
//  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

在您的应用程序委托或您需要提升服务的地方,您编写下一行:

Service myService = [[SomeService alloc] initWithFrequency: 60]; //execute doInBackground each 60 seconds
[myService startService];

如果你需要停止它:

[myService stopService];

可能已经解释了太多,但我想向任何人解释清楚!我希望它的帮助和对不起我的英语。

于 2013-10-01T16:22:24.613 回答
2

不,没有与 Android 服务等效的东西。MansApps 代码不起作用,至少在 iOS7 上不起作用。过期处理程序中的调用[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];只会在应用程序回到前台时返回,即[self startBackgroundTask];当应用程序停留在后台时不会执行调用。

于 2013-10-12T16:30:42.253 回答
1

如果您的应用程序没有实现下面列出的任何功能,基本上是不可能的。他们几乎不会在将您的应用上传到商店之前对其进行调查,您需要证明使用该权限是合理的

这就是苹果公司的说法:

实施长时间运行的任务

对于需要更多执行时间来实现的任务,您必须请求特定权限才能在后台运行它们而不会被挂起。在 iOS 中,只允许特定类型的应用程序在后台运行:

  • 在后台向用户播放有声内容的应用程序,例如音乐播放器应用程序
  • 在后台录制音频内容的应用程序
  • 让用户随时了解其位置的应用程序,例如导航应用程序
  • 支持互联网协议语音 (VoIP) 的应用程序
  • 需要定期下载和处理新内容的应用
  • 从外部配件接收定期更新的应用程序

实现这些服务的应用程序必须声明它们支持的服务并使用系统框架来实现这些服务的相关方面。声明服务让系统知道您使用了哪些服务,但在某些情况下,实际上是系统框架阻止了您的应用程序被挂起。

于 2015-12-30T15:57:24.013 回答
0

我找到了最好的标准解决方案:

推送通知

(Matthijs Hollemans 原帖,Ali Hafizji 更新)。

在 iOS 中,应用程序不能在后台做很多事情。应用程序只允许执行有限的活动集,因此可以节省电池寿命。但是,如果发生了一些有趣的事情,并且您希望让用户知道这一点,即使他们目前没有使用您的应用程序,该怎么办?例如,可能用户收到了一条新推文,他们最喜欢的球队赢得了比赛,或者他们的晚餐准备好了。由于应用程序当前未运行,因此无法检查这些事件。幸运的是,Apple 已经为此提供了解决方案。您可以编写一个服务器端组件来代替您的应用程序不断检查事件或在后台工作,而不是这样做。并且当感兴趣的事件发生时,服务器端组件可以向应用程序发送推送通知推送通知可以做三件事:

  • 显示一条短信
  • 播放简短的声音
  • 在应用程序图标上的徽章中设置一个数字

教程链接: http: //maniacdev.com/2011/05/tutorial-ios-push-notification-services-for-beginners

于 2013-11-04T11:24:48.617 回答