【问题标题】:iOS equivalent to Android Service?iOS 相当于 Android 服务?
【发布时间】:2013-08-20 07:50:31
【问题描述】:

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

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

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

【问题讨论】:

  • 我建议你在别处问这个问题,因为 iOS 7 还没有发布。这种事情最好的地方是苹果开发者论坛。不过,我怀疑 Apple 是否会简单地让您的应用程序在后台运行。太多的白痴程序员会编写废话服务来消耗电池。
  • 嘿,我有一个类似的问题要解决......如果你解决了你的问题,请告诉我你是怎么做到的?

标签: android ios service background ios7


【解决方案1】:

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


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

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

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

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


  • Service.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

  • Service.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];

可能解释得比必要的多,但我想向任何人解释清楚! 我希望它对我的英语有所帮助和抱歉。

【讨论】:

  • 我在真实设备中测试我的解决方案,一切正常运行超过 16 小时。但是我遇到了一个问题,如果您将频率设置为超过 10 分钟,则服务会运行,但计时器会在频率时间过去后执行代码,因此如果服务在执行代码之前无效,则永远不会在您的应用程序中执行此操作它在背景中。所以我正在尝试解决它,如果有人这样做,请留下解决方案的评论!
  • 这个解决方案苹果批准是否友好?
  • 我不知道,还在开发应用程序。只是遇到了问题,因为我在 iPhone 5C 上测试了该应用程序,并且服务在 10 分钟后停止。 :S
  • 谢谢。我在装有 iOS 6.1 的 iPhone 4S 上试过。作业在十分钟后停止。虽然代码在时间结束后重新调用后台任务。任何帮助:O
  • @Ahmed 看看这个答案:Push Notifications
【解决方案2】:

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

【讨论】:

  • 我使用推送通知来解决它,并且一切工作得更好,而我所做的服务,我保留它以在用户使用应用程序时刷新或获取东西。
【解决方案3】:

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

Apple 对此是这么说的:

实现长时间运行的任务

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

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

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

【讨论】:

    【解决方案4】:

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

    推送通知

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

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

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

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

    【讨论】:

    • 原始问题明确指出推送通知可能不是一种选择,对于许多持续的后台处理或通信解决方案而言,它们远非“最佳”解决方案。
    猜你喜欢
    • 2013-05-16
    • 2018-02-09
    • 2012-09-14
    • 2015-06-06
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多