performFetchWithCompletionHandler永远不会被触发

56 objective-c ios ios7

1)我的plist配置提供backgroundmode:

<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
</array> 
Run Code Online (Sandbox Code Playgroud)

2)didFinishLaunchingWithOptions我有:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:1.0];
Run Code Online (Sandbox Code Playgroud)

3)我UIApplicationDelegate在代表中宣布了协议.

4)我实现了以下方法,但它永远不会被触发.(仅当我使用"XCode-> Debug-> Simulate Background Fetch"模拟获取时才有效.)

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
Run Code Online (Sandbox Code Playgroud)

为什么?这是DP5 beta错误吗?我应该雷达吗?

Cla*_*ges 96

在Xcode 5 Debug模式下,您可以从菜单强制进行后台提取:Debug> Simulate Background Fetch.

汪!

  • 在连接到调试器时有效,并且调试器阻止iOS触发提取。要使iOS正常运行,必须从Xcode 9.4开始与调试器分离。 (2认同)

One*_*rew 39

我担心这很难在设备上调试,因为你无法保证在你指定的时间内调用它.

setMinimumBackgroundFetchInterval意味着它不会在小于您指定值的间隔中调用.但是没有setMaximumBackgroundFetchInterval.因此,如果iOS决定每天只调用一次你的应用程序,甚至每周只调用一次,那么无论你是谁,都不会更频繁地调用它minimumBackgroundFetchInterval.AFAIK iOS决定何时performFetchWithCompletionHandler通过模式调用用户启动应用程序的时间和频率.

  • 任何人都可以详细说明这个答案吗?"你不知道什么时候,你永远不知道什么时候"可能是正确的答案,但我真的希望我们能做得更好.如果我们无法区分"出了问题"和"你的时间尚未出现",那么调试后台获取过程几乎是不可能的. (4认同)
  • 当设备被锁定并且没有连接到Wi-Fi时,我看到刷新时间在10到20分钟之间.唤醒设备可以提前触发刷新,但不会在5分钟内触发. (2认同)

Rob*_*Rob 26

有许多注意事项:

  1. 确保在plist中设置了后台获取功能.

  2. 确保尚未针对此特定应用禁用后台提取功能,或者通常在设备的"设置"应用中禁用后台提取功能.

  3. 确保设置最小获取间隔.

  4. 确保你优雅地离开应用程序(例如,只需按下主页按钮并启动另一个应用程序和/或只是锁定设备).但是,如果你杀了应用程序(双击主页按钮并向上滑动,或者你有什么),这将阻止操作系统为你的应用程序提供触发后续后台提取请求的机会(至少在用户再次运行应用程序之前) ).

  5. 确保您在物理设备上进行测试,而不是通过Xcode调试器运行应用程序.附加到调试器会更改后台操作的行为.

  6. 确保该应用实际上正在执行一些网络请求.如果您的应用程序根本不执行任何网络请求,则它将不参与后台获取.例如,如果您使用"后台获取"的小测试应用程序并且不发出任何网络请求,则不会参与后台获取.

    同样,如果操作系统在后台模式下启动您的应用程序,以便它可以执行后台提取,如果您实际上没有执行网络请求,操作系统可能会停止为您的应用程序提供将来执行后台提取的功能.

  7. 确保调用完成处理程序,并在指定的时间内完成,或者您的应用程序将来可能不参与后台提取.

  8. 操作系统执行后台提取的时间取决于未来可能会更改的记录不完整的规则.但相关因素包括:

    • 设备是否已连接电源和/或充足电;

    • 是否连接到WiFi;

    • 用户实际启动应用程序的频率;

    • 设备是否正在执行其他与网络相关的任务(例如,后台提取是否可以与其他网络操作合并);

    • 过去后台获取请求的频率导致数据可用.


    根据我的经验,在应用程序第一次运行后,如果连接到wifi和电源,如果您在大约5分钟后唤醒设备,该应用程序将执行后台获取.这不是一个严格而快速的规则,而是我们过去所经历的.

    但许多新开发人员在Stack Overflow上发布了一些问题,例如"我怎么能在x分钟(或几小时)内获得应用程序请求数据","我如何每天凌晨2点请求数据",等等.简短的回答是你不能.操作系统自行决定背景的时间安排.您无法控制此情况(最小请求间隔除外;但您无法控制最大间隔,因为操作系统会控制该间隔).

  9. 对于许多人来说,这似乎是显而易见的,但请确保您有一种可靠的方法来了解后台获取过程是否正确运行.用户通知框架可用于提供一些警报,以便您知道后台请求是否产生了某些内容.或者,os_log"统一通知"可用于在可在macOS Console应用程序上监视的设备上发布消息.但不止一次,我看到用户做了类似等待消息显示在Xcode或等待的事情UIAlertController.你需要一些机制,当没有连接到Xcode和应用程序永远不会进入前台时工作.


小智 21

使用您的设备,您可以application:performFetchWithCompletionHandler通过以下步骤触发:

  • 将您的应用程序置于后台状态
  • 锁定您的设备并等待5分钟.
  • 解锁您的设备,这将触发该方法


小智 21

(仅当我使用"XCode-> Debug-> Simulate Background Fetch"模拟获取时才有效.)

这是因为你处于调试模式.请尝试在没有XCode的情况下启动应用.


Axe*_*eva 5

要检查的另一件事是你的plist文件.确保UIApplicationExitsOnSuspend密钥不存在.

Stack Overflow上的许多人都建议使用该设置来强制您的应用在每次启动时重新开始.这确实有效,但副作用是它会阻止触发新的iOS 7后台提取功能.