ios - 使用 Xcode 和 Objective-c 的 iOS 应用程序后台未显示 userNotification
问题描述
当应用程序在后台时,我正在尝试使用 userNotifications 来通知位置事件。到目前为止,我已经在我的 App Delegate 中请求了许可,并且收到了请求许可的警报。
AppDelegate.h
#import <UserNotifications/UserNotifications.h>
#import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate >
{
UNUserNotificationCenter *center;
}
@property(readonly, copy) NSString *localizedDescription;
@end
然后在 AppDelegate.m
@synthesize localizedDescription;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (@available(iOS 14.0, *)) {
if (settings.authorizationStatus == UNAuthorizationStatusEphemeral) {
NSLog(@"Ephermeral");
}
else if (settings.authorizationStatus == UNAuthorizationStatusProvisional) {
NSLog(@"provisional");
}
else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
NSLog(@"authorized");
}
else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
NSLog(@"denied");
}
else if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
NSLog(@"Not determined");
[self->center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge|UNAuthorizationOptionAlert|UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (! error) {
NSLog(@"success");
}
else {
NSLog(@"desc%@",self.localizedDescription);
}
}];
}}
else {
NSLog(@"earlier");
}
}];
return YES;
}
就像我在安装后第一次启动时所说的那样,我被要求获得许可,并在给予通知后包含在应用程序的设置中。
接下来在一个单独的 viewController 中,我设置了实际的通知。
在 notificationViewController.h
#import <UserNotifications/UserNotifications.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#import <UserNotifications/UNNotificationTrigger.h>
@interface notificationViewController : UIViewController<UNUserNotificationCenterDelegate>
并在 notificationViewController.m
-(void)locationManager:(CLLocationManager*)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion*)region{
if(state == CLRegionStateInside){
if ([region.identifier isEqualToString:@"com.checkers.bluetooth"]) {
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
center.delegate = self;
objNotificationContent.title = [NSString localizedUserNotificationStringForKey:NSLocalizedString(@"PLAYGAME", nil) arguments:nil];
objNotificationContent.body = [NSString localizedUserNotificationStringForKey: NSLocalizedString(@"PLAYCHECKERS", nil)arguments:nil];
objNotificationContent.sound = [UNNotificationSound defaultSound];
objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
CLRegion *regiona = region;
UNLocationNotificationTrigger* trigger = [UNLocationNotificationTrigger
triggerWithRegion:regiona repeats:NO];
NSLog(@"trigger%@",trigger);
NSString *identifier = @"Someone wants to play";
UNNotificationRequest* request = [UNNotificationRequest
requestWithIdentifier:identifier content:objNotificationContent trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"%@", error.localizedDescription);
}
else {
NSLog(@"fired ok");
}
}];
}
我在这里所做的是,当设备进入标识符为“com.checkers.bluetooth”的区域时,如果应用程序在后台,我想发出通知。
所以我首先定义了UNNotificationCenter,然后我分配并启动了通知的内容。
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
objNotificationContent.title = [NSString localizedUserNotificationStringForKey:NSLocalizedString(@"PLAYGAME", nil) arguments:nil];
objNotificationContent.body = [NSString localizedUserNotificationStringForKey: NSLocalizedString(@"PLAYCHECKERS", nil)arguments:nil];
objNotificationContent.sound = [UNNotificationSound defaultSound];
objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
然后我定义区域并使其成为位置触发器。
CLRegion *regiona = region;
UNLocationNotificationTrigger* trigger = [UNLocationNotificationTrigger
triggerWithRegion:regiona repeats:NO];
NSLog(@"trigger%@",trigger);
然后我定义通知的标识符并创建一个请求。
NSString *identifier = @"Someone wants to play";
UNNotificationRequest* request = [UNNotificationRequest
requestWithIdentifier:identifier content:objNotificationContent trigger:trigger];
最后,我添加了带有完成处理程序的 notificationRequest。
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"%@", error.localizedDescription);
}
else {
NSLog(@"fired ok");
}
}];
当我运行应用程序并让设备进入信标区域时,我得到以下日志:
2021-03-30 10:03:16.451795-0700 my little world app[604:139241] trigger<UNLocationNotificationTrigger: 0x281f8ae20; repeats: NO, region: CLBeaconRegion (identifier:'com.checkers.bluetooth', uuid:C74E2565-516C-40AF-9ABF-A9ABEBDE3188, major:(null), minor:(null))>
我认为这表明触发器正在被识别。接下来我得到这个日志:
2021-03-30 10:03:16.486303-0700 my little world app[604:139430] fired ok
这表明通知中心确实添加了通知请求,并且它确实完成且没有任何错误。
问题是应用程序从不显示通知。
我的假设是错误的,是我的代码不正确还是顺序错误。我查看了多个示例,它们都差不多,并且似乎是我所拥有的,所以我不知道该怎么做才能让通知出现。
难道它是一个 CLBeaconRegion 而不是一个触发器的 CLRegion 是问题所在吗?
有人可以帮忙吗。
我已经使用 UIAlert 来通知用户这种情况发生在应用程序处于前台并且它工作得很好所以我知道事情正在被调用时。
解决方案
推荐阅读
- xamarin - Xamarin:为选定的选项卡项添加边框
- javascript - 如何在全日历中重复事件
- php - 使用 WHERE 条件获取包含模型的计数字段
- docusignapi - DOCUSIGN:如何通过以编程方式传递访问代码来绕过访问代码验证页面
- typescript - 打字稿和值不能为空
- spring-boot - 为什么在尝试通过 Spring Boot Security 生成的默认用户名“用户”和安全密码登录时出现白标签错误页面?
- css - 悬停时放大图像的CSS动画?
- netsuite - NetSuite Suitelet 自定义 HTML | 在表单上按提交会导致值为空
- docker - Docker 无法使用 Dockerfile 构建 docker 映像,没有这样的文件或目录(尽管 Dockerfile 存在,并且拼写正确,没有扩展名)
- python - 我可以在 python 中修改语言环境 localeconv() 的一部分吗