Ios 静默推送通知未随UIBackgroundRefreshStatusDenied一起提供,但应用程序位于前台
使用Ios 静默推送通知未随UIBackgroundRefreshStatusDenied一起提供,但应用程序位于前台,ios,objective-c,Ios,Objective C,使用UIBackgroundRefreshStatusAvailable,我的应用程序会收到预期的静默推送通知,无论是在后台还是前台 此功能的名称--后台应用程序刷新--对我来说,它在禁用时不会影响前台应用程序的行为 不幸的是,我的应用程序在前台时没有收到静默推送通知,后台应用程序刷新被禁用,即uibackgroundrefreshtstatusdenied 我没有使用用户可见的推送通知,因此没有参与UNUserNotificationCenter等 是否可以在后台应用程序刷新被禁用的情况下接收
UIBackgroundRefreshStatusAvailable
,我的应用程序会收到预期的静默推送通知,无论是在后台还是前台
此功能的名称--后台应用程序刷新--对我来说,它在禁用时不会影响前台应用程序的行为
不幸的是,我的应用程序在前台时没有收到静默推送通知,后台应用程序刷新被禁用,即uibackgroundrefreshtstatusdenied
我没有使用用户可见的推送通知,因此没有参与UNUserNotificationCenter
等
是否可以在后台应用程序刷新被禁用的情况下接收静默推送通知,即uibackgroundrefreshtstatusdenied
Objective-C,Xcode 11.3.1,部署目标iOS 10.3。安装了iOS 12.4.5的iPhone 6
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application registerForRemoteNotifications];
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// not called when app in foreground but bg app refresh turned off
}
以下是启用bg应用程序刷新时收到的示例userInfo
didReceiveMemotentification:
{
aps = {
"content-available" = 1;
};
ck = {
ce = 2;
cid = "iCloud.de.udo-thiel.DiskBench";
ckuserid = "_56bd97c2eb1e52d09756163efaab6b02";
nid = "e70e4a8d-d77b-4315-8b3e-d9de229cf083";
qry = {
dbs = 2;
fo = 2;
rid = "Res-iPad 2-16";
sid = "public-results2";
zid = "_defaultZone";
zoid = "_defaultOwner";
};
};
}这是一个有趣的问题,因为它基本上解决了命名这个相当复杂的功能的问题 简言之,我恐怕答案是否定的。虽然我自己不必处理这个问题,但我已经看到许多其他人与你处于相同的地位 对我来说,将整个“静默远程通知功能”看作与应用程序处于前台或后台的关系不大,而与“远程应用程序输入”的关系更大,这会有所帮助: 如果它被激活,即您有可用的
uibackgroundRefreshStatus
,您的服务器可以无声地发送它,在这种情况下,它会对其作出反应。基本上,服务器以与用户点击类似的方式提供输入(当然是通过不同的调用函数)。不管应用程序是在前台还是后台,这种输入都会发生
如果该功能处于非活动状态,即您有uibackgroundrefreshtstatusdenied
或uibackgroundrefreshtstatusrestricted
,则整个功能将关闭。这意味着这种接收输入的方式不起作用,application:didReceiveMemotentification:fetchCompletionHandler:
根本不被调用。无可否认,这个方法名称比state enum案例更好地反映了这个问题
两种解决方法:
applicationIDBecomeActive:
和applicationWillResignActive:
中注册和注销远程通知。不幸的是,这可能会变得丑陋,因为它会导致服务器不断地为用户更改令牌,但如果您想不惜任何代价避免在后台收到通知,请这样做UIApplication.shared.applicationState
)。从技术上讲,这“浪费”了一点运行时间,因为你的应用程序可能会被唤醒,然后不会做任何有意义的事情,但我认为这并不太糟糕作为旁注:是的,苹果SDK在命名和解释所有不同的背景内容和通知时有点混乱。甚至应用程序状态本身(活动、非活动、背景、前景、暂停等)也比名称看起来更复杂。我认为这是历史的原因。在我们有背景模式和通知之前,人们只是轮询数据以获得类似“无声前景通知”的东西,基本上就是你想要的东西。因此,最终他们希望在应用程序不在前台时也能这样做,大声要求后台执行。苹果并不是真的想不受限制地同意这一点,通知的概念发展得如此缓慢,但由于它有点相关,术语“背景”就潜入其中(此外,我们也有背景提取…),即使它不一定有意义。
也有人可能会说它仍然是有效的,因为它对于应用程序处于后台/挂起状态更为重要。“仅在前台时获取静默通知”的用例仍然可以通过简单的轮询来覆盖(尽管我同意这很难看),并且如果使用push,也可以在后台获取这些通知 因此,您的解决方案是要么用用户可见的通知替换静默通知,要么轮询后端,对吗?我编辑了我的答案。在某种程度上,是的,如果我无法避免的话。如果你有一个非常依赖服务器通知应用程序的东西,而用户已经禁用了通知,那么你需要用另一种方式进行检查。不过,我想说的是,这还需要回答另一个问题,因为无论应用程序状态如何,远程通知在禁用时都不起作用。仔细想想,我有一种预感,也许你打算将通知作为与服务器进行连续消息交换的一种形式。这并不是最好的方式,因为任何通知都不能保证按时到达,过多的通知可能会导致iOS限制它们。对于聊天之类的事情,我推荐WebSockets,它从iOS 13开始就得到了很好的支持,例如,请参阅教程“您可以共享apns请求的有效负载吗?”@AhmetAYGÜN I hav